From: khartlage Date: Mon, 22 Dec 2003 14:20:53 +0000 (+0000) Subject: new version with WorkingCopy Management X-Git-Url: http://git.phpeclipse.com new version with WorkingCopy Management --- diff --git a/net.sourceforge.phpeclipse/.classpath b/net.sourceforge.phpeclipse/.classpath index 1d2e74f..5ffe139 100644 --- a/net.sourceforge.phpeclipse/.classpath +++ b/net.sourceforge.phpeclipse/.classpath @@ -2,21 +2,21 @@ + path="ECLIPSE_HOME/plugins/org.eclipse.core.resources_2.1.1/resources.jar" sourcepath="ORG_ECLIPSE_PLATFORM_SOURCE_SRC/org.eclipse.core.resources_2.1.1/resourcessrc.zip"/> + path="ECLIPSE_HOME/plugins/org.eclipse.ui_2.1.1/ui.jar" sourcepath="ORG_ECLIPSE_PLATFORM_SOURCE_SRC/org.eclipse.ui_2.1.1/uisrc.zip"/> + path="ECLIPSE_HOME/plugins/org.eclipse.swt.win32_2.1.1/ws/win32/swt.jar" sourcepath="ORG_ECLIPSE_PLATFORM_WIN32_SOURCE_SRC/org.eclipse.swt.win32_2.1.1/ws/win32/swtsrc.zip"/> + path="ECLIPSE_HOME/plugins/org.eclipse.jface_2.1.1/jface.jar" sourcepath="ORG_ECLIPSE_PLATFORM_SOURCE_SRC/org.eclipse.jface_2.1.1/jfacesrc.zip"/> + path="ECLIPSE_HOME/plugins/org.eclipse.ui.workbench_2.1.1/workbench.jar" sourcepath="ORG_ECLIPSE_PLATFORM_SOURCE_SRC/org.eclipse.ui.workbench_2.1.1/workbenchsrc.zip"/> + path="ECLIPSE_HOME/plugins/org.eclipse.ui.externaltools_2.1.1/externaltools.jar" sourcepath="ORG_ECLIPSE_PLATFORM_SOURCE_SRC/org.eclipse.ui.externaltools_2.1.1/externaltoolssrc.zip"/> + path="ECLIPSE_HOME/plugins/org.eclipse.help_2.1.1/help.jar" sourcepath="ORG_ECLIPSE_PLATFORM_SOURCE_SRC/org.eclipse.help_2.1.1/helpsrc.zip"/> - - + path="ECLIPSE_HOME/plugins/org.eclipse.debug.ui_2.1.1/dtui.jar" sourcepath="ORG_ECLIPSE_PLATFORM_SOURCE_SRC/org.eclipse.debug.ui_2.1.1/dtuisrc.zip"/> + + + + + path="ECLIPSE_HOME/plugins/org.eclipse.core.boot_2.1.1/boot.jar" sourcepath="ORG_ECLIPSE_PLATFORM_SOURCE_SRC/org.eclipse.core.boot_2.1.1/bootsrc.zip"/> - + path="ECLIPSE_HOME/plugins/org.eclipse.core.runtime_2.1.1/runtime.jar" sourcepath="ORG_ECLIPSE_PLATFORM_SOURCE_SRC/org.eclipse.core.runtime_2.1.1/runtimesrc.zip"/> + diff --git a/net.sourceforge.phpeclipse/icons/clcl16/add_exc.gif b/net.sourceforge.phpeclipse/icons/clcl16/add_exc.gif new file mode 100644 index 0000000..a321874 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/add_exc.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/alphab_sort_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/alphab_sort_co.gif new file mode 100644 index 0000000..6d77244 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/alphab_sort_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/class_obj.gif b/net.sourceforge.phpeclipse/icons/clcl16/class_obj.gif new file mode 100644 index 0000000..10baaac Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/class_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/clear_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/clear_co.gif new file mode 100644 index 0000000..2558326 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/clear_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/collapseall.gif b/net.sourceforge.phpeclipse/icons/clcl16/collapseall.gif new file mode 100644 index 0000000..0bae56c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/collapseall.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/default_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/default_co.gif new file mode 100644 index 0000000..19d27de Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/default_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/definingtype_sort_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/definingtype_sort_co.gif new file mode 100644 index 0000000..b32f336 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/definingtype_sort_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/exc_catch.gif b/net.sourceforge.phpeclipse/icons/clcl16/exc_catch.gif new file mode 100644 index 0000000..e6cb8b1 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/exc_catch.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/fields_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/fields_co.gif new file mode 100644 index 0000000..e14ce56 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/fields_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/filter_ps.gif b/net.sourceforge.phpeclipse/icons/clcl16/filter_ps.gif new file mode 100644 index 0000000..1492b4e Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/filter_ps.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/final_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/final_co.gif new file mode 100644 index 0000000..9528145 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/final_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/flatLayout.gif b/net.sourceforge.phpeclipse/icons/clcl16/flatLayout.gif new file mode 100644 index 0000000..b84df08 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/flatLayout.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/gointo_toplevel_type.gif b/net.sourceforge.phpeclipse/icons/clcl16/gointo_toplevel_type.gif new file mode 100644 index 0000000..0533fc2 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/gointo_toplevel_type.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/hexad_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/hexad_co.gif new file mode 100644 index 0000000..ec7455b Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/hexad_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/hierarchicalLayout.gif b/net.sourceforge.phpeclipse/icons/clcl16/hierarchicalLayout.gif new file mode 100644 index 0000000..e597c3d Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/hierarchicalLayout.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/hierarchy_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/hierarchy_co.gif new file mode 100644 index 0000000..59ecde8 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/hierarchy_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/history_list.gif b/net.sourceforge.phpeclipse/icons/clcl16/history_list.gif new file mode 100644 index 0000000..0b8d0ed Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/history_list.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/impl_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/impl_co.gif new file mode 100644 index 0000000..5a8c7ea Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/impl_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/inher_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/inher_co.gif new file mode 100644 index 0000000..414fa6a Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/inher_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/lock_close.gif b/net.sourceforge.phpeclipse/icons/clcl16/lock_close.gif new file mode 100644 index 0000000..2bcdbf0 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/lock_close.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/metharg_obj.gif b/net.sourceforge.phpeclipse/icons/clcl16/metharg_obj.gif new file mode 100644 index 0000000..f300af6 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/metharg_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/pack_empty_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/pack_empty_co.gif new file mode 100644 index 0000000..da642a1 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/pack_empty_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/private_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/private_co.gif new file mode 100644 index 0000000..b5b8853 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/private_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/protected_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/protected_co.gif new file mode 100644 index 0000000..2b76d36 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/protected_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/public_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/public_co.gif new file mode 100644 index 0000000..18103b1 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/public_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/refresh_nav.gif b/net.sourceforge.phpeclipse/icons/clcl16/refresh_nav.gif new file mode 100644 index 0000000..a063c23 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/refresh_nav.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/remove_exc.gif b/net.sourceforge.phpeclipse/icons/clcl16/remove_exc.gif new file mode 100644 index 0000000..12a9167 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/remove_exc.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/removea_exc.gif b/net.sourceforge.phpeclipse/icons/clcl16/removea_exc.gif new file mode 100644 index 0000000..2c069ab Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/removea_exc.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/search_sortmatch.gif b/net.sourceforge.phpeclipse/icons/clcl16/search_sortmatch.gif new file mode 100644 index 0000000..9ed470d Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/search_sortmatch.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/static_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/static_co.gif new file mode 100644 index 0000000..10d08ae Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/static_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/sub_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/sub_co.gif new file mode 100644 index 0000000..c8f0628 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/sub_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/super_co.gif b/net.sourceforge.phpeclipse/icons/clcl16/super_co.gif new file mode 100644 index 0000000..199d4b7 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/super_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/synced.gif b/net.sourceforge.phpeclipse/icons/clcl16/synced.gif new file mode 100644 index 0000000..f865f3a Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/synced.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/th_horizontal.gif b/net.sourceforge.phpeclipse/icons/clcl16/th_horizontal.gif new file mode 100644 index 0000000..f4c14a4 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/th_horizontal.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/th_showqualified.gif b/net.sourceforge.phpeclipse/icons/clcl16/th_showqualified.gif new file mode 100644 index 0000000..3aa2efa Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/th_showqualified.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/th_single.gif b/net.sourceforge.phpeclipse/icons/clcl16/th_single.gif new file mode 100644 index 0000000..c3a7519 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/th_single.gif differ diff --git a/net.sourceforge.phpeclipse/icons/clcl16/th_vertical.gif b/net.sourceforge.phpeclipse/icons/clcl16/th_vertical.gif new file mode 100644 index 0000000..f685839 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/clcl16/th_vertical.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/comment_edit.gif b/net.sourceforge.phpeclipse/icons/ctool16/comment_edit.gif new file mode 100644 index 0000000..9fa43d5 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/comment_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/disp_sbook.gif b/net.sourceforge.phpeclipse/icons/ctool16/disp_sbook.gif new file mode 100644 index 0000000..f9fb6b0 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/disp_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/export_wiz.gif b/net.sourceforge.phpeclipse/icons/ctool16/export_wiz.gif new file mode 100644 index 0000000..5a01b75 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/export_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/exportjar_wiz.gif b/net.sourceforge.phpeclipse/icons/ctool16/exportjar_wiz.gif new file mode 100644 index 0000000..6388d79 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/exportjar_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/format_edit.gif b/net.sourceforge.phpeclipse/icons/ctool16/format_edit.gif new file mode 100644 index 0000000..b924a33 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/format_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/import_wiz.gif b/net.sourceforge.phpeclipse/icons/ctool16/import_wiz.gif new file mode 100644 index 0000000..6152fd7 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/import_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/importjar_wiz.gif b/net.sourceforge.phpeclipse/icons/ctool16/importjar_wiz.gif new file mode 100644 index 0000000..870aeab Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/importjar_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/insp_sbook.gif b/net.sourceforge.phpeclipse/icons/ctool16/insp_sbook.gif new file mode 100644 index 0000000..2b645a8 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/insp_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/java_app.gif b/net.sourceforge.phpeclipse/icons/ctool16/java_app.gif new file mode 100644 index 0000000..6c14675 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/java_app.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/java_attach.gif b/net.sourceforge.phpeclipse/icons/ctool16/java_attach.gif new file mode 100644 index 0000000..b33f4a0 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/java_attach.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/javadoc.gif b/net.sourceforge.phpeclipse/icons/ctool16/javadoc.gif new file mode 100644 index 0000000..e2bbdf6 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/javadoc.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/jdoc_hover_edit.gif b/net.sourceforge.phpeclipse/icons/ctool16/jdoc_hover_edit.gif new file mode 100644 index 0000000..afbeba3 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/jdoc_hover_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/newfield_wiz.gif b/net.sourceforge.phpeclipse/icons/ctool16/newfield_wiz.gif new file mode 100644 index 0000000..33a542b Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/newfield_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/newint_wiz.gif b/net.sourceforge.phpeclipse/icons/ctool16/newint_wiz.gif new file mode 100644 index 0000000..3b703cd Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/newint_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/newjprj_wiz.gif b/net.sourceforge.phpeclipse/icons/ctool16/newjprj_wiz.gif new file mode 100644 index 0000000..c533510 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/newjprj_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/newjworkingSet_wiz.gif b/net.sourceforge.phpeclipse/icons/ctool16/newjworkingSet_wiz.gif new file mode 100644 index 0000000..6c14675 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/newjworkingSet_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/newpack_wiz.gif b/net.sourceforge.phpeclipse/icons/ctool16/newpack_wiz.gif new file mode 100644 index 0000000..415063f Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/newpack_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/newpackfolder_wiz.gif b/net.sourceforge.phpeclipse/icons/ctool16/newpackfolder_wiz.gif new file mode 100644 index 0000000..9da3670 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/newpackfolder_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/newsbook_wiz.gif b/net.sourceforge.phpeclipse/icons/ctool16/newsbook_wiz.gif new file mode 100644 index 0000000..2590cf5 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/newsbook_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/next_error_nav.gif b/net.sourceforge.phpeclipse/icons/ctool16/next_error_nav.gif new file mode 100644 index 0000000..775842e Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/next_error_nav.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/opentype.gif b/net.sourceforge.phpeclipse/icons/ctool16/opentype.gif new file mode 100644 index 0000000..40d2bc9 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/opentype.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/pack_sbook.gif b/net.sourceforge.phpeclipse/icons/ctool16/pack_sbook.gif new file mode 100644 index 0000000..3aa2efa Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/pack_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/prev_error_nav.gif b/net.sourceforge.phpeclipse/icons/ctool16/prev_error_nav.gif new file mode 100644 index 0000000..3b1bb7c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/prev_error_nav.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/run_sbook.gif b/net.sourceforge.phpeclipse/icons/ctool16/run_sbook.gif new file mode 100644 index 0000000..95d53e4 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/run_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/segment_edit.gif b/net.sourceforge.phpeclipse/icons/ctool16/segment_edit.gif new file mode 100644 index 0000000..be9eb92 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/segment_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/shift_l_edit.gif b/net.sourceforge.phpeclipse/icons/ctool16/shift_l_edit.gif new file mode 100644 index 0000000..2700d54 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/shift_l_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/shift_r_edit.gif b/net.sourceforge.phpeclipse/icons/ctool16/shift_r_edit.gif new file mode 100644 index 0000000..fed1373 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/shift_r_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/term_sbook.gif b/net.sourceforge.phpeclipse/icons/ctool16/term_sbook.gif new file mode 100644 index 0000000..d47876f Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/term_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ctool16/uncomment_edit.gif b/net.sourceforge.phpeclipse/icons/ctool16/uncomment_edit.gif new file mode 100644 index 0000000..4b3d884 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ctool16/uncomment_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/cview16/browse_persp.gif b/net.sourceforge.phpeclipse/icons/cview16/browse_persp.gif new file mode 100644 index 0000000..857ad49 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/cview16/browse_persp.gif differ diff --git a/net.sourceforge.phpeclipse/icons/cview16/class_hi.gif b/net.sourceforge.phpeclipse/icons/cview16/class_hi.gif new file mode 100644 index 0000000..3ffaf4c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/cview16/class_hi.gif differ diff --git a/net.sourceforge.phpeclipse/icons/cview16/classfilegeneration_tab.gif b/net.sourceforge.phpeclipse/icons/cview16/classfilegeneration_tab.gif new file mode 100644 index 0000000..83cbb07 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/cview16/classfilegeneration_tab.gif differ diff --git a/net.sourceforge.phpeclipse/icons/cview16/errorwarning_tab.gif b/net.sourceforge.phpeclipse/icons/cview16/errorwarning_tab.gif new file mode 100644 index 0000000..f42eefd Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/cview16/errorwarning_tab.gif differ diff --git a/net.sourceforge.phpeclipse/icons/cview16/hierch_persp.gif b/net.sourceforge.phpeclipse/icons/cview16/hierch_persp.gif new file mode 100644 index 0000000..9277395 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/cview16/hierch_persp.gif differ diff --git a/net.sourceforge.phpeclipse/icons/cview16/jdkcompliance_tab.gif b/net.sourceforge.phpeclipse/icons/cview16/jdkcompliance_tab.gif new file mode 100644 index 0000000..3a59b3c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/cview16/jdkcompliance_tab.gif differ diff --git a/net.sourceforge.phpeclipse/icons/cview16/jperspective.gif b/net.sourceforge.phpeclipse/icons/cview16/jperspective.gif new file mode 100644 index 0000000..0080b32 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/cview16/jperspective.gif differ diff --git a/net.sourceforge.phpeclipse/icons/cview16/members.gif b/net.sourceforge.phpeclipse/icons/cview16/members.gif new file mode 100644 index 0000000..f4fb313 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/cview16/members.gif differ diff --git a/net.sourceforge.phpeclipse/icons/cview16/package.gif b/net.sourceforge.phpeclipse/icons/cview16/package.gif new file mode 100644 index 0000000..77b3b80 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/cview16/package.gif differ diff --git a/net.sourceforge.phpeclipse/icons/cview16/packages.gif b/net.sourceforge.phpeclipse/icons/cview16/packages.gif new file mode 100644 index 0000000..67ebb3f Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/cview16/packages.gif differ diff --git a/net.sourceforge.phpeclipse/icons/cview16/projects.gif b/net.sourceforge.phpeclipse/icons/cview16/projects.gif new file mode 100644 index 0000000..06839c0 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/cview16/projects.gif differ diff --git a/net.sourceforge.phpeclipse/icons/cview16/types.gif b/net.sourceforge.phpeclipse/icons/cview16/types.gif new file mode 100644 index 0000000..6da652d Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/cview16/types.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/add_exc.gif b/net.sourceforge.phpeclipse/icons/dlcl16/add_exc.gif new file mode 100644 index 0000000..c5b450a Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/add_exc.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/alphab_sort_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/alphab_sort_co.gif new file mode 100644 index 0000000..62a8fdb Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/alphab_sort_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/class_obj.gif b/net.sourceforge.phpeclipse/icons/dlcl16/class_obj.gif new file mode 100644 index 0000000..5c10745 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/class_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/clear_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/clear_co.gif new file mode 100644 index 0000000..d873c49 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/clear_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/collapseall.gif b/net.sourceforge.phpeclipse/icons/dlcl16/collapseall.gif new file mode 100644 index 0000000..0bae56c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/collapseall.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/default_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/default_co.gif new file mode 100644 index 0000000..452fb2f Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/default_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/definingtype_sort_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/definingtype_sort_co.gif new file mode 100644 index 0000000..23a7291 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/definingtype_sort_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/exc_catch.gif b/net.sourceforge.phpeclipse/icons/dlcl16/exc_catch.gif new file mode 100644 index 0000000..cec357c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/exc_catch.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/fields_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/fields_co.gif new file mode 100644 index 0000000..49bf697 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/fields_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/filter_ps.gif b/net.sourceforge.phpeclipse/icons/dlcl16/filter_ps.gif new file mode 100644 index 0000000..2b6285b Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/filter_ps.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/final_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/final_co.gif new file mode 100644 index 0000000..d75db8a Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/final_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/flatLayout.gif b/net.sourceforge.phpeclipse/icons/dlcl16/flatLayout.gif new file mode 100644 index 0000000..aa0160d Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/flatLayout.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/gointo_toplevel_type.gif b/net.sourceforge.phpeclipse/icons/dlcl16/gointo_toplevel_type.gif new file mode 100644 index 0000000..b8e29ff Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/gointo_toplevel_type.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/hexad_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/hexad_co.gif new file mode 100644 index 0000000..44d1b77 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/hexad_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/hierarchicalLayout.gif b/net.sourceforge.phpeclipse/icons/dlcl16/hierarchicalLayout.gif new file mode 100644 index 0000000..76f3360 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/hierarchicalLayout.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/hierarchy_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/hierarchy_co.gif new file mode 100644 index 0000000..a91aa7e Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/hierarchy_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/history_list.gif b/net.sourceforge.phpeclipse/icons/dlcl16/history_list.gif new file mode 100644 index 0000000..5a8b119 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/history_list.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/impl_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/impl_co.gif new file mode 100644 index 0000000..d71b1a0 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/impl_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/inher_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/inher_co.gif new file mode 100644 index 0000000..a2b3356 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/inher_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/lock_close.gif b/net.sourceforge.phpeclipse/icons/dlcl16/lock_close.gif new file mode 100644 index 0000000..9067936 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/lock_close.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/metharg_obj.gif b/net.sourceforge.phpeclipse/icons/dlcl16/metharg_obj.gif new file mode 100644 index 0000000..b3597e3 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/metharg_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/pack_empty_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/pack_empty_co.gif new file mode 100644 index 0000000..1319191 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/pack_empty_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/private_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/private_co.gif new file mode 100644 index 0000000..01891e2 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/private_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/protected_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/protected_co.gif new file mode 100644 index 0000000..9d77745 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/protected_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/public_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/public_co.gif new file mode 100644 index 0000000..2733d9c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/public_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/refresh_nav.gif b/net.sourceforge.phpeclipse/icons/dlcl16/refresh_nav.gif new file mode 100644 index 0000000..b2281b4 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/refresh_nav.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/remove_exc.gif b/net.sourceforge.phpeclipse/icons/dlcl16/remove_exc.gif new file mode 100644 index 0000000..7e0ad4a Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/remove_exc.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/removea_exc.gif b/net.sourceforge.phpeclipse/icons/dlcl16/removea_exc.gif new file mode 100644 index 0000000..7ace43e Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/removea_exc.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/search_sortmatch.gif b/net.sourceforge.phpeclipse/icons/dlcl16/search_sortmatch.gif new file mode 100644 index 0000000..8a47d61 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/search_sortmatch.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/static_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/static_co.gif new file mode 100644 index 0000000..7c78e8c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/static_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/sub_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/sub_co.gif new file mode 100644 index 0000000..eb77439 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/sub_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/super_co.gif b/net.sourceforge.phpeclipse/icons/dlcl16/super_co.gif new file mode 100644 index 0000000..c30f0e2 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/super_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/synced.gif b/net.sourceforge.phpeclipse/icons/dlcl16/synced.gif new file mode 100644 index 0000000..ae5d548 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/synced.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/th_horizontal.gif b/net.sourceforge.phpeclipse/icons/dlcl16/th_horizontal.gif new file mode 100644 index 0000000..02e35a4 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/th_horizontal.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/th_showqualified.gif b/net.sourceforge.phpeclipse/icons/dlcl16/th_showqualified.gif new file mode 100644 index 0000000..3aa2efa Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/th_showqualified.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/th_single.gif b/net.sourceforge.phpeclipse/icons/dlcl16/th_single.gif new file mode 100644 index 0000000..1419ba5 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/th_single.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dlcl16/th_vertical.gif b/net.sourceforge.phpeclipse/icons/dlcl16/th_vertical.gif new file mode 100644 index 0000000..e548d11 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dlcl16/th_vertical.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/comment_edit.gif b/net.sourceforge.phpeclipse/icons/dtool16/comment_edit.gif new file mode 100644 index 0000000..1197d0c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/comment_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/disp_sbook.gif b/net.sourceforge.phpeclipse/icons/dtool16/disp_sbook.gif new file mode 100644 index 0000000..d2d6592 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/disp_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/export_wiz.gif b/net.sourceforge.phpeclipse/icons/dtool16/export_wiz.gif new file mode 100644 index 0000000..13959f3 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/export_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/exportjar_wiz.gif b/net.sourceforge.phpeclipse/icons/dtool16/exportjar_wiz.gif new file mode 100644 index 0000000..c829da3 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/exportjar_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/format_edit.gif b/net.sourceforge.phpeclipse/icons/dtool16/format_edit.gif new file mode 100644 index 0000000..fb2cd70 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/format_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/import_wiz.gif b/net.sourceforge.phpeclipse/icons/dtool16/import_wiz.gif new file mode 100644 index 0000000..a3934cb Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/import_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/importjar_wiz.gif b/net.sourceforge.phpeclipse/icons/dtool16/importjar_wiz.gif new file mode 100644 index 0000000..1776c73 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/importjar_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/insp_sbook.gif b/net.sourceforge.phpeclipse/icons/dtool16/insp_sbook.gif new file mode 100644 index 0000000..27b96a7 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/insp_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/java_app.gif b/net.sourceforge.phpeclipse/icons/dtool16/java_app.gif new file mode 100644 index 0000000..36536c6 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/java_app.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/java_attach.gif b/net.sourceforge.phpeclipse/icons/dtool16/java_attach.gif new file mode 100644 index 0000000..8a4369e Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/java_attach.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/javadoc.gif b/net.sourceforge.phpeclipse/icons/dtool16/javadoc.gif new file mode 100644 index 0000000..66ea5a2 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/javadoc.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/jdoc_hover_edit.gif b/net.sourceforge.phpeclipse/icons/dtool16/jdoc_hover_edit.gif new file mode 100644 index 0000000..f352844 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/jdoc_hover_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/newclass_wiz.gif b/net.sourceforge.phpeclipse/icons/dtool16/newclass_wiz.gif new file mode 100644 index 0000000..859df29 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/newclass_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/newfield_wiz.gif b/net.sourceforge.phpeclipse/icons/dtool16/newfield_wiz.gif new file mode 100644 index 0000000..c679d44 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/newfield_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/newint_wiz.gif b/net.sourceforge.phpeclipse/icons/dtool16/newint_wiz.gif new file mode 100644 index 0000000..c4c09a0 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/newint_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/newjprj_wiz.gif b/net.sourceforge.phpeclipse/icons/dtool16/newjprj_wiz.gif new file mode 100644 index 0000000..17404dd Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/newjprj_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/newjworkingSet_wiz.gif b/net.sourceforge.phpeclipse/icons/dtool16/newjworkingSet_wiz.gif new file mode 100644 index 0000000..36536c6 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/newjworkingSet_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/newpack_wiz.gif b/net.sourceforge.phpeclipse/icons/dtool16/newpack_wiz.gif new file mode 100644 index 0000000..981ea97 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/newpack_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/newpackfolder_wiz.gif b/net.sourceforge.phpeclipse/icons/dtool16/newpackfolder_wiz.gif new file mode 100644 index 0000000..edd8a08 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/newpackfolder_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/newsbook_wiz.gif b/net.sourceforge.phpeclipse/icons/dtool16/newsbook_wiz.gif new file mode 100644 index 0000000..2705628 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/newsbook_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/next_error_nav.gif b/net.sourceforge.phpeclipse/icons/dtool16/next_error_nav.gif new file mode 100644 index 0000000..874bf69 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/next_error_nav.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/opentype.gif b/net.sourceforge.phpeclipse/icons/dtool16/opentype.gif new file mode 100644 index 0000000..09c754c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/opentype.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/pack_sbook.gif b/net.sourceforge.phpeclipse/icons/dtool16/pack_sbook.gif new file mode 100644 index 0000000..1319191 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/pack_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/prev_error_nav.gif b/net.sourceforge.phpeclipse/icons/dtool16/prev_error_nav.gif new file mode 100644 index 0000000..4c32376 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/prev_error_nav.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/run_sbook.gif b/net.sourceforge.phpeclipse/icons/dtool16/run_sbook.gif new file mode 100644 index 0000000..a38e4ad Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/run_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/segment_edit.gif b/net.sourceforge.phpeclipse/icons/dtool16/segment_edit.gif new file mode 100644 index 0000000..6844777 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/segment_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/shift_l_edit.gif b/net.sourceforge.phpeclipse/icons/dtool16/shift_l_edit.gif new file mode 100644 index 0000000..a93966e Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/shift_l_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/shift_r_edit.gif b/net.sourceforge.phpeclipse/icons/dtool16/shift_r_edit.gif new file mode 100644 index 0000000..c1254af Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/shift_r_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/term_sbook.gif b/net.sourceforge.phpeclipse/icons/dtool16/term_sbook.gif new file mode 100644 index 0000000..bf15460 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/term_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/dtool16/uncomment_edit.gif b/net.sourceforge.phpeclipse/icons/dtool16/uncomment_edit.gif new file mode 100644 index 0000000..dcad7bc Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/dtool16/uncomment_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/add_exc.gif b/net.sourceforge.phpeclipse/icons/elcl16/add_exc.gif new file mode 100644 index 0000000..3eb5d12 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/add_exc.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/alphab_sort_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/alphab_sort_co.gif new file mode 100644 index 0000000..9d38f6d Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/alphab_sort_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/class_obj.gif b/net.sourceforge.phpeclipse/icons/elcl16/class_obj.gif new file mode 100644 index 0000000..3a5283a Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/class_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/clear_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/clear_co.gif new file mode 100644 index 0000000..6faf8d6 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/clear_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/collapseall.gif b/net.sourceforge.phpeclipse/icons/elcl16/collapseall.gif new file mode 100644 index 0000000..3409b11 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/collapseall.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/default_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/default_co.gif new file mode 100644 index 0000000..d8e1506 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/default_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/definingtype_sort_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/definingtype_sort_co.gif new file mode 100644 index 0000000..3a308c5 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/definingtype_sort_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/exc_catch.gif b/net.sourceforge.phpeclipse/icons/elcl16/exc_catch.gif new file mode 100644 index 0000000..3a63aae Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/exc_catch.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/fields_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/fields_co.gif new file mode 100644 index 0000000..ac9f965 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/fields_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/filter_ps.gif b/net.sourceforge.phpeclipse/icons/elcl16/filter_ps.gif new file mode 100644 index 0000000..5372656 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/filter_ps.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/final_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/final_co.gif new file mode 100644 index 0000000..fdf0285 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/final_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/flatLayout.gif b/net.sourceforge.phpeclipse/icons/elcl16/flatLayout.gif new file mode 100644 index 0000000..9f9ca48 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/flatLayout.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/gointo_toplevel_type.gif b/net.sourceforge.phpeclipse/icons/elcl16/gointo_toplevel_type.gif new file mode 100644 index 0000000..b920e33 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/gointo_toplevel_type.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/hexad_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/hexad_co.gif new file mode 100644 index 0000000..c046c42 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/hexad_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/hierarchicalLayout.gif b/net.sourceforge.phpeclipse/icons/elcl16/hierarchicalLayout.gif new file mode 100644 index 0000000..b50b2c3 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/hierarchicalLayout.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/hierarchy_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/hierarchy_co.gif new file mode 100644 index 0000000..fdf4104 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/hierarchy_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/history_list.gif b/net.sourceforge.phpeclipse/icons/elcl16/history_list.gif new file mode 100644 index 0000000..fce22c1 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/history_list.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/impl_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/impl_co.gif new file mode 100644 index 0000000..bfab85c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/impl_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/inher_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/inher_co.gif new file mode 100644 index 0000000..6b422e7 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/inher_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/lock_close.gif b/net.sourceforge.phpeclipse/icons/elcl16/lock_close.gif new file mode 100644 index 0000000..d0dea1c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/lock_close.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/metharg_obj.gif b/net.sourceforge.phpeclipse/icons/elcl16/metharg_obj.gif new file mode 100644 index 0000000..e43f9ee Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/metharg_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/pack_empty_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/pack_empty_co.gif new file mode 100644 index 0000000..ad9d74b Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/pack_empty_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/private_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/private_co.gif new file mode 100644 index 0000000..fb94c77 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/private_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/protected_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/protected_co.gif new file mode 100644 index 0000000..270bdac Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/protected_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/public_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/public_co.gif new file mode 100644 index 0000000..662f345 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/public_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/refresh_nav.gif b/net.sourceforge.phpeclipse/icons/elcl16/refresh_nav.gif new file mode 100644 index 0000000..919423d Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/refresh_nav.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/remove_exc.gif b/net.sourceforge.phpeclipse/icons/elcl16/remove_exc.gif new file mode 100644 index 0000000..310510e Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/remove_exc.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/removea_exc.gif b/net.sourceforge.phpeclipse/icons/elcl16/removea_exc.gif new file mode 100644 index 0000000..33908b1 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/removea_exc.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/search_sortmatch.gif b/net.sourceforge.phpeclipse/icons/elcl16/search_sortmatch.gif new file mode 100644 index 0000000..336c0ec Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/search_sortmatch.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/static_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/static_co.gif new file mode 100644 index 0000000..9330990 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/static_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/sub_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/sub_co.gif new file mode 100644 index 0000000..cd768de Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/sub_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/super_co.gif b/net.sourceforge.phpeclipse/icons/elcl16/super_co.gif new file mode 100644 index 0000000..4ea1f3c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/super_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/synced.gif b/net.sourceforge.phpeclipse/icons/elcl16/synced.gif new file mode 100644 index 0000000..ae5d548 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/synced.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/th_horizontal.gif b/net.sourceforge.phpeclipse/icons/elcl16/th_horizontal.gif new file mode 100644 index 0000000..a1b054f Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/th_horizontal.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/th_showqualified.gif b/net.sourceforge.phpeclipse/icons/elcl16/th_showqualified.gif new file mode 100644 index 0000000..3aa2efa Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/th_showqualified.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/th_single.gif b/net.sourceforge.phpeclipse/icons/elcl16/th_single.gif new file mode 100644 index 0000000..d6f1cdf Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/th_single.gif differ diff --git a/net.sourceforge.phpeclipse/icons/elcl16/th_vertical.gif b/net.sourceforge.phpeclipse/icons/elcl16/th_vertical.gif new file mode 100644 index 0000000..1795443 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/elcl16/th_vertical.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/comment_edit.gif b/net.sourceforge.phpeclipse/icons/etool16/comment_edit.gif new file mode 100644 index 0000000..ac4a4f3 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/comment_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/disp_sbook.gif b/net.sourceforge.phpeclipse/icons/etool16/disp_sbook.gif new file mode 100644 index 0000000..3bcafea Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/disp_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/export_wiz.gif b/net.sourceforge.phpeclipse/icons/etool16/export_wiz.gif new file mode 100644 index 0000000..dc6292d Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/export_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/exportjar_wiz.gif b/net.sourceforge.phpeclipse/icons/etool16/exportjar_wiz.gif new file mode 100644 index 0000000..a50e16b Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/exportjar_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/format_edit.gif b/net.sourceforge.phpeclipse/icons/etool16/format_edit.gif new file mode 100644 index 0000000..f247efc Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/format_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/import_wiz.gif b/net.sourceforge.phpeclipse/icons/etool16/import_wiz.gif new file mode 100644 index 0000000..74dc174 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/import_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/importjar_wiz.gif b/net.sourceforge.phpeclipse/icons/etool16/importjar_wiz.gif new file mode 100644 index 0000000..51fa044 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/importjar_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/insp_sbook.gif b/net.sourceforge.phpeclipse/icons/etool16/insp_sbook.gif new file mode 100644 index 0000000..bcd5f22 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/insp_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/java_app.gif b/net.sourceforge.phpeclipse/icons/etool16/java_app.gif new file mode 100644 index 0000000..09d704e Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/java_app.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/java_attach.gif b/net.sourceforge.phpeclipse/icons/etool16/java_attach.gif new file mode 100644 index 0000000..ee81236 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/java_attach.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/java_workingset_wiz.gif b/net.sourceforge.phpeclipse/icons/etool16/java_workingset_wiz.gif new file mode 100644 index 0000000..af26e1e Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/java_workingset_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/javadoc.gif b/net.sourceforge.phpeclipse/icons/etool16/javadoc.gif new file mode 100644 index 0000000..7d04c37 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/javadoc.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/jdoc_hover_edit.gif b/net.sourceforge.phpeclipse/icons/etool16/jdoc_hover_edit.gif new file mode 100644 index 0000000..96420e3 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/jdoc_hover_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/newclass_wiz.gif b/net.sourceforge.phpeclipse/icons/etool16/newclass_wiz.gif new file mode 100644 index 0000000..a34cb30 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/newclass_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/newfield_wiz.gif b/net.sourceforge.phpeclipse/icons/etool16/newfield_wiz.gif new file mode 100644 index 0000000..2b2157a Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/newfield_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/newint_wiz.gif b/net.sourceforge.phpeclipse/icons/etool16/newint_wiz.gif new file mode 100644 index 0000000..00bc0d0 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/newint_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/newjprj_wiz.gif b/net.sourceforge.phpeclipse/icons/etool16/newjprj_wiz.gif new file mode 100644 index 0000000..1cf466b Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/newjprj_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/newjworkingSet_wiz.gif b/net.sourceforge.phpeclipse/icons/etool16/newjworkingSet_wiz.gif new file mode 100644 index 0000000..09d704e Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/newjworkingSet_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/newpack_wiz.gif b/net.sourceforge.phpeclipse/icons/etool16/newpack_wiz.gif new file mode 100644 index 0000000..bbe2eba Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/newpack_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/newpackfolder_wiz.gif b/net.sourceforge.phpeclipse/icons/etool16/newpackfolder_wiz.gif new file mode 100644 index 0000000..daf9f59 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/newpackfolder_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/newsbook_wiz.gif b/net.sourceforge.phpeclipse/icons/etool16/newsbook_wiz.gif new file mode 100644 index 0000000..4f371de Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/newsbook_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/next_error_nav.gif b/net.sourceforge.phpeclipse/icons/etool16/next_error_nav.gif new file mode 100644 index 0000000..6a8e019 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/next_error_nav.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/opentype.gif b/net.sourceforge.phpeclipse/icons/etool16/opentype.gif new file mode 100644 index 0000000..c945ea9 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/opentype.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/pack_sbook.gif b/net.sourceforge.phpeclipse/icons/etool16/pack_sbook.gif new file mode 100644 index 0000000..1211fcd Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/pack_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/prev_error_nav.gif b/net.sourceforge.phpeclipse/icons/etool16/prev_error_nav.gif new file mode 100644 index 0000000..2cba4b1 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/prev_error_nav.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/run_sbook.gif b/net.sourceforge.phpeclipse/icons/etool16/run_sbook.gif new file mode 100644 index 0000000..924a2cc Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/run_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/shift_l_edit.gif b/net.sourceforge.phpeclipse/icons/etool16/shift_l_edit.gif new file mode 100644 index 0000000..fe7b311 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/shift_l_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/shift_r_edit.gif b/net.sourceforge.phpeclipse/icons/etool16/shift_r_edit.gif new file mode 100644 index 0000000..e0f2a56 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/shift_r_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/term_sbook.gif b/net.sourceforge.phpeclipse/icons/etool16/term_sbook.gif new file mode 100644 index 0000000..37f8d22 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/term_sbook.gif differ diff --git a/net.sourceforge.phpeclipse/icons/etool16/uncomment_edit.gif b/net.sourceforge.phpeclipse/icons/etool16/uncomment_edit.gif new file mode 100644 index 0000000..7b3c966 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/etool16/uncomment_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/eview16/browse_persp.gif b/net.sourceforge.phpeclipse/icons/eview16/browse_persp.gif new file mode 100644 index 0000000..32ef186 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/eview16/browse_persp.gif differ diff --git a/net.sourceforge.phpeclipse/icons/eview16/class_hi.gif b/net.sourceforge.phpeclipse/icons/eview16/class_hi.gif new file mode 100644 index 0000000..481e5d0 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/eview16/class_hi.gif differ diff --git a/net.sourceforge.phpeclipse/icons/eview16/hierch_persp.gif b/net.sourceforge.phpeclipse/icons/eview16/hierch_persp.gif new file mode 100644 index 0000000..6e01dc0 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/eview16/hierch_persp.gif differ diff --git a/net.sourceforge.phpeclipse/icons/eview16/jperspective.gif b/net.sourceforge.phpeclipse/icons/eview16/jperspective.gif new file mode 100644 index 0000000..1642d8c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/eview16/jperspective.gif differ diff --git a/net.sourceforge.phpeclipse/icons/eview16/members.gif b/net.sourceforge.phpeclipse/icons/eview16/members.gif new file mode 100644 index 0000000..8d09d00 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/eview16/members.gif differ diff --git a/net.sourceforge.phpeclipse/icons/eview16/package.gif b/net.sourceforge.phpeclipse/icons/eview16/package.gif new file mode 100644 index 0000000..1228d12 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/eview16/package.gif differ diff --git a/net.sourceforge.phpeclipse/icons/eview16/packages.gif b/net.sourceforge.phpeclipse/icons/eview16/packages.gif new file mode 100644 index 0000000..80fef75 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/eview16/packages.gif differ diff --git a/net.sourceforge.phpeclipse/icons/eview16/projects.gif b/net.sourceforge.phpeclipse/icons/eview16/projects.gif new file mode 100644 index 0000000..2357c93 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/eview16/projects.gif differ diff --git a/net.sourceforge.phpeclipse/icons/eview16/types.gif b/net.sourceforge.phpeclipse/icons/eview16/types.gif new file mode 100644 index 0000000..12b9e70 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/eview16/types.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/brkpi_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/brkpi_obj.gif new file mode 100644 index 0000000..afcf4b8 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/brkpi_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/change.gif b/net.sourceforge.phpeclipse/icons/obj16/change.gif new file mode 100644 index 0000000..5bef5e7 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/change.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/class_default_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/class_default_obj.gif new file mode 100644 index 0000000..5f2a62e Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/class_default_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/classf_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/classf_obj.gif new file mode 100644 index 0000000..cfb37c4 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/classf_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/classfo_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/classfo_obj.gif new file mode 100644 index 0000000..9dc7490 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/classfo_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/compare_field.gif b/net.sourceforge.phpeclipse/icons/obj16/compare_field.gif new file mode 100644 index 0000000..db8bb07 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/compare_field.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/compare_method.gif b/net.sourceforge.phpeclipse/icons/obj16/compare_method.gif new file mode 100644 index 0000000..502b835 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/compare_method.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/composite_change.gif b/net.sourceforge.phpeclipse/icons/obj16/composite_change.gif new file mode 100644 index 0000000..661a2cf Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/composite_change.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/correction_change.gif b/net.sourceforge.phpeclipse/icons/obj16/correction_change.gif new file mode 100644 index 0000000..09d776f Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/correction_change.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/correction_delete_import.gif b/net.sourceforge.phpeclipse/icons/obj16/correction_delete_import.gif new file mode 100644 index 0000000..118f677 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/correction_delete_import.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/correction_move.gif b/net.sourceforge.phpeclipse/icons/obj16/correction_move.gif new file mode 100644 index 0000000..80b1146 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/correction_move.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/correction_rename.gif b/net.sourceforge.phpeclipse/icons/obj16/correction_rename.gif new file mode 100644 index 0000000..09d776f Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/correction_rename.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/cp_order_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/cp_order_obj.gif new file mode 100644 index 0000000..98ec3b3 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/cp_order_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/cu_change.gif b/net.sourceforge.phpeclipse/icons/obj16/cu_change.gif new file mode 100644 index 0000000..02fad7f Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/cu_change.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/cu_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/cu_obj.gif new file mode 100644 index 0000000..aba55e9 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/cu_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/empty_logical_package_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/empty_logical_package_obj.gif new file mode 100644 index 0000000..d0f64fc Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/empty_logical_package_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/empty_pack_fldr_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/empty_pack_fldr_obj.gif new file mode 100644 index 0000000..adc730f Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/empty_pack_fldr_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/empty_pack_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/empty_pack_obj.gif new file mode 100644 index 0000000..8067752 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/empty_pack_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/envvar_nonexist_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/envvar_nonexist_obj.gif new file mode 100644 index 0000000..19cf3f3 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/envvar_nonexist_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/envvar_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/envvar_obj.gif new file mode 100644 index 0000000..d079ebb Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/envvar_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/exclusion_filter_attrib.gif b/net.sourceforge.phpeclipse/icons/obj16/exclusion_filter_attrib.gif new file mode 100644 index 0000000..3d83fd6 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/exclusion_filter_attrib.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/fatalerror_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/fatalerror_obj.gif new file mode 100644 index 0000000..d85b98b Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/fatalerror_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/field_default_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/field_default_obj.gif new file mode 100644 index 0000000..51e02b3 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/field_default_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/field_private_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/field_private_obj.gif new file mode 100644 index 0000000..0e29242 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/field_private_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/field_protected_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/field_protected_obj.gif new file mode 100644 index 0000000..222116b Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/field_protected_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/field_public_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/field_public_obj.gif new file mode 100644 index 0000000..630b286 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/field_public_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/file_change.gif b/net.sourceforge.phpeclipse/icons/obj16/file_change.gif new file mode 100644 index 0000000..df822a9 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/file_change.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/file_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/file_obj.gif new file mode 100644 index 0000000..6b86d07 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/file_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/html_tag_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/html_tag_obj.gif new file mode 100644 index 0000000..f10ccee Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/html_tag_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/imp_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/imp_obj.gif new file mode 100644 index 0000000..dea2e92 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/imp_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/innerclass_default_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/innerclass_default_obj.gif new file mode 100644 index 0000000..5f2a62e Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/innerclass_default_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/innerclass_private_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/innerclass_private_obj.gif new file mode 100644 index 0000000..dfdcce1 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/innerclass_private_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/innerclass_protected_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/innerclass_protected_obj.gif new file mode 100644 index 0000000..039d129 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/innerclass_protected_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/innerclass_public_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/innerclass_public_obj.gif new file mode 100644 index 0000000..15cfc6d Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/innerclass_public_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/innerinterface_default_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/innerinterface_default_obj.gif new file mode 100644 index 0000000..6ce3038 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/innerinterface_default_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/innerinterface_private_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/innerinterface_private_obj.gif new file mode 100644 index 0000000..447c2b4 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/innerinterface_private_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/innerinterface_protected_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/innerinterface_protected_obj.gif new file mode 100644 index 0000000..98b6c63 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/innerinterface_protected_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/innerinterface_public_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/innerinterface_public_obj.gif new file mode 100644 index 0000000..13c9570 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/innerinterface_public_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/int_default_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/int_default_obj.gif new file mode 100644 index 0000000..6ce3038 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/int_default_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/intf_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/intf_obj.gif new file mode 100644 index 0000000..85069e1 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/intf_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jar_desc_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jar_desc_obj.gif new file mode 100644 index 0000000..0b99965 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jar_desc_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jar_l_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jar_l_obj.gif new file mode 100644 index 0000000..11e04e2 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jar_l_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jar_lsrc_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jar_lsrc_obj.gif new file mode 100644 index 0000000..bb78fff Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jar_lsrc_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jar_nonexist_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jar_nonexist_obj.gif new file mode 100644 index 0000000..e56ec31 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jar_nonexist_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jar_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jar_obj.gif new file mode 100644 index 0000000..61f34f2 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jar_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jar_src_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jar_src_obj.gif new file mode 100644 index 0000000..a515124 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jar_src_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/java_model_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/java_model_obj.gif new file mode 100644 index 0000000..7b2b633 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/java_model_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/javadoc_location_attrib.gif b/net.sourceforge.phpeclipse/icons/obj16/javadoc_location_attrib.gif new file mode 100644 index 0000000..2612d34 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/javadoc_location_attrib.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jcu_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jcu_obj.gif new file mode 100644 index 0000000..4cecec9 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jcu_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jcu_resource_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jcu_resource_obj.gif new file mode 100644 index 0000000..819ec34 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jcu_resource_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jdoc_tag_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jdoc_tag_obj.gif new file mode 100644 index 0000000..4e343b9 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jdoc_tag_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jexception_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jexception_obj.gif new file mode 100644 index 0000000..4522b44 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jexception_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jexceptiond_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jexceptiond_obj.gif new file mode 100644 index 0000000..0e981e3 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jexceptiond_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jrtexception_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jrtexception_obj.gif new file mode 100644 index 0000000..9f5a027 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jrtexception_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jsbook_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jsbook_obj.gif new file mode 100644 index 0000000..a162c17 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jsbook_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jsbook_run_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jsbook_run_obj.gif new file mode 100644 index 0000000..5bbd272 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jsbook_run_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jsearch_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jsearch_obj.gif new file mode 100644 index 0000000..ee75bdb Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jsearch_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/jworkingSet_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/jworkingSet_obj.gif new file mode 100644 index 0000000..e369ff8 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/jworkingSet_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/library_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/library_obj.gif new file mode 100644 index 0000000..f966fc3 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/library_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/localvariable_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/localvariable_obj.gif new file mode 100644 index 0000000..bf0a368 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/localvariable_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/logical_package_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/logical_package_obj.gif new file mode 100644 index 0000000..7656618 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/logical_package_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/methdef_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/methdef_obj.gif new file mode 100644 index 0000000..fde860a Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/methdef_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/methpri_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/methpri_obj.gif new file mode 100644 index 0000000..96f464d Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/methpri_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/methpro_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/methpro_obj.gif new file mode 100644 index 0000000..d524944 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/methpro_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/methpub_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/methpub_obj.gif new file mode 100644 index 0000000..b512915 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/methpub_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/never_translate.gif b/net.sourceforge.phpeclipse/icons/obj16/never_translate.gif new file mode 100644 index 0000000..d20d298 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/never_translate.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/nls_search_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/nls_search_obj.gif new file mode 100644 index 0000000..4d1bda1 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/nls_search_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/occ_match.gif b/net.sourceforge.phpeclipse/icons/obj16/occ_match.gif new file mode 100644 index 0000000..6e8e08d Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/occ_match.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/occ_read.gif b/net.sourceforge.phpeclipse/icons/obj16/occ_read.gif new file mode 100644 index 0000000..704e3c4 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/occ_read.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/occ_write.gif b/net.sourceforge.phpeclipse/icons/obj16/occ_write.gif new file mode 100644 index 0000000..b834948 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/occ_write.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/output_folder_attrib.gif b/net.sourceforge.phpeclipse/icons/obj16/output_folder_attrib.gif new file mode 100644 index 0000000..07b0883 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/output_folder_attrib.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/package_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/package_obj.gif new file mode 100644 index 0000000..64622ef Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/package_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/packagefolder_nonexist_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/packagefolder_nonexist_obj.gif new file mode 100644 index 0000000..db9749b Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/packagefolder_nonexist_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/packagefolder_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/packagefolder_obj.gif new file mode 100644 index 0000000..387781b Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/packagefolder_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/packd_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/packd_obj.gif new file mode 100644 index 0000000..3aa2efa Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/packd_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/prjct_nonexist_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/prjct_nonexist_obj.gif new file mode 100644 index 0000000..5fce4d6 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/prjct_nonexist_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/profield_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/profield_obj.gif new file mode 100644 index 0000000..3932f61 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/profield_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/pubfield_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/pubfield_obj.gif new file mode 100644 index 0000000..e5fd09b Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/pubfield_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/quickfix_error_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/quickfix_error_obj.gif new file mode 100644 index 0000000..d6427e8 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/quickfix_error_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/quickfix_warning_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/quickfix_warning_obj.gif new file mode 100644 index 0000000..b34d85f Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/quickfix_warning_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/search_decl_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/search_decl_obj.gif new file mode 100644 index 0000000..3eddefd Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/search_decl_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/search_ref_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/search_ref_obj.gif new file mode 100644 index 0000000..1b0c43b Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/search_ref_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/skip.gif b/net.sourceforge.phpeclipse/icons/obj16/skip.gif new file mode 100644 index 0000000..5d50ae2 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/skip.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/source_attach_attrib.gif b/net.sourceforge.phpeclipse/icons/obj16/source_attach_attrib.gif new file mode 100644 index 0000000..3976f8f Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/source_attach_attrib.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/text_edit.gif b/net.sourceforge.phpeclipse/icons/obj16/text_edit.gif new file mode 100644 index 0000000..c639f65 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/text_edit.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/translate.gif b/net.sourceforge.phpeclipse/icons/obj16/translate.gif new file mode 100644 index 0000000..00da14e Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/translate.gif differ diff --git a/net.sourceforge.phpeclipse/icons/obj16/unknown_obj.gif b/net.sourceforge.phpeclipse/icons/obj16/unknown_obj.gif new file mode 100644 index 0000000..c0058f7 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/obj16/unknown_obj.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/abstract_co.gif b/net.sourceforge.phpeclipse/icons/ovr16/abstract_co.gif new file mode 100644 index 0000000..3e8c061 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/abstract_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/constr_ovr.gif b/net.sourceforge.phpeclipse/icons/ovr16/constr_ovr.gif new file mode 100644 index 0000000..3bfa12b Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/constr_ovr.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/error_co.gif b/net.sourceforge.phpeclipse/icons/ovr16/error_co.gif new file mode 100644 index 0000000..8612eaf Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/error_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/final_co.gif b/net.sourceforge.phpeclipse/icons/ovr16/final_co.gif new file mode 100644 index 0000000..d734b3d Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/final_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/focus_ovr.gif b/net.sourceforge.phpeclipse/icons/ovr16/focus_ovr.gif new file mode 100644 index 0000000..e96d53b Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/focus_ovr.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/implm_co.gif b/net.sourceforge.phpeclipse/icons/ovr16/implm_co.gif new file mode 100644 index 0000000..16c78d7 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/implm_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/java_ovr.gif b/net.sourceforge.phpeclipse/icons/ovr16/java_ovr.gif new file mode 100644 index 0000000..3d1362f Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/java_ovr.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/native_co.gif b/net.sourceforge.phpeclipse/icons/ovr16/native_co.gif new file mode 100644 index 0000000..77613cd Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/native_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/over_co.gif b/net.sourceforge.phpeclipse/icons/ovr16/over_co.gif new file mode 100644 index 0000000..c5f5d95 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/over_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/run_co.gif b/net.sourceforge.phpeclipse/icons/ovr16/run_co.gif new file mode 100644 index 0000000..e179837 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/run_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/static_co.gif b/net.sourceforge.phpeclipse/icons/ovr16/static_co.gif new file mode 100644 index 0000000..08438a5 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/static_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/synch_co.gif b/net.sourceforge.phpeclipse/icons/ovr16/synch_co.gif new file mode 100644 index 0000000..ff0ddb8 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/synch_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/typeinfocus_underlay.gif b/net.sourceforge.phpeclipse/icons/ovr16/typeinfocus_underlay.gif new file mode 100644 index 0000000..ec7807c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/typeinfocus_underlay.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/volatile_co.gif b/net.sourceforge.phpeclipse/icons/ovr16/volatile_co.gif new file mode 100644 index 0000000..8ddf0be Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/volatile_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/ovr16/warning_co.gif b/net.sourceforge.phpeclipse/icons/ovr16/warning_co.gif new file mode 100644 index 0000000..3af228c Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/ovr16/warning_co.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/addlibrary_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/addlibrary_wiz.gif new file mode 100644 index 0000000..e0eea42 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/addlibrary_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/coderefact_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/coderefact_wiz.gif new file mode 100644 index 0000000..10e80d9 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/coderefact_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/compunitrefact_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/compunitrefact_wiz.gif new file mode 100644 index 0000000..310ee8a Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/compunitrefact_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/export_javadoc_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/export_javadoc_wiz.gif new file mode 100644 index 0000000..62aa7ba Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/export_javadoc_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/extstr_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/extstr_wiz.gif new file mode 100644 index 0000000..111b284 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/extstr_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/fieldrefact_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/fieldrefact_wiz.gif new file mode 100644 index 0000000..2e0d346 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/fieldrefact_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/jar_pack_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/jar_pack_wiz.gif new file mode 100644 index 0000000..0de3582 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/jar_pack_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/java_app_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/java_app_wiz.gif new file mode 100644 index 0000000..8d425d5 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/java_app_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/java_attach_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/java_attach_wiz.gif new file mode 100644 index 0000000..544efda Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/java_attach_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/java_workingset_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/java_workingset_wiz.gif new file mode 100644 index 0000000..31c69f8 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/java_workingset_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/methrefact_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/methrefact_wiz.gif new file mode 100644 index 0000000..3ea2af7 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/methrefact_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/newfield_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/newfield_wiz.gif new file mode 100644 index 0000000..478cfe3 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/newfield_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/newint_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/newint_wiz.gif new file mode 100644 index 0000000..385d0b8 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/newint_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/newjprj_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/newjprj_wiz.gif new file mode 100644 index 0000000..3172ab1 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/newjprj_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/newmeth_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/newmeth_wiz.gif new file mode 100644 index 0000000..a17c735 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/newmeth_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/newpack_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/newpack_wiz.gif new file mode 100644 index 0000000..ba81b8e Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/newpack_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/newsbook_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/newsbook_wiz.gif new file mode 100644 index 0000000..ba31651 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/newsbook_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/newsrcfldr_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/newsrcfldr_wiz.gif new file mode 100644 index 0000000..4b1ad56 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/newsrcfldr_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/packrefact_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/packrefact_wiz.gif new file mode 100644 index 0000000..72b4eff Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/packrefact_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/pullup_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/pullup_wiz.gif new file mode 100644 index 0000000..0ae1083 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/pullup_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/refactor_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/refactor_wiz.gif new file mode 100644 index 0000000..af125c7 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/refactor_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/icons/wizban/typerefact_wiz.gif b/net.sourceforge.phpeclipse/icons/wizban/typerefact_wiz.gif new file mode 100644 index 0000000..90e2d45 Binary files /dev/null and b/net.sourceforge.phpeclipse/icons/wizban/typerefact_wiz.gif differ diff --git a/net.sourceforge.phpeclipse/plugin.properties b/net.sourceforge.phpeclipse/plugin.properties index 97666be..ecc9f01 100644 --- a/net.sourceforge.phpeclipse/plugin.properties +++ b/net.sourceforge.phpeclipse/plugin.properties @@ -4,6 +4,8 @@ pluginName=PHPEclipse Tools Core providerName=phpeclipse.de naturePHP.name=PHP Project +phpProblemName=PHP Problem +phpEditorTextHoversName=PHP Editor Text Hovers perspectivePHP.name=PHP perspectiveHTML.name=HTML @@ -34,6 +36,16 @@ htmlFileExtension=html htmFileExtension=htm xmlFileExtension=xml tplFileExtension=tpl + +sourceHover= Source +sourceHoverDescription= Shows the source of the selected element. +javadocHover= PHPdoc +javadocHoverDescription= Shows the PHPdoc of the selected element. +sequentialHover= Best Match +sequentialHoverDescription= Shows the hover which fits best for the selected element and the current context. +problemHover= Problems +problemHoverDescription= Shows the problem descriptions for the selected element. + # # Action sets # diff --git a/net.sourceforge.phpeclipse/plugin.xml b/net.sourceforge.phpeclipse/plugin.xml index a94138f..5443171 100644 --- a/net.sourceforge.phpeclipse/plugin.xml +++ b/net.sourceforge.phpeclipse/plugin.xml @@ -24,30 +24,46 @@ - + class="net.sourceforge.phpdt.internal.core.JavaProject"> + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + r + + + + + + * Clients should subclass this class to implement a specific classpath + * variable initializer. The subclass must have a public 0-argument + * constructor and a concrete implementation of initialize. + * + * @see IClasspathEntry + * @since 2.0 + */ +public abstract class ClasspathVariableInitializer { + + /** + * Creates a new classpath variable initializer. + */ + public ClasspathVariableInitializer() { + } + + /** + * Binds a value to the workspace classpath variable with the given name, + * or fails silently if this cannot be done. + *

+ * A variable initializer is automatically activated whenever a variable value + * is needed and none has been recorded so far. The implementation of + * the initializer can set the corresponding variable using + * JavaCore#setClasspathVariable. + * + * @param variable the name of the workspace classpath variable + * that requires a binding + * + * @see JavaCore#getClasspathVariable(String) + * @see JavaCore#setClasspathVariable(String, IPath, IProgressMonitor) + * @see JavaCore#setClasspathVariables(String[], IPath[], IProgressMonitor) + */ + public abstract void initialize(String variable); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/Flags.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/Flags.java index 3fcf33a..fefe486 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/Flags.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/Flags.java @@ -80,12 +80,12 @@ public final class Flags { * Interface property flag. See The Java Virtual Machine Specification for more details. * @since 2.0 */ -// public static final int AccInterface = IConstants.AccInterface; + public static final int AccInterface = IConstants.AccInterface; /** * Abstract property flag. See The Java Virtual Machine Specification for more details. * @since 2.0 */ -// public static final int AccAbstract = IConstants.AccAbstract; + public static final int AccAbstract = IConstants.AccAbstract; /** * Strictfp property flag. See The Java Virtual Machine Specification for more details. * @since 2.0 @@ -105,7 +105,7 @@ public final class Flags { * Deprecated property flag. See The Java Virtual Machine Specification for more details. * @since 2.0 */ -// public static final int AccDeprecated = IConstants.AccDeprecated; + public static final int AccDeprecated = IConstants.AccDeprecated; /** * Not instantiable. @@ -118,9 +118,9 @@ public final class Flags { * @param flags the flags * @return true if the abstract modifier is included */ -// public static boolean isAbstract(int flags) { -// return (flags & AccAbstract) != 0; -// } + public static boolean isAbstract(int flags) { + return (flags & AccAbstract) != 0; + } /** * Returns whether the given integer includes the indication that the * element is deprecated (@deprecated tag in Javadoc comment). @@ -128,9 +128,9 @@ public final class Flags { * @param flags the flags * @return true if the element is marked as deprecated */ -// public static boolean isDeprecated(int flags) { -// return (flags & AccDeprecated) != 0; -// } + public static boolean isDeprecated(int flags) { + return (flags & AccDeprecated) != 0; + } /** * Returns whether the given integer includes the final modifier. * @@ -147,9 +147,9 @@ public final class Flags { * @return true if the interface modifier is included * @since 2.0 */ -// public static boolean isInterface(int flags) { -// return (flags & AccInterface) != 0; -// } + public static boolean isInterface(int flags) { + return (flags & AccInterface) != 0; + } /** * Returns whether the given integer includes the native modifier. * diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IBufferFactory.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IBufferFactory.java index 45389b6..15b61e6 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IBufferFactory.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IBufferFactory.java @@ -28,6 +28,6 @@ public interface IBufferFactory { * @param owner the owner of the buffer * @see IBuffer */ -// IBuffer createBuffer(IOpenable owner); + IBuffer createBuffer(IOpenable owner); } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IClasspathEntry.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IClasspathEntry.java new file mode 100644 index 0000000..83de070 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IClasspathEntry.java @@ -0,0 +1,370 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core; + +import org.eclipse.core.runtime.IPath; + +/** + * An entry on a Java project classpath identifying one or more package fragment + * roots. A classpath entry has a content kind (either source, + * K_SOURCE, or binary, K_BINARY), which is inherited + * by each package fragment root and package fragment associated with the entry. + *

+ * A classpath entry can refer to any of the following:

    + * + *
  • Source code in the current project. In this case, the entry identifies a + * root folder in the current project containing package fragments and + * .java source files. The root folder itself represents a default + * package, subfolders represent package fragments, and .java files + * represent compilation units. All compilation units will be compiled when + * the project is built. The classpath entry must specify the + * absolute path to the root folder. Entries of this kind are + * associated with the CPE_SOURCE constant. + * Source classpath entries can carry patterns to exclude selected files. + * Excluded .java source files do not appear as compilation + * units and are not compiled when the project is built. + *
  • + * + *
  • A binary library in the current project, in another project, or in the external + * file system. In this case the entry identifies a JAR (or root folder) containing + * package fragments and .class files. The classpath entry + * must specify the absolute path to the JAR (or root folder), and in case it refers + * to an external JAR, then there is no associated resource in the workbench. Entries + * of this kind are associated with the CPE_LIBRARY constant.
  • + * + *
  • A required project. In this case the entry identifies another project in + * the workspace. The required project is used as a binary library when compiling + * (that is, the builder looks in the output location of the required project + * for required .class files when building). When performing other + * "development" operations - such as code assist, code resolve, type hierarchy + * creation, etc. - the source code of the project is referred to. Thus, development + * is performed against a required project's source code, and compilation is + * performed against a required project's last built state. The + * classpath entry must specify the absolute path to the + * project. Entries of this kind are associated with the CPE_PROJECT + * constant. + * Note: referencing a required project with a classpath entry refers to the source + * code or associated .class files located in its output location. + * It will also automatically include any other libraries or projects that the required project's classpath + * refers to, iff the corresponding classpath entries are tagged as being exported + * (IClasspathEntry#isExported). + * Unless exporting some classpath entries, classpaths are not chained by default - + * each project must specify its own classpath in its entirety.
  • + * + *
  • A path beginning in a classpath variable defined globally to the workspace. + * Entries of this kind are associated with the CPE_VARIABLE constant. + * Classpath variables are created using JavaCore#setClasspathVariable, + * and gets resolved, to either a project or library entry, using + * JavaCore#getResolvedClasspathVariable. + * It is also possible to register an automatic initializer (ClasspathVariableInitializer), + * which will be invoked through the extension point "org.eclipse.jdt.core.classpathVariableInitializer". + * After resolution, a classpath variable entry may either correspond to a project or a library entry.
  • + * + *
  • A named classpath container identified by its container path. + * A classpath container provides a way to indirectly reference a set of classpath entries through + * a classpath entry of kind CPE_CONTAINER. Typically, a classpath container can + * be used to describe a complex library composed of multiple JARs, projects or classpath variables, + * considering also that containers can be mapped differently on each project. Several projects can + * reference the same generic container path, but have each of them actually bound to a different + * container object. + * The container path is a formed by a first ID segment followed with extra segments, + * which can be used as additional hints for resolving this container reference. If no container was ever + * recorded for this container path onto this project (using setClasspathContainer, + * then a ClasspathContainerInitializer will be activated if any was registered for this + * container ID onto the extension point "org.eclipse.jdt.core.classpathContainerInitializer". + * A classpath container entry can be resolved explicitly using JavaCore#getClasspathContainer + * and the resulting container entries can contain any non-container entry. In particular, it may contain variable + * entries, which in turn needs to be resolved before being directly used. + *
    Also note that the container resolution APIs include an IJavaProject argument, so as to allow the same + * container path to be interpreted in different ways for different projects.
  • + *
+ *

+ * The result of IJavaProject#getResolvedClasspath will have all entries of type + * CPE_VARIABLE and CPE_CONTAINER resolved to a set of + * CPE_SOURCE, CPE_LIBRARY or CPE_PROJECT + * classpath entries. + *

+ * Any classpath entry other than a source folder (kind CPE_SOURCE) can + * be marked as being exported. Exported entries are automatically contributed to + * dependent projects, along with the project's default output folder, which is + * implicitly exported, and any auxiliary output folders specified on source + * classpath entries. The project's output folder(s) are always listed first, + * followed by the any exported entries. + *

+ * This interface is not intended to be implemented by clients. + * Classpath entries can be created via methods on JavaCore. + *

+ * + * @see JavaCore#newLibraryEntry + * @see JavaCore#newProjectEntry + * @see JavaCore#newSourceEntry + * @see JavaCore#newVariableEntry + * @see JavaCore#newContainerEntry + * @see ClasspathVariableInitializer + * @see ClasspathContainerInitializer + */ +public interface IClasspathEntry { + + /** + * Entry kind constant describing a classpath entry identifying a + * library. A library is a folder or JAR containing package + * fragments consisting of pre-compiled binaries. + */ + int CPE_LIBRARY = 1; + + /** + * Entry kind constant describing a classpath entry identifying a + * required project. + */ + int CPE_PROJECT = 2; + + /** + * Entry kind constant describing a classpath entry identifying a + * folder containing package fragments with source code + * to be compiled. + */ + int CPE_SOURCE = 3; + + /** + * Entry kind constant describing a classpath entry defined using + * a path that begins with a classpath variable reference. + */ + int CPE_VARIABLE = 4; + + /** + * Entry kind constant describing a classpath entry representing + * a name classpath container. + * + * @since 2.0 + */ + int CPE_CONTAINER = 5; + + /** + * Returns the kind of files found in the package fragments identified by this + * classpath entry. + * + * @return IPackageFragmentRoot.K_SOURCE for files containing + * source code, and IPackageFragmentRoot.K_BINARY for binary + * class files. + * There is no specified value for an entry denoting a variable (CPE_VARIABLE) + * or a classpath container (CPE_CONTAINER). + */ + int getContentKind(); + + /** + * Returns the kind of this classpath entry. + * + * @return one of: + *
    + *
  • CPE_SOURCE - this entry describes a source root in + its project + *
  • CPE_LIBRARY - this entry describes a folder or JAR + containing binaries + *
  • CPE_PROJECT - this entry describes another project + * + *
  • CPE_VARIABLE - this entry describes a project or library + * indirectly via a classpath variable in the first segment of the path + * * + *
  • CPE_CONTAINER - this entry describes set of entries + * referenced indirectly via a classpath container + *
+ */ + int getEntryKind(); + + /** + * Returns the set of patterns used to exclude resources associated with + * this source entry. + *

+ * Exclusion patterns allow specified portions of the resource tree rooted + * at this source entry's path to be filtered out. If no exclusion patterns + * are specified, this source entry includes all relevent files. Each path + * specified must be a relative path, and will be interpreted relative + * to this source entry's path. File patterns are case-sensitive. A file + * matched by one or more of these patterns is excluded from the + * corresponding package fragment root. + *

+ *

+ * Note that there is no need to supply a pattern to exclude ".class" files + * because a source entry filters these out automatically. + *

+ *

+ * The pattern mechanism is similar to Ant's. Each pattern is represented as + * a relative path. The path segments can be regular file or folder names or simple patterns + * involving standard wildcard characters. + *

+ *

+ * '*' matches 0 or more characters within a segment. So + * *.java matches .java, a.java + * and Foo.java, but not Foo.properties + * (does not end with .java). + *

+ *

+ * '?' matches 1 character within a segment. So ?.java + * matches a.java, A.java, + * but not .java or xyz.java (neither have + * just one character before .java). + *

+ *

+ * Combinations of *'s and ?'s are allowed. + *

+ *

+ * The special pattern '**' matches zero or more segments. A path + * like tests/ that ends in a trailing separator is interpreted + * as tests/**, and would match all files under the + * the folder named tests. + *

+ *

+ * Examples: + *

    + *
  • + * tests/** (or simply tests/) + * matches all files under a root folder + * named tests. This includes tests/Foo.java + * and tests/com/example/Foo.java, but not + * com/example/tests/Foo.java (not under a root folder named + * tests). + *
  • + *
  • + * tests/* matches all files directly below a root + * folder named tests. This includes tests/Foo.java + * and tests/FooHelp.java + * but not tests/com/example/Foo.java (not directly under + * a folder named tests) or + * com/Foo.java (not under a folder named tests). + *
  • + *
  • + * **/tests/** matches all files under any + * folder named tests. This includes tests/Foo.java, + * com/examples/tests/Foo.java, and + * com/examples/tests/unit/Foo.java, but not + * com/example/Foo.java (not under a folder named + * tests). + *
  • + *
+ *

+ * + * @return the possibly empty list of resource exclusion patterns + * associated with this source entry, and null for other + * kinds of classpath entries + * @since 2.1 + */ + IPath[] getExclusionPatterns(); + + /** + * Returns the full path to the specific location where the builder writes + * .class files generated for this source entry + * (entry kind CPE_SOURCE). + *

+ * Source entries can optionally be associated with a specific output location. + * If none is provided, the source entry will be implicitly associated with its project + * default output location (see IJavaProject#getOutputLocation). + *

+ * NOTE: A specific output location cannot coincidate with another source/library entry. + *

+ * + * @return the full path to the specific location where the builder writes + * .class files for this source entry, or null + * if using default output folder + * @since 2.1 + */ + IPath getOutputLocation(); + + /** + * Returns the path of this classpath entry. + * + * The meaning of the path of a classpath entry depends on its entry kind:
    + *
  • Source code in the current project (CPE_SOURCE) - + * The path associated with this entry is the absolute path to the root folder.
  • + *
  • A binary library in the current project (CPE_LIBRARY) - the path + * associated with this entry is the absolute path to the JAR (or root folder), and + * in case it refers to an external JAR, then there is no associated resource in + * the workbench. + *
  • A required project (CPE_PROJECT) - the path of the entry denotes the + * path to the corresponding project resource.
  • + *
  • A variable entry (CPE_VARIABLE) - the first segment of the path + * is the name of a classpath variable. If this classpath variable + * is bound to the path P, the path of the corresponding classpath entry + * is computed by appending to P the segments of the returned + * path without the variable.
  • + *
  • A container entry (CPE_CONTAINER) - the path of the entry + * is the name of the classpath container, which can be bound indirectly to a set of classpath + * entries after resolution. The containerPath is a formed by a first ID segment followed with + * extra segments that can be used as additional hints for resolving this container + * reference (also see IClasspathContainer). + *
  • + *
+ * + * @return the path of this classpath entry + */ + IPath getPath(); + + /** + * Returns the path to the source archive or folder associated with this + * classpath entry, or null if this classpath entry has no + * source attachment. + *

+ * Only library and variable classpath entries may have source attachments. + * For library classpath entries, the result path (if present) locates a source + * archive or folder. This archive or folder can be located in a project of the + * workspace or outside thr workspace. For variable classpath entries, the + * result path (if present) has an analogous form and meaning as the + * variable path, namely the first segment is the name of a classpath variable. + *

+ * + * @return the path to the source archive or folder, or null if none + */ + IPath getSourceAttachmentPath(); + + /** + * Returns the path within the source archive or folder where package fragments + * are located. An empty path indicates that packages are located at + * the root of the source archive or folder. Returns a non-null value + * if and only if getSourceAttachmentPath returns + * a non-null value. + * + * @return the path within the source archive or folder, or null if + * not applicable + */ + IPath getSourceAttachmentRootPath(); + + /** + * Returns whether this entry is exported to dependent projects. + * Always returns false for source entries (kind + * CPE_SOURCE), which cannot be exported. + * + * @return true if exported, and false otherwise + * @since 2.0 + */ + boolean isExported(); + + /** + * This is a helper method, which returns the resolved classpath entry denoted + * by an entry (if it is a variable entry). It is obtained by resolving the variable + * reference in the first segment. Returns null if unable to resolve using + * the following algorithm: + *
    + *
  • if variable segment cannot be resolved, returns null
  • + *
  • finds a project, JAR or binary folder in the workspace at the resolved path location
  • + *
  • if none finds an external JAR file or folder outside the workspace at the resolved path location
  • + *
  • if none returns null
  • + *
+ *

+ * Variable source attachment is also resolved and recorded in the resulting classpath entry. + *

+ * @return the resolved library or project classpath entry, or null + * if the given path could not be resolved to a classpath entry + *

+ * Note that this deprecated API doesn't handle CPE_CONTAINER entries. + * + * @deprecated - use JavaCore.getResolvedClasspathEntry(...) + */ + IClasspathEntry getResolvedEntry(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICompilationUnit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICompilationUnit.java index 94f7f88..5bcfd3f 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICompilationUnit.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICompilationUnit.java @@ -11,6 +11,7 @@ package net.sourceforge.phpdt.core; + /** * Represents an entire Java compilation unit (.java source file). * Compilation unit elements need to be opened before they can be navigated or manipulated. @@ -23,8 +24,8 @@ package net.sourceforge.phpdt.core; *

* This interface is not intended to be implemented by clients. *

- */ -public interface ICompilationUnit extends IJavaElement, IParent, IOpenable { + */ +public interface ICompilationUnit extends IJavaElement, ISourceReference, IParent, IOpenable, IWorkingCopy, ISourceManipulation { //extends IJavaElement, ISourceReference, IParent, IOpenable, IWorkingCopy, ISourceManipulation, ICodeAssist { /** * Creates and returns an import declaration in this compilation unit @@ -122,7 +123,7 @@ public interface ICompilationUnit extends IJavaElement, IParent, IOpenable { * @exception JavaModelException if this element does not exist or if an * exception occurs while accessing its corresponding resource */ -//IType[] getAllTypes() throws JavaModelException; +IType[] getAllTypes() throws JavaModelException; /** * Returns the smallest element within this compilation unit that * includes the given source position (that is, a method, field, etc.), or @@ -136,7 +137,7 @@ public interface ICompilationUnit extends IJavaElement, IParent, IOpenable { * @exception JavaModelException if the compilation unit does not exist or if an * exception occurs while accessing its corresponding resource */ -//IJavaElement getElementAt(int position) throws JavaModelException; +IJavaElement getElementAt(int position) throws JavaModelException; /** * Returns the first import declaration in this compilation unit with the given name. * This is a handle-only method. The import declaration may or may not exist. This @@ -174,7 +175,7 @@ public interface ICompilationUnit extends IJavaElement, IParent, IOpenable { * * @param name the name of the package declaration as defined by JLS2 7.4. (For example, "java.lang") */ -//IPackageDeclaration getPackageDeclaration(String name); +IPackageDeclaration getPackageDeclaration(String name); /** * Returns the package declarations in this compilation unit * in the order in which they appear in the source. @@ -195,7 +196,7 @@ public interface ICompilationUnit extends IJavaElement, IParent, IOpenable { * @return a handle onto the corresponding type. The type may or may not exist. * @see JavaConventions#validateCompilationUnitName(String name) */ -//IType getType(String name); +IType getType(String name); /** * Returns the top-level types declared in this compilation unit * in the order in which they appear in the source. @@ -203,6 +204,6 @@ public interface ICompilationUnit extends IJavaElement, IParent, IOpenable { * @exception JavaModelException if this element does not exist or if an * exception occurs while accessing its corresponding resource */ -//IType[] getTypes() throws JavaModelException; +IType[] getTypes() throws JavaModelException; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaElement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaElement.java index 318061a..0f4693a 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaElement.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaElement.java @@ -12,6 +12,7 @@ package net.sourceforge.phpdt.core; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IPath; /** * Common protocol for all elements provided by the Java model. @@ -129,7 +130,7 @@ public interface IJavaElement extends IAdaptable { * @return true if this element exists in the Java model, and * false if this element does not exist */ -// boolean exists(); + boolean exists(); /** * Returns the first ancestor of this Java element that has the given type. @@ -160,7 +161,7 @@ public interface IJavaElement extends IAdaptable { * @exception JavaModelException if this element does not exist or if an * exception occurs while accessing its corresponding resource */ -// IResource getCorrespondingResource() throws JavaModelException; + IResource getCorrespondingResource() throws JavaModelException; /** * Returns the name of this element. This is a handle-only method. @@ -208,7 +209,7 @@ public interface IJavaElement extends IAdaptable { * @return the containing Java project, or null if this element is * not contained in a Java project */ -// IJavaProject getJavaProject(); + IJavaProject getJavaProject(); /** * Returns the first openable parent. If this element is openable, the element @@ -243,7 +244,7 @@ public interface IJavaElement extends IAdaptable { * @return the path to the innermost resource enclosing this element * @since 2.0 */ -// IPath getPath(); + IPath getPath(); /** * Returns the innermost resource enclosing this element. @@ -299,5 +300,5 @@ public interface IJavaElement extends IAdaptable { * @exception JavaModelException if this element does not exist or if an * exception occurs while accessing its corresponding resource */ -// boolean isStructureKnown() throws JavaModelException; + boolean isStructureKnown() throws JavaModelException; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaModel.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaModel.java index a4ff657..f8cf1d8 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaModel.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaModel.java @@ -10,7 +10,9 @@ *******************************************************************************/ package net.sourceforge.phpdt.core; +import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.runtime.IProgressMonitor; /** * Represent the root Java element corresponding to the workspace. @@ -47,7 +49,7 @@ public interface IJavaModel extends IJavaElement, IOpenable, IParent { * @return true if the resource is accessible through the Java model * @since 2.1 */ -//boolean contains(IResource resource); +boolean contains(IResource resource); /** * Copies the given elements to the specified container(s). * If one container is specified, all elements are copied to that @@ -94,7 +96,7 @@ public interface IJavaModel extends IJavaElement, IOpenable, IParent { *
  • A container or element is read-only (READ_ONLY)
  • * */ -//void copy(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean replace, IProgressMonitor monitor) throws JavaModelException; +void copy(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean replace, IProgressMonitor monitor) throws JavaModelException; /** * Deletes the given elements, forcing the operation if necessary and specified. * @@ -110,7 +112,7 @@ public interface IJavaModel extends IJavaElement, IOpenable, IParent { *
  • An element is read-only (READ_ONLY)
  • * */ -//void delete(IJavaElement[] elements, boolean force, IProgressMonitor monitor) throws JavaModelException; +void delete(IJavaElement[] elements, boolean force, IProgressMonitor monitor) throws JavaModelException; /** * Returns the Java project with the given name. This is a handle-only method. * The project may or may not exist. @@ -195,7 +197,7 @@ IWorkspace getWorkspace(); * * @exception IllegalArgumentException any element or container is null */ -//void move(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean replace, IProgressMonitor monitor) throws JavaModelException; +void move(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean replace, IProgressMonitor monitor) throws JavaModelException; /** * Triggers an update of the JavaModel with respect to the referenced external archives. @@ -249,6 +251,6 @@ IWorkspace getWorkspace(); *
  • An element is read-only (READ_ONLY) * */ -//void rename(IJavaElement[] elements, IJavaElement[] destinations, String[] names, boolean replace, IProgressMonitor monitor) throws JavaModelException; +void rename(IJavaElement[] elements, IJavaElement[] destinations, String[] names, boolean replace, IProgressMonitor monitor) throws JavaModelException; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaModelMarker.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaModelMarker.java new file mode 100644 index 0000000..22cce48 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaModelMarker.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core; + +import net.sourceforge.phpeclipse.PHPCore; + +/** + * Markers used by the Java model. + *

    + * This interface declares constants only; it is not intended to be implemented + * or extended. + *

    + */ +public interface IJavaModelMarker { + + /** + * Java model problem marker type (value "org.eclipse.jdt.core.problem"). + * This can be used to recognize those markers in the workspace that flag problems + * detected by the Java tooling during compilation. + */ + public static final String JAVA_MODEL_PROBLEM_MARKER = PHPCore.PLUGIN_ID + ".problem"; //$NON-NLS-1$ + + + /** + * Java model transient problem marker type (value "org.eclipse.jdt.core.transient_problem"). + * This can be used to recognize those markers in the workspace that flag transient + * problems detected by the Java tooling (such as a problem + * detected by the outliner, or a problem detected during a code completion) + */ + public static final String TRANSIENT_PROBLEM = PHPCore.PLUGIN_ID + ".transient_problem"; //$NON-NLS-1$ + + /** + * Java model task marker type (value "org.eclipse.jdt.core.task"). + * This can be used to recognize task markers in the workspace that correspond to tasks + * specified in Java source comments and detected during compilation (for example, 'TO-DO: ...'). + * Tasks are identified by a task tag, which can be customized through PHPCore + * option "org.eclipse.jdt.core.compiler.taskTag". + * @since 2.1 + */ + public static final String TASK_MARKER = PHPCore.PLUGIN_ID + ".task"; //$NON-NLS-1$ + + + /** + * Id marker attribute (value "arguments"). + * Arguments are concatenated into one String, prefixed with an argument count (followed with colon + * separator) and separated with '#' characters. For example: + * { "foo", "bar" } is encoded as "2:foo#bar", + * { } is encoded as "0: " + * @since 2.0 + */ + public static final String ARGUMENTS = "arguments"; //$NON-NLS-1$ + + /** + * Id marker attribute (value "id"). + */ + public static final String ID = "id"; //$NON-NLS-1$ + + /** + * Flags marker attribute (value "flags"). + * Reserved for future use. + */ + public static final String FLAGS = "flags"; //$NON-NLS-1$ + + /** + * Cycle detected marker attribute (value "cycleDetected"). + * Used only on buildpath problem markers. + * The value of this attribute is either "true" or "false". + */ + public static final String CYCLE_DETECTED = "cycleDetected"; //$NON-NLS-1$ + + /** + * Build path problem marker type (value "org.eclipse.jdt.core.buildpath_problem"). + * This can be used to recognize those markers in the workspace that flag problems + * detected by the Java tooling during classpath setting. + */ + public static final String BUILDPATH_PROBLEM_MARKER = PHPCore.PLUGIN_ID + ".buildpath_problem"; //$NON-NLS-1$ + + /** + * Classpath file format marker attribute (value "classpathFileFormat"). + * Used only on buildpath problem markers. + * The value of this attribute is either "true" or "false". + * + * @since 2.0 + */ + public static final String CLASSPATH_FILE_FORMAT = "classpathFileFormat"; //$NON-NLS-1$ + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaProject.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaProject.java index 612ff56..8bf235a 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaProject.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaProject.java @@ -14,7 +14,12 @@ *******************************************************************************/ package net.sourceforge.phpdt.core; +import java.util.Map; + import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; /** @@ -70,7 +75,7 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * classpath-relative path, or null if no such * IJavaElement is found */ -// IJavaElement findElement(IPath path) throws JavaModelException; + IJavaElement findElement(IPath path) throws JavaModelException; /** * Returns the first existing package fragment on this project's classpath @@ -102,8 +107,8 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * whose path matches the given (absolute) path, or null if * one does not exist */ -// IPackageFragmentRoot findPackageFragmentRoot(IPath path) -// throws JavaModelException; + IPackageFragmentRoot findPackageFragmentRoot(IPath path) + throws JavaModelException; /** * Returns the existing package fragment roots identified by the given entry. * Note that a classpath entry that refers to another project may @@ -122,7 +127,7 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * @see IClasspathContainer * @since 2.1 */ -// IPackageFragmentRoot[] findPackageFragmentRoots(IClasspathEntry entry); + IPackageFragmentRoot[] findPackageFragmentRoots(IClasspathEntry entry); /** * Returns the first type found following this project's classpath * with the given fully qualified name or null if none is found. @@ -182,7 +187,7 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * @exception JavaModelException if this element does not exist or if an * exception occurs while accessing its corresponding resource */ -// IPackageFragmentRoot[] getAllPackageFragmentRoots() throws JavaModelException; + IPackageFragmentRoot[] getAllPackageFragmentRoots() throws JavaModelException; /** * Returns an array of non-Java resources directly contained in this project. @@ -216,7 +221,7 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * @see JavaCore#getDefaultOptions * @since 2.1 */ -// String getOption(String optionName, boolean inheritJavaCoreOptions); + String getOption(String optionName, boolean inheritJavaCoreOptions); /** * Returns the table of the current custom options for this project. Projects remember their custom options, @@ -254,7 +259,7 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * @see #setOutputLocation * @see IClasspathEntry#getOutputLocation */ -// IPath getOutputLocation() throws JavaModelException; + IPath getOutputLocation() throws JavaModelException; /** * Returns a package fragment root for the JAR at the specified file system path. @@ -278,7 +283,7 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * must either be a folder representing the top of a package hierarchy, * or a .jar or .zip file */ -// IPackageFragmentRoot getPackageFragmentRoot(IResource resource); + IPackageFragmentRoot getPackageFragmentRoot(IResource resource); /** * Returns all of the package fragment roots contained in this @@ -293,7 +298,7 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * @exception JavaModelException if this element does not exist or if an * exception occurs while accessing its corresponding resource */ -// IPackageFragmentRoot[] getPackageFragmentRoots() throws JavaModelException; + IPackageFragmentRoot[] getPackageFragmentRoots() throws JavaModelException; /** * Returns the existing package fragment roots identified by the given entry. @@ -313,7 +318,7 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * @see IClasspathContainer * @deprecated Use IJavaProject#findPackageFragmentRoots instead */ -// IPackageFragmentRoot[] getPackageFragmentRoots(IClasspathEntry entry); + IPackageFragmentRoot[] getPackageFragmentRoots(IClasspathEntry entry); /** * Returns all package fragments in all package fragment roots contained @@ -327,7 +332,7 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * @exception JavaModelException if this element does not exist or if an * exception occurs while accessing its corresponding resource */ -// IPackageFragment[] getPackageFragments() throws JavaModelException; + IPackageFragment[] getPackageFragments() throws JavaModelException; /** * Returns the IProject on which this IJavaProject @@ -356,7 +361,7 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * exception occurs while accessing its corresponding resource * @see IClasspathEntry */ -// IClasspathEntry[] getRawClasspath() throws JavaModelException; + IClasspathEntry[] getRawClasspath() throws JavaModelException; /** * Returns the names of the projects that are directly required by this @@ -369,7 +374,7 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * @exception JavaModelException if this element does not exist or if an * exception occurs while accessing its corresponding resource */ -// String[] getRequiredProjectNames() throws JavaModelException; + String[] getRequiredProjectNames() throws JavaModelException; /** * This is a helper method returning the resolved classpath for the project @@ -403,14 +408,14 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * * @see IClasspathEntry */ -// IClasspathEntry[] getResolvedClasspath(boolean ignoreUnresolvedEntry) -// throws JavaModelException; + IClasspathEntry[] getResolvedClasspath(boolean ignoreUnresolvedEntry) + throws JavaModelException; /** * Returns whether this project has been built at least once and thus whether it has a build state. * @return true if this project has been built at least once, false otherwise */ -// boolean hasBuildState(); + boolean hasBuildState(); /** * Returns whether setting this project's classpath to the given classpath entries @@ -422,7 +427,7 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * @param entries the given classpath entries * @return true if the given classpath entries would result in a cycle, false otherwise */ -// boolean hasClasspathCycle(IClasspathEntry[] entries); + boolean hasClasspathCycle(IClasspathEntry[] entries); /** * Returns whether the given element is on the classpath of this project, * that is, referenced from a classpath entry and not explicitly excluded @@ -503,7 +508,7 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * @see JavaCore#getDefaultOptions * @since 2.1 */ -// void setOptions(Map newOptions); + void setOptions(Map newOptions); /** * Sets the default output location of this project to the location @@ -535,8 +540,8 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * @see #getOutputLocation * @see IClasspathEntry#getOutputLocation */ -// void setOutputLocation(IPath path, IProgressMonitor monitor) -// throws JavaModelException; + void setOutputLocation(IPath path, IProgressMonitor monitor) + throws JavaModelException; /** * Sets the classpath of this project using a list of classpath entries. In particular such a classpath may contain @@ -566,8 +571,8 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * * @see IClasspathEntry */ -// void setRawClasspath(IClasspathEntry[] entries, IProgressMonitor monitor) -// throws JavaModelException; + void setRawClasspath(IClasspathEntry[] entries, IProgressMonitor monitor) + throws JavaModelException; /** * Sets the both the classpath of this project and its default output @@ -614,6 +619,6 @@ public interface IJavaProject extends IParent, IJavaElement, IOpenable { * @see IClasspathEntry * @since 2.0 */ -// void setRawClasspath(IClasspathEntry[] entries, IPath outputLocation, IProgressMonitor monitor) -// throws JavaModelException; + void setRawClasspath(IClasspathEntry[] entries, IPath outputLocation, IProgressMonitor monitor) + throws JavaModelException; } \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IMember.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IMember.java index 8494bd8..68446bd 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IMember.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IMember.java @@ -45,7 +45,7 @@ ICompilationUnit getCompilationUnit(); * @return the type in which this member is declared, or null * if this member is not declared in a type (for example, a top-level type) */ -//IType getDeclaringType(); + IType getDeclaringType(); /** * Returns the modifier flags for this member. The flags can be examined using class * Flags. @@ -73,7 +73,7 @@ int getFlags() throws JavaModelException; * (for example, an initializer), or if this member does not have * associated source code (for example, a binary type) */ -//ISourceRange getNameRange() throws JavaModelException; +ISourceRange getNameRange() throws JavaModelException; /** * Returns whether this member is from a class file. * This is a handle-only method. diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IOpenable.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IOpenable.java index 9409305..4df0499 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IOpenable.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IOpenable.java @@ -10,6 +10,8 @@ *******************************************************************************/ package net.sourceforge.phpdt.core; +import org.eclipse.core.runtime.IProgressMonitor; + /** * Common protocol for Java elements that must be opened before they can be @@ -52,7 +54,7 @@ public interface IOpenable { * * @exception JavaModelException if an error occurs closing this element */ -//public void close() throws JavaModelException; +public void close() throws JavaModelException; /** * Returns the buffer opened for this element, or null * if this element does not have a buffer. @@ -82,7 +84,7 @@ public IBuffer getBuffer() throws JavaModelException; * element's children and has not yet destroyed * */ -//boolean hasUnsavedChanges() throws JavaModelException; +boolean hasUnsavedChanges() throws JavaModelException; /** * Returns whether the element is consistent with its underlying resource or buffer. * The element is consistent when opened, and is consistent if the underlying resource @@ -116,7 +118,7 @@ boolean isOpen(); * * @see IOpenable#isConsistent */ -//void makeConsistent(IProgressMonitor progress) throws JavaModelException; +void makeConsistent(IProgressMonitor progress) throws JavaModelException; /** * Opens this element and all parent elements that are not already open. * For compilation units, a buffer is opened on the contents of the underlying resource. @@ -132,7 +134,7 @@ boolean isOpen(); *
  • This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
  • * */ -//public void open(IProgressMonitor progress) throws JavaModelException; +public void open(IProgressMonitor progress) throws JavaModelException; /** * Saves any changes in this element's buffer to its underlying resource * via a workspace resource operation. This has no effect if the element has no underlying @@ -163,5 +165,5 @@ boolean isOpen(); *
  • This Java element is read-only (READ_ONLY)
  • * */ -//public void save(IProgressMonitor progress, boolean force) throws JavaModelException; +public void save(IProgressMonitor progress, boolean force) throws JavaModelException; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageDeclaration.java new file mode 100644 index 0000000..d96737b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageDeclaration.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core; + + +/** + * Represents a package declaration in Java compilation unit. + *

    + * This interface is not intended to be implemented by clients. + *

    + */ +public interface IPackageDeclaration extends IJavaElement, ISourceReference { +/** + * Returns the name of the package the statement refers to. + * This is a handle-only method. + */ +String getElementName(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageFragment.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageFragment.java index 131d36f..2d832d5 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageFragment.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageFragment.java @@ -112,7 +112,7 @@ public interface IPackageFragment extends IParent, IJavaElement, IOpenable { * exception occurs while accessing its corresponding resource. * @return all of the compilation units in this package fragment */ -// ICompilationUnit[] getCompilationUnits() throws JavaModelException; + ICompilationUnit[] getCompilationUnits() throws JavaModelException; /** * Returns the dot-separated package name of this fragment, for example * "java.lang", or "" (the empty string), diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageFragmentRoot.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageFragmentRoot.java index ba8d7ea..9e9fb02 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageFragmentRoot.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageFragmentRoot.java @@ -256,7 +256,7 @@ public interface IPackageFragmentRoot * exception occurs while accessing its corresponding resource. * @return this package fragment root's kind encoded as an integer */ -// int getKind() throws JavaModelException; + int getKind() throws JavaModelException; /** * Returns an array of non-Java resources contained in this package fragment root. diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IParent.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IParent.java index 2a31793..f1571c5 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IParent.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IParent.java @@ -26,7 +26,7 @@ public interface IParent { * exception occurs while accessing its corresponding resource * @return the immediate children of this element */ -//IJavaElement[] getChildren() throws JavaModelException; +IJavaElement[] getChildren() throws JavaModelException; /** * Returns whether this element has one or more immediate children. * This is a convenience method, and may be more efficient than @@ -36,5 +36,5 @@ public interface IParent { * exception occurs while accessing its corresponding resource * @return true if the immediate children of this element, false otherwise */ -//boolean hasChildren() throws JavaModelException; +boolean hasChildren() throws JavaModelException; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ISourceManipulation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ISourceManipulation.java index 2747a52..449f6bb 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ISourceManipulation.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ISourceManipulation.java @@ -47,7 +47,7 @@ public interface ISourceManipulation { * * @exception IllegalArgumentException if container is null */ -void copy(IJavaElement container, IJavaElement sibling, String rename, boolean replace, IProgressMonitor monitor) throws JavaModelException; +//void copy(IJavaElement container, IJavaElement sibling, String rename, boolean replace, IProgressMonitor monitor) throws JavaModelException; /** * Deletes this element, forcing if specified and necessary. * @@ -62,7 +62,7 @@ void copy(IJavaElement container, IJavaElement sibling, String rename, boolean r *
  • This element is read-only (READ_ONLY)
  • * */ -void delete(boolean force, IProgressMonitor monitor) throws JavaModelException; +//void delete(boolean force, IProgressMonitor monitor) throws JavaModelException; /** * Moves this element to the given container. * @@ -90,7 +90,7 @@ void delete(boolean force, IProgressMonitor monitor) throws JavaModelException; * * @exception IllegalArgumentException if container is null */ -void move(IJavaElement container, IJavaElement sibling, String rename, boolean replace, IProgressMonitor monitor) throws JavaModelException; +//void move(IJavaElement container, IJavaElement sibling, String rename, boolean replace, IProgressMonitor monitor) throws JavaModelException; /** * Renames this element to the given name. * @@ -109,5 +109,5 @@ void move(IJavaElement container, IJavaElement sibling, String rename, boolean r *
  • This element is read-only (READ_ONLY) * */ -void rename(String name, boolean replace, IProgressMonitor monitor) throws JavaModelException; +//void rename(String name, boolean replace, IProgressMonitor monitor) throws JavaModelException; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IType.java index 31e4630..9ba334d 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IType.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IType.java @@ -53,16 +53,16 @@ public interface IType extends IMember, IParent { * @param requestor the completion requestor * @since 2.0 */ - void codeComplete( - char[] snippet, - int insertion, - int position, - char[][] localVariableTypeNames, - char[][] localVariableNames, - int[] localVariableModifiers, - boolean isStatic, - ICompletionRequestor requestor) - throws JavaModelException; +// void codeComplete( +// char[] snippet, +// int insertion, +// int position, +// char[][] localVariableTypeNames, +// char[][] localVariableNames, +// int[] localVariableModifiers, +// boolean isStatic, +// ICompletionRequestor requestor) +// throws JavaModelException; /** * Creates and returns a field in this type with the @@ -94,8 +94,8 @@ public interface IType extends IMember, IParent { * * @return a field in this type with the given contents */ - IField createField(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) - throws JavaModelException; +// IField createField(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) +// throws JavaModelException; /** * Creates and returns a static initializer in this type with the @@ -153,8 +153,8 @@ public interface IType extends IMember, IParent { * * @return a method or constructor in this type with the given contents */ - IMethod createMethod(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) - throws JavaModelException; +// IMethod createMethod(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) +// throws JavaModelException; /** * Creates and returns a type in this type with the @@ -186,8 +186,8 @@ public interface IType extends IMember, IParent { * * @return a type in this type with the given contents */ - IType createType(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) - throws JavaModelException; +// IType createType(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) +// throws JavaModelException; /** * Finds the methods in this type that correspond to @@ -585,5 +585,5 @@ public interface IType extends IMember, IParent { * @exception JavaModelException if code resolve could not be performed. * @return the resolved type names or null if unable to find any matching type */ - String[][] resolveType(String typeName) throws JavaModelException; +// String[][] resolveType(String typeName) throws JavaModelException; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IWorkingCopy.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IWorkingCopy.java index d364b32..72f4a48 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IWorkingCopy.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IWorkingCopy.java @@ -160,7 +160,7 @@ public interface IWorkingCopy { * @return the found primary type of this compilation unit, or null if no such a type exists * @since 2.0 */ -// IType findPrimaryType(); + IType findPrimaryType(); /** * Returns a shared working copy on this element using the given factory to create diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/JavaCore.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/JavaCore.java deleted file mode 100644 index 6e8531b..0000000 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/JavaCore.java +++ /dev/null @@ -1,3238 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * IBM Corporation - added the following constants: - * COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE - * COMPILER_PB_STATIC_ACCESS_RECEIVER - * COMPILER_TASK_TAGS - * CORE_CIRCULAR_CLASSPATH - * CORE_INCOMPLETE_CLASSPATH - * IBM Corporation - added run(IWorkspaceRunnable, IProgressMonitor) - * IBM Corporation - added exclusion patterns to source classpath entries - * IBM Corporation - added specific output location to source classpath entries - * IBM Corporation - added the following constants: - * CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER - * CLEAN - * IBM Corporation - added getClasspathContainerInitializer(String) - * IBM Corporation - added the following constants: - * CODEASSIST_ARGUMENT_PREFIXES - * CODEASSIST_ARGUMENT_SUFFIXES - * CODEASSIST_FIELD_PREFIXES - * CODEASSIST_FIELD_SUFFIXES - * CODEASSIST_LOCAL_PREFIXES - * CODEASSIST_LOCAL_SUFFIXES - * CODEASSIST_STATIC_FIELD_PREFIXES - * CODEASSIST_STATIC_FIELD_SUFFIXES - * COMPILER_PB_CHAR_ARRAY_IN_STRING_CONCATENATION - *******************************************************************************/ -package net.sourceforge.phpdt.core; - -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Map; - -import net.sourceforge.phpdt.internal.core.BatchOperation; -import net.sourceforge.phpdt.internal.core.BufferManager; -import net.sourceforge.phpdt.internal.core.JavaModel; -import net.sourceforge.phpdt.internal.core.JavaModelManager; -import net.sourceforge.phpdt.internal.core.Region; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IMarkerDelta; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceChangeEvent; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExecutableExtension; -import org.eclipse.core.runtime.IPluginDescriptor; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Plugin; -import org.eclipse.core.runtime.Preferences; - - -/** - * The plug-in runtime class for the Java model plug-in containing the core - * (UI-free) support for Java projects. - *

    - * Like all plug-in runtime classes (subclasses of Plugin), this - * class is automatically instantiated by the platform when the plug-in gets - * activated. Clients must not attempt to instantiate plug-in runtime classes - * directly. - *

    - *

    - * The single instance of this class can be accessed from any plug-in declaring - * the Java model plug-in as a prerequisite via - * JavaCore.getJavaCore(). The Java model plug-in will be activated - * automatically if not already active. - *

    - */ -public final class JavaCore extends Plugin implements IExecutableExtension { - - private static Plugin JAVA_CORE_PLUGIN = null; - /** - * The plug-in identifier of the Java core support - * (value "org.eclipse.jdt.core"). - */ - public static final String PLUGIN_ID = "org.eclipse.jdt.core" ; //$NON-NLS-1$ - - /** - * The identifier for the Java builder - * (value "org.eclipse.jdt.core.javabuilder"). - */ - public static final String BUILDER_ID = PLUGIN_ID + ".javabuilder" ; //$NON-NLS-1$ - - /** - * The identifier for the Java model - * (value "org.eclipse.jdt.core.javamodel"). - */ - public static final String MODEL_ID = PLUGIN_ID + ".javamodel" ; //$NON-NLS-1$ - - /** - * The identifier for the Java nature - * (value "org.eclipse.jdt.core.javanature"). - * The presence of this nature on a project indicates that it is - * Java-capable. - * - * @see org.eclipse.core.resources.IProject#hasNature(java.lang.String) - */ - public static final String NATURE_ID = PLUGIN_ID + ".javanature" ; //$NON-NLS-1$ - - /** - * Name of the handle id attribute in a Java marker. - */ - protected static final String ATT_HANDLE_ID = - "org.eclipse.jdt.internal.core.JavaModelManager.handleId" ; //$NON-NLS-1$ - - // *************** Possible IDs for configurable options. ******************** - - /** - * Possible configurable option ID. - * @see #getDefaultOptions() - */ - public static final String COMPILER_LOCAL_VARIABLE_ATTR = PLUGIN_ID + ".compiler.debug.localVariable"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions() - */ - public static final String COMPILER_LINE_NUMBER_ATTR = PLUGIN_ID + ".compiler.debug.lineNumber"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - */ - public static final String COMPILER_SOURCE_FILE_ATTR = PLUGIN_ID + ".compiler.debug.sourceFile"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - */ - public static final String COMPILER_CODEGEN_UNUSED_LOCAL = PLUGIN_ID + ".compiler.codegen.unusedLocal"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - */ - public static final String COMPILER_CODEGEN_TARGET_PLATFORM = PLUGIN_ID + ".compiler.codegen.targetPlatform"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - */ - public static final String COMPILER_PB_UNREACHABLE_CODE = PLUGIN_ID + ".compiler.problem.unreachableCode"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - */ - public static final String COMPILER_PB_INVALID_IMPORT = PLUGIN_ID + ".compiler.problem.invalidImport"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - */ - public static final String COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD = PLUGIN_ID + ".compiler.problem.overridingPackageDefaultMethod"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - */ - public static final String COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME = PLUGIN_ID + ".compiler.problem.methodWithConstructorName"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - */ - public static final String COMPILER_PB_DEPRECATION = PLUGIN_ID + ".compiler.problem.deprecation"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE = PLUGIN_ID + ".compiler.problem.deprecationInDeprecatedCode"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - */ - public static final String COMPILER_PB_HIDDEN_CATCH_BLOCK = PLUGIN_ID + ".compiler.problem.hiddenCatchBlock"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - */ - public static final String COMPILER_PB_UNUSED_LOCAL = PLUGIN_ID + ".compiler.problem.unusedLocal"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - */ - public static final String COMPILER_PB_UNUSED_PARAMETER = PLUGIN_ID + ".compiler.problem.unusedParameter"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String COMPILER_PB_UNUSED_PARAMETER_WHEN_IMPLEMENTING_ABSTRACT = PLUGIN_ID + ".compiler.problem.unusedParameterWhenImplementingAbstract"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String COMPILER_PB_UNUSED_PARAMETER_WHEN_OVERRIDING_CONCRETE = PLUGIN_ID + ".compiler.problem.unusedParameterWhenOverridingConcrete"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String COMPILER_PB_UNUSED_IMPORT = PLUGIN_ID + ".compiler.problem.unusedImport"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - */ - public static final String COMPILER_PB_SYNTHETIC_ACCESS_EMULATION = PLUGIN_ID + ".compiler.problem.syntheticAccessEmulation"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String COMPILER_PB_NON_NLS_STRING_LITERAL = PLUGIN_ID + ".compiler.problem.nonExternalizedStringLiteral"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String COMPILER_PB_ASSERT_IDENTIFIER = PLUGIN_ID + ".compiler.problem.assertIdentifier"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String COMPILER_PB_STATIC_ACCESS_RECEIVER = PLUGIN_ID + ".compiler.problem.staticAccessReceiver"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String COMPILER_PB_NO_EFFECT_ASSIGNMENT = PLUGIN_ID + ".compiler.problem.noEffectAssignment"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String COMPILER_PB_INCOMPATIBLE_NON_INHERITED_INTERFACE_METHOD = PLUGIN_ID + ".compiler.problem.incompatibleNonInheritedInterfaceMethod"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String COMPILER_PB_UNUSED_PRIVATE_MEMBER = PLUGIN_ID + ".compiler.problem.unusedPrivateMember"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String COMPILER_PB_CHAR_ARRAY_IN_STRING_CONCATENATION = PLUGIN_ID + ".compiler.problem.noImplicitStringConversion"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String COMPILER_PB_MAX_PER_UNIT = PLUGIN_ID + ".compiler.maxProblemPerUnit"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String COMPILER_SOURCE = PLUGIN_ID + ".compiler.source"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String COMPILER_COMPLIANCE = PLUGIN_ID + ".compiler.compliance"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String COMPILER_TASK_PRIORITIES = PLUGIN_ID + ".compiler.taskPriorities"; //$NON-NLS-1$ - /** - * Possible configurable option value for COMPILER_TASK_PRIORITIES. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String COMPILER_TASK_PRIORITY_HIGH = "HIGH"; //$NON-NLS-1$ - /** - * Possible configurable option value for COMPILER_TASK_PRIORITIES. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String COMPILER_TASK_PRIORITY_LOW = "LOW"; //$NON-NLS-1$ - /** - * Possible configurable option value for COMPILER_TASK_PRIORITIES. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String COMPILER_TASK_PRIORITY_NORMAL = "NORMAL"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String COMPILER_TASK_TAGS = PLUGIN_ID + ".compiler.taskTags"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - */ - public static final String CORE_JAVA_BUILD_ORDER = PLUGIN_ID + ".computeJavaBuildOrder"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String CORE_JAVA_BUILD_RESOURCE_COPY_FILTER = PLUGIN_ID + ".builder.resourceCopyExclusionFilter"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CORE_JAVA_BUILD_DUPLICATE_RESOURCE = PLUGIN_ID + ".builder.duplicateResourceTask"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER = PLUGIN_ID + ".builder.cleanOutputFolder"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CORE_INCOMPLETE_CLASSPATH = PLUGIN_ID + ".incompleteClasspath"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CORE_CIRCULAR_CLASSPATH = PLUGIN_ID + ".circularClasspath"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String CORE_JAVA_BUILD_INVALID_CLASSPATH = PLUGIN_ID + ".builder.invalidClasspath"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String CORE_ENCODING = PLUGIN_ID + ".encoding"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS = PLUGIN_ID + ".classpath.exclusionPatterns"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS = PLUGIN_ID + ".classpath.multipleOutputLocations"; //$NON-NLS-1$ - /** - * Default task tag - * @since 2.1 - */ - public static final String DEFAULT_TASK_TAG = "TODO"; //$NON-NLS-1$ - /** - * Default task priority - * @since 2.1 - */ - public static final String DEFAULT_TASK_PRIORITY = "NORMAL"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String FORMATTER_NEWLINE_OPENING_BRACE = PLUGIN_ID + ".formatter.newline.openingBrace"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String FORMATTER_NEWLINE_CONTROL = PLUGIN_ID + ".formatter.newline.controlStatement"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String FORMATTER_NEWLINE_ELSE_IF = PLUGIN_ID + ".formatter.newline.elseIf"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String FORMATTER_NEWLINE_EMPTY_BLOCK = PLUGIN_ID + ".formatter.newline.emptyBlock"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String FORMATTER_CLEAR_BLANK_LINES = PLUGIN_ID + ".formatter.newline.clearAll"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String FORMATTER_LINE_SPLIT = PLUGIN_ID + ".formatter.lineSplit"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String FORMATTER_COMPACT_ASSIGNMENT = PLUGIN_ID + ".formatter.style.assignment"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String FORMATTER_TAB_CHAR = PLUGIN_ID + ".formatter.tabulation.char"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String FORMATTER_TAB_SIZE = PLUGIN_ID + ".formatter.tabulation.size"; //$NON-NLS-1$ - /** - * Possible configurable option ID - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String FORMATTER_SPACE_CASTEXPRESSION = PLUGIN_ID + ".formatter.space.castexpression"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String CODEASSIST_VISIBILITY_CHECK = PLUGIN_ID + ".codeComplete.visibilityCheck"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String CODEASSIST_IMPLICIT_QUALIFICATION = PLUGIN_ID + ".codeComplete.forceImplicitQualification"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CODEASSIST_FIELD_PREFIXES = PLUGIN_ID + ".codeComplete.fieldPrefixes"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CODEASSIST_STATIC_FIELD_PREFIXES = PLUGIN_ID + ".codeComplete.staticFieldPrefixes"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CODEASSIST_LOCAL_PREFIXES = PLUGIN_ID + ".codeComplete.localPrefixes"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CODEASSIST_ARGUMENT_PREFIXES = PLUGIN_ID + ".codeComplete.argumentPrefixes"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CODEASSIST_FIELD_SUFFIXES = PLUGIN_ID + ".codeComplete.fieldSuffixes"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CODEASSIST_STATIC_FIELD_SUFFIXES = PLUGIN_ID + ".codeComplete.staticFieldSuffixes"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CODEASSIST_LOCAL_SUFFIXES = PLUGIN_ID + ".codeComplete.localSuffixes"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CODEASSIST_ARGUMENT_SUFFIXES = PLUGIN_ID + ".codeComplete.argumentSuffixes"; //$NON-NLS-1$ - - // *************** Possible values for configurable options. ******************** - - /** - * Possible configurable option value. - * @see #getDefaultOptions - */ - public static final String GENERATE = "generate"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - */ - public static final String DO_NOT_GENERATE = "do not generate"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - */ - public static final String PRESERVE = "preserve"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - */ - public static final String OPTIMIZE_OUT = "optimize out"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - */ - public static final String VERSION_1_1 = "1.1"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - */ - public static final String VERSION_1_2 = "1.2"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String VERSION_1_3 = "1.3"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String VERSION_1_4 = "1.4"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String ABORT = "abort"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - */ - public static final String ERROR = "error"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - */ - public static final String WARNING = "warning"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - */ - public static final String IGNORE = "ignore"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - */ - public static final String COMPUTE = "compute"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String INSERT = "insert"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String DO_NOT_INSERT = "do not insert"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String PRESERVE_ONE = "preserve one"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String CLEAR_ALL = "clear all"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String NORMAL = "normal"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String COMPACT = "compact"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String TAB = "tab"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String SPACE = "space"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String ENABLED = "enabled"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - * @since 2.0 - */ - public static final String DISABLED = "disabled"; //$NON-NLS-1$ - /** - * Possible configurable option value. - * @see #getDefaultOptions - * @since 2.1 - */ - public static final String CLEAN = "clean"; //$NON-NLS-1$ - - /** - * Creates the Java core plug-in. - * @since 2.1 - */ - public JavaCore(IPluginDescriptor pluginDescriptor) { - super(pluginDescriptor); - JAVA_CORE_PLUGIN = this; - } - - /** - * Adds the given listener for changes to Java elements. - * Has no effect if an identical listener is already registered. - * - * This listener will only be notified during the POST_CHANGE resource change notification - * and any reconcile operation (POST_RECONCILE). - * For finer control of the notification, use addElementChangedListener(IElementChangedListener,int), - * which allows to specify a different eventMask. - * - * @see ElementChangedEvent - * @param listener the listener - */ - public static void addElementChangedListener(IElementChangedListener listener) { - addElementChangedListener(listener, ElementChangedEvent.POST_CHANGE | ElementChangedEvent.POST_RECONCILE); - } - - /** - * Adds the given listener for changes to Java elements. - * Has no effect if an identical listener is already registered. - * After completion of this method, the given listener will be registered for exactly - * the specified events. If they were previously registered for other events, they - * will be deregistered. - *

    - * Once registered, a listener starts receiving notification of changes to - * java elements in the model. The listener continues to receive - * notifications until it is replaced or removed. - *

    - *

    - * Listeners can listen for several types of event as defined in ElementChangeEvent. - * Clients are free to register for any number of event types however if they register - * for more than one, it is their responsibility to ensure they correctly handle the - * case where the same java element change shows up in multiple notifications. - * Clients are guaranteed to receive only the events for which they are registered. - *

    - * - * @param listener the listener - * @param eventMask the bit-wise OR of all event types of interest to the listener - * @see IElementChangedListener - * @see ElementChangedEvent - * @see #removeElementChangedListener(IElementChangedListener) - * @since 2.0 - */ - public static void addElementChangedListener(IElementChangedListener listener, int eventMask) { - JavaModelManager.getJavaModelManager().addElementChangedListener(listener, eventMask); - } - - /** - * Configures the given marker attribute map for the given Java element. - * Used for markers, which denote a Java element rather than a resource. - * - * @param attributes the mutable marker attribute map (key type: String, - * value type: String) - * @param element the Java element for which the marker needs to be configured - */ - public static void addJavaElementMarkerAttributes( - Map attributes, - IJavaElement element) { -// if (element instanceof IMember) -// element = ((IMember) element).getClassFile(); - if (attributes != null && element != null) - attributes.put(ATT_HANDLE_ID, element.getHandleIdentifier()); - } - - /** - * Configures the given marker for the given Java element. - * Used for markers, which denote a Java element rather than a resource. - * - * @param marker the marker to be configured - * @param element the Java element for which the marker needs to be configured - * @exception CoreException if the IMarker.setAttribute on the marker fails - */ - public void configureJavaElementMarker(IMarker marker, IJavaElement element) - throws CoreException { -// if (element instanceof IMember) -// element = ((IMember) element).getClassFile(); - if (marker != null && element != null) - marker.setAttribute(ATT_HANDLE_ID, element.getHandleIdentifier()); - } - - /** - * Returns the Java model element corresponding to the given handle identifier - * generated by IJavaElement.getHandleIdentifier(), or - * null if unable to create the associated element. - */ - public static IJavaElement create(String handleIdentifier) { - if (handleIdentifier == null) { - return null; - } - try { - return JavaModelManager.getJavaModelManager().getHandleFromMemento(handleIdentifier); - } catch (JavaModelException e) { - return null; - } - } - /** - * Returns the Java element corresponding to the given file, or - * null if unable to associate the given file - * with a Java element. - * - *

    The file must be one of:

      - *
    • a .java file - the element returned is the corresponding ICompilationUnit
    • - *
    • a .class file - the element returned is the corresponding IClassFile
    • - *
    • a .jar file - the element returned is the corresponding IPackageFragmentRoot
    • - *
    - *

    - * Creating a Java element has the side effect of creating and opening all of the - * element's parents if they are not yet open. - * - * @param the given file - * @return the Java element corresponding to the given file, or - * null if unable to associate the given file - * with a Java element - */ - public static IJavaElement create(IFile file) { - return JavaModelManager.create(file, null); - } - /** - * Returns the package fragment or package fragment root corresponding to the given folder, or - * null if unable to associate the given folder with a Java element. - *

    - * Note that a package fragment root is returned rather than a default package. - *

    - * Creating a Java element has the side effect of creating and opening all of the - * element's parents if they are not yet open. - * - * @param the given folder - * @return the package fragment or package fragment root corresponding to the given folder, or - * null if unable to associate the given folder with a Java element - */ - public static IJavaElement create(IFolder folder) { - return JavaModelManager.create(folder, null); - } - /** - * Returns the Java project corresponding to the given project. - *

    - * Creating a Java Project has the side effect of creating and opening all of the - * project's parents if they are not yet open. - *

    - * Note that no check is done at this time on the existence or the java nature of this project. - * - * @param project the given project - * @return the Java project corresponding to the given project, null if the given project is null - */ - public static IJavaProject create(IProject project) { - if (project == null) { - return null; - } - JavaModel javaModel = JavaModelManager.getJavaModelManager().getJavaModel(); - return javaModel.getJavaProject(project); - } - /** - * Returns the Java element corresponding to the given resource, or - * null if unable to associate the given resource - * with a Java element. - *

    - * The resource must be one of:

      - *
    • a project - the element returned is the corresponding IJavaProject
    • - *
    • a .java file - the element returned is the corresponding ICompilationUnit
    • - *
    • a .class file - the element returned is the corresponding IClassFile
    • - *
    • a .jar file - the element returned is the corresponding IPackageFragmentRoot
    • - *
    • a folder - the element returned is the corresponding IPackageFragmentRoot - * or IPackageFragment
    • - *
    • the workspace root resource - the element returned is the IJavaModel
    • - *
    - *

    - * Creating a Java element has the side effect of creating and opening all of the - * element's parents if they are not yet open. - * - * @param resource the given resource - * @return the Java element corresponding to the given resource, or - * null if unable to associate the given resource - * with a Java element - */ - public static IJavaElement create(IResource resource) { - return JavaModelManager.create(resource, null); - } - /** - * Returns the Java model. - * - * @param root the given root - * @return the Java model, or null if the root is null - */ - public static IJavaModel create(IWorkspaceRoot root) { - if (root == null) { - return null; - } - return JavaModelManager.getJavaModelManager().getJavaModel(); - } - /** - * Creates and returns a class file element for - * the given .class file. Returns null if unable - * to recognize the class file. - * - * @param file the given .class file - * @return a class file element for the given .class file, or null if unable - * to recognize the class file - */ -// public static IClassFile createClassFileFrom(IFile file) { -// return JavaModelManager.createClassFileFrom(file, null); -// } - /** - * Creates and returns a compilation unit element for - * the given .java file. Returns null if unable - * to recognize the compilation unit. - * - * @param file the given .java file - * @return a compilation unit element for the given .java file, or null if unable - * to recognize the compilation unit - */ - public static ICompilationUnit createCompilationUnitFrom(IFile file) { - return JavaModelManager.createCompilationUnitFrom(file, null); - } - /** - * Creates and returns a handle for the given JAR file. - * The Java model associated with the JAR's project may be - * created as a side effect. - * - * @param file the given JAR file - * @return a handle for the given JAR file, or null if unable to create a JAR package fragment root. - * (for example, if the JAR file represents a non-Java resource) - */ -// public static IPackageFragmentRoot createJarPackageFragmentRootFrom(IFile file) { -// return JavaModelManager.createJarPackageFragmentRootFrom(file, null); -// } - - /** - * Answers the project specific value for a given classpath container. - * In case this container path could not be resolved, then will answer null. - * Both the container path and the project context are supposed to be non-null. - *

    - * The containerPath is a formed by a first ID segment followed with extra segments, which can be - * used as additional hints for resolution. If no container was ever recorded for this container path - * onto this project (using setClasspathContainer, then a - * ClasspathContainerInitializer will be activated if any was registered for this container - * ID onto the extension point "org.eclipse.jdt.core.classpathContainerInitializer". - *

    - * There is no assumption that the returned container must answer the exact same containerPath - * when requested IClasspathContainer#getPath. - * Indeed, the containerPath is just an indication for resolving it to an actual container object. - *

    - * Classpath container values are persisted locally to the workspace, but - * are not preserved from a session to another. It is thus highly recommended to register a - * ClasspathContainerInitializer for each referenced container - * (through the extension point "org.eclipse.jdt.core.ClasspathContainerInitializer"). - *

    - * @param containerPath the name of the container, which needs to be resolved - * @param project a specific project in which the container is being resolved - * @return the corresponding classpath container or null if unable to find one. - * - * @exception JavaModelException if an exception occurred while resolving the container, or if the resolved container - * contains illegal entries (contains CPE_CONTAINER entries or null entries). - * - * @see ClasspathContainerInitializer - * @see IClasspathContainer - * @see #setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], IProgressMonitor) - * @since 2.0 - */ -// public static IClasspathContainer getClasspathContainer(final IPath containerPath, final IJavaProject project) throws JavaModelException { -// -// IClasspathContainer container = JavaModelManager.containerGet(project, containerPath); -// if (container == JavaModelManager.ContainerInitializationInProgress) return null; // break cycle -// -// if (container == null){ -// final ClasspathContainerInitializer initializer = JavaCore.getClasspathContainerInitializer(containerPath.segment(0)); -// if (initializer != null){ -// if (JavaModelManager.CP_RESOLVE_VERBOSE){ -// System.out.println("CPContainer INIT - triggering initialization of: ["+project.getElementName()+"] " + containerPath + " using initializer: "+ initializer); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ -// new Exception("FAKE exception for dumping current CPContainer (["+project.getElementName()+"] "+ containerPath+ ")INIT invocation stack trace").printStackTrace(); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ -// } -// JavaModelManager.containerPut(project, containerPath, JavaModelManager.ContainerInitializationInProgress); // avoid initialization cycles -// boolean ok = false; -// try { -// // wrap initializer call with Safe runnable in case initializer would be causing some grief -// Platform.run(new ISafeRunnable() { -// public void handleException(Throwable exception) { -// Util.log(exception, "Exception occurred in classpath container initializer: "+initializer); //$NON-NLS-1$ -// } -// public void run() throws Exception { -// initializer.initialize(containerPath, project); -// } -// }); -// -// // retrieve value (if initialization was successful) -// container = JavaModelManager.containerGet(project, containerPath); -// if (container == JavaModelManager.ContainerInitializationInProgress) return null; // break cycle -// ok = true; -// } finally { -// if (!ok) JavaModelManager.containerPut(project, containerPath, null); // flush cache -// } -// if (JavaModelManager.CP_RESOLVE_VERBOSE){ -// System.out.print("CPContainer INIT - after resolution: ["+project.getElementName()+"] " + containerPath + " --> "); //$NON-NLS-2$//$NON-NLS-1$//$NON-NLS-3$ -// if (container != null){ -// System.out.print("container: "+container.getDescription()+" {"); //$NON-NLS-2$//$NON-NLS-1$ -// IClasspathEntry[] entries = container.getClasspathEntries(); -// if (entries != null){ -// for (int i = 0; i < entries.length; i++){ -// if (i > 0) System.out.println(", ");//$NON-NLS-1$ -// System.out.println(entries[i]); -// } -// } -// System.out.println("}");//$NON-NLS-1$ -// } else { -// System.out.println("{unbound}");//$NON-NLS-1$ -// } -// } -// } else { -// if (JavaModelManager.CP_RESOLVE_VERBOSE){ -// System.out.println("CPContainer INIT - no initializer found for: "+project.getElementName()+"] " + containerPath); //$NON-NLS-1$ //$NON-NLS-2$ -// } -// } -// } -// return container; -// } - - /** - * Helper method finding the classpath container initializer registered for a given classpath container ID - * or null if none was found while iterating over the contributions to extension point to - * the extension point "org.eclipse.jdt.core.classpathContainerInitializer". - *

    - * A containerID is the first segment of any container path, used to identify the registered container initializer. - *

    - * @param String - a containerID identifying a registered initializer - * @return ClasspathContainerInitializer - the registered classpath container initializer or null if - * none was found. - * @since 2.1 - */ -// public static ClasspathContainerInitializer getClasspathContainerInitializer(String containerID){ -// -// Plugin jdtCorePlugin = JavaCore.getPlugin(); -// if (jdtCorePlugin == null) return null; -// -// IExtensionPoint extension = jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.CPCONTAINER_INITIALIZER_EXTPOINT_ID); -// if (extension != null) { -// IExtension[] extensions = extension.getExtensions(); -// for(int i = 0; i < extensions.length; i++){ -// IConfigurationElement [] configElements = extensions[i].getConfigurationElements(); -// for(int j = 0; j < configElements.length; j++){ -// String initializerID = configElements[j].getAttribute("id"); //$NON-NLS-1$ -// if (initializerID != null && initializerID.equals(containerID)){ -// if (JavaModelManager.CP_RESOLVE_VERBOSE) { -// System.out.println("CPContainer INIT - found initializer: "+containerID +" --> " + configElements[j].getAttribute("class"));//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$ -// } -// try { -// Object execExt = configElements[j].createExecutableExtension("class"); //$NON-NLS-1$ -// if (execExt instanceof ClasspathContainerInitializer){ -// return (ClasspathContainerInitializer)execExt; -// } -// } catch(CoreException e) { -// } -// } -// } -// } -// } -// return null; -// } - - /** - * Returns the path held in the given classpath variable. - * Returns null if unable to bind. - *

    - * Classpath variable values are persisted locally to the workspace, and - * are preserved from session to session. - *

    - * Note that classpath variables can be contributed registered initializers for, - * using the extension point "org.eclipse.jdt.core.classpathVariableInitializer". - * If an initializer is registered for a variable, its persisted value will be ignored: - * its initializer will thus get the opportunity to rebind the variable differently on - * each session. - * - * @param variableName the name of the classpath variable - * @return the path, or null if none - * @see #setClasspathVariable - */ -// public static IPath getClasspathVariable(final String variableName) { -// -// IPath variablePath = JavaModelManager.variableGet(variableName); -// if (variablePath == JavaModelManager.VariableInitializationInProgress) return null; // break cycle -// -// if (variablePath != null) { -// return variablePath; -// } -// -// // even if persisted value exists, initializer is given priority, only if no initializer is found the persisted value is reused -// final ClasspathVariableInitializer initializer = JavaCore.getClasspathVariableInitializer(variableName); -// if (initializer != null){ -// if (JavaModelManager.CP_RESOLVE_VERBOSE){ -// System.out.println("CPVariable INIT - triggering initialization of: " + variableName+ " using initializer: "+ initializer); //$NON-NLS-1$ //$NON-NLS-2$ -// new Exception("FAKE exception for dumping current CPVariable ("+variableName+ ")INIT invocation stack trace").printStackTrace(); //$NON-NLS-1$//$NON-NLS-2$ -// } -// JavaModelManager.variablePut(variableName, JavaModelManager.VariableInitializationInProgress); // avoid initialization cycles -// boolean ok = false; -// try { -// // wrap initializer call with Safe runnable in case initializer would be causing some grief -// Platform.run(new ISafeRunnable() { -// public void handleException(Throwable exception) { -// Util.log(exception, "Exception occurred in classpath variable initializer: "+initializer+" while initializing variable: "+variableName); //$NON-NLS-1$ //$NON-NLS-2$ -// } -// public void run() throws Exception { -// initializer.initialize(variableName); -// } -// }); -// variablePath = (IPath) JavaModelManager.variableGet(variableName); // initializer should have performed side-effect -// if (variablePath == JavaModelManager.VariableInitializationInProgress) return null; // break cycle (initializer did not init or reentering call) -// if (JavaModelManager.CP_RESOLVE_VERBOSE){ -// System.out.println("CPVariable INIT - after initialization: " + variableName + " --> " + variablePath); //$NON-NLS-2$//$NON-NLS-1$ -// } -// ok = true; -// } finally { -// if (!ok) JavaModelManager.variablePut(variableName, null); // flush cache -// } -// } else { -// if (JavaModelManager.CP_RESOLVE_VERBOSE){ -// System.out.println("CPVariable INIT - no initializer found for: " + variableName); //$NON-NLS-1$ -// } -// } -// return variablePath; -// } - - /** - * Helper method finding the classpath variable initializer registered for a given classpath variable name - * or null if none was found while iterating over the contributions to extension point to - * the extension point "org.eclipse.jdt.core.classpathVariableInitializer". - *

    - * @param the given variable - * @return ClasspathVariableInitializer - the registered classpath variable initializer or null if - * none was found. - * @since 2.1 - */ -// public static ClasspathVariableInitializer getClasspathVariableInitializer(String variable){ -// -// Plugin jdtCorePlugin = JavaCore.getPlugin(); -// if (jdtCorePlugin == null) return null; -// -// IExtensionPoint extension = jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.CPVARIABLE_INITIALIZER_EXTPOINT_ID); -// if (extension != null) { -// IExtension[] extensions = extension.getExtensions(); -// for(int i = 0; i < extensions.length; i++){ -// IConfigurationElement [] configElements = extensions[i].getConfigurationElements(); -// for(int j = 0; j < configElements.length; j++){ -// try { -// String varAttribute = configElements[j].getAttribute("variable"); //$NON-NLS-1$ -// if (variable.equals(varAttribute)) { -// if (JavaModelManager.CP_RESOLVE_VERBOSE) { -// System.out.println("CPVariable INIT - found initializer: "+variable+" --> " + configElements[j].getAttribute("class"));//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$ -// } -// Object execExt = configElements[j].createExecutableExtension("class"); //$NON-NLS-1$ -// if (execExt instanceof ClasspathVariableInitializer){ -// return (ClasspathVariableInitializer)execExt; -// } -// } -// } catch(CoreException e){ -// } -// } -// } -// } -// return null; -// } - - /** - * Returns the names of all known classpath variables. - *

    - * Classpath variable values are persisted locally to the workspace, and - * are preserved from session to session. - *

    - * - * @return the list of classpath variable names - * @see #setClasspathVariable - */ -// public static String[] getClasspathVariableNames() { -// return JavaModelManager.variableNames(); -// } - - /** - * Returns a table of all known configurable options with their default values. - * These options allow to configure the behaviour of the underlying components. - * The client may safely use the result as a template that they can modify and - * then pass to setOptions. - * - * Helper constants have been defined on JavaCore for each of the option ID and - * their possible constant values. - * - * Note: more options might be added in further releases. - *

    -	 * RECOGNIZED OPTIONS:
    -	 * COMPILER / Generating Local Variable Debug Attribute
    - 	 *    When generated, this attribute will enable local variable names 
    -	 *    to be displayed in debugger, only in place where variables are 
    -	 *    definitely assigned (.class file is then bigger)
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.debug.localVariable"
    -	 *     - possible values:   { "generate", "do not generate" }
    -	 *     - default:           "generate"
    -	 *
    -	 * COMPILER / Generating Line Number Debug Attribute 
    -	 *    When generated, this attribute will enable source code highlighting in debugger 
    -	 *    (.class file is then bigger).
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.debug.lineNumber"
    -	 *     - possible values:   { "generate", "do not generate" }
    -	 *     - default:           "generate"
    -	 *    
    -	 * COMPILER / Generating Source Debug Attribute 
    -	 *    When generated, this attribute will enable the debugger to present the 
    -	 *    corresponding source code.
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.debug.sourceFile"
    -	 *     - possible values:   { "generate", "do not generate" }
    -	 *     - default:           "generate"
    -	 *    
    -	 * COMPILER / Preserving Unused Local Variables
    -	 *    Unless requested to preserve unused local variables (that is, never read), the 
    -	 *    compiler will optimize them out, potentially altering debugging
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.codegen.unusedLocal"
    -	 *     - possible values:   { "preserve", "optimize out" }
    -	 *     - default:           "preserve"
    -	 * 
    -	 * COMPILER / Defining Target Java Platform
    -	 *    For binary compatibility reason, .class files can be tagged to with certain VM versions and later.
    -	 *    Note that "1.4" target require to toggle compliance mode to "1.4" too.
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.codegen.targetPlatform"
    -	 *     - possible values:   { "1.1", "1.2", "1.3", "1.4" }
    -	 *     - default:           "1.1"
    -	 *
    -	 * COMPILER / Reporting Unreachable Code
    -	 *    Unreachable code can optionally be reported as an error, warning or simply 
    -	 *    ignored. The bytecode generation will always optimized it out.
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.unreachableCode"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "error"
    -	 *
    -	 * COMPILER / Reporting Invalid Import
    -	 *    An import statement that cannot be resolved might optionally be reported 
    -	 *    as an error, as a warning or ignored.
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.invalidImport"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "error"
    -	 *
    -	 * COMPILER / Reporting Attempt to Override Package-Default Method
    -	 *    A package default method is not visible in a different package, and thus 
    -	 *    cannot be overridden. When enabling this option, the compiler will signal 
    -	 *    such scenarii either as an error or a warning.
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "warning"
    -	 *
    -	 * COMPILER / Reporting Method With Constructor Name
    -	 *    Naming a method with a constructor name is generally considered poor 
    -	 *    style programming. When enabling this option, the compiler will signal such 
    -	 *    scenarii either as an error or a warning.
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.methodWithConstructorName"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "warning"
    -	 *
    -	 * COMPILER / Reporting Deprecation
    -	 *    When enabled, the compiler will signal use of deprecated API either as an 
    -	 *    error or a warning.
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.deprecation"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "warning"
    -	 *
    -	 * COMPILER / Reporting Deprecation Inside Deprecated Code
    -	 *    When enabled, the compiler will signal use of deprecated API inside deprecated code.
    -	 *    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.deprecation".
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode"
    -	 *     - possible values:   { "enabled", "disabled" }
    -	 *     - default:           "disabled"
    -	 *
    -	 * COMPILER / Reporting Hidden Catch Block
    -	 *    Locally to a try statement, some catch blocks may hide others . For example,
    -	 *      try {  throw new java.io.CharConversionException();
    -	 *      } catch (java.io.CharConversionException e) {
    -	 *      } catch (java.io.IOException e) {}. 
    -	 *    When enabling this option, the compiler will issue an error or a warning for hidden 
    -	 *    catch blocks corresponding to checked exceptions
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "warning"
    -	 *
    -	 * COMPILER / Reporting Unused Local
    -	 *    When enabled, the compiler will issue an error or a warning for unused local 
    -	 *    variables (that is, variables never read from)
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedLocal"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "ignore"
    -	 *
    -	 * COMPILER / Reporting Unused Parameter
    -	 *    When enabled, the compiler will issue an error or a warning for unused method 
    -	 *    parameters (that is, parameters never read from)
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedParameter"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "ignore"
    -	 *
    -	 * COMPILER / Reporting Unused Parameter if Implementing Abstract Method
    -	 *    When enabled, the compiler will signal unused parameters in abstract method implementations.
    -	 *    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.unusedParameter".
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract"
    -	 *     - possible values:   { "enabled", "disabled" }
    -	 *     - default:           "disabled"
    -	 *
    -	 * COMPILER / Reporting Unused Parameter if Overriding Concrete Method
    -	 *    When enabled, the compiler will signal unused parameters in methods overriding concrete ones.
    -	 *    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.unusedParameter".
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete"
    -	 *     - possible values:   { "enabled", "disabled" }
    -	 *     - default:           "disabled"
    -	 *
    -	 * COMPILER / Reporting Unused Import
    -	 *    When enabled, the compiler will issue an error or a warning for unused import 
    -	 *    reference 
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedImport"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "warning"
    -	 *
    -	 * COMPILER / Reporting Unused Private Members
    -	 *    When enabled, the compiler will issue an error or a warning whenever a private 
    -	 *    method or field is declared but never used within the same unit.
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedPrivateMember"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "ignore"
    -	 *
    -	 * COMPILER / Reporting Synthetic Access Emulation
    -	 *    When enabled, the compiler will issue an error or a warning whenever it emulates 
    -	 *    access to a non-accessible member of an enclosing type. Such access can have
    -	 *    performance implications.
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "ignore"
    -	 *
    -	 * COMPILER / Reporting Non-Externalized String Literal
    -	 *    When enabled, the compiler will issue an error or a warning for non externalized 
    -	 *    String literal (that is, not tagged with //$NON-NLS-$). 
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "ignore"
    -	 * 
    -	 * COMPILER / Reporting Usage of 'assert' Identifier
    -	 *    When enabled, the compiler will issue an error or a warning whenever 'assert' is 
    -	 *    used as an identifier (reserved keyword in 1.4)
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.assertIdentifier"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "ignore"
    -	 * 
    -	 * COMPILER / Reporting Non-Static Reference to a Static Member
    -	 *    When enabled, the compiler will issue an error or a warning whenever a static field
    -	 *    or method is accessed with an expression receiver. A reference to a static member should
    -	 *    be qualified with a type name.
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.staticAccessReceiver"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "warning"
    -	 * 
    -	 * COMPILER / Reporting Assignment with no Effect
    -	 *    When enabled, the compiler will issue an error or a warning whenever an assignment
    -	 *    has no effect (e.g 'x = x').
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.noEffectAssignment"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "warning"
    -	 * 
    -	 * COMPILER / Reporting Interface Method not Compatible with non-Inherited Methods
    -	 *    When enabled, the compiler will issue an error or a warning whenever an interface
    -	 *    defines a method incompatible with a non-inherited Object method. Until this conflict
    -	 *    is resolved, such an interface cannot be implemented, For example, 
    -	 *      interface I { 
    -	 *         int clone();
    -	 *      } 
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "warning"
    -	 * 
    -	 * COMPILER / Reporting Usage of char[] Expressions in String Concatenations
    -	 *    When enabled, the compiler will issue an error or a warning whenever a char[] expression
    -	 *    is used in String concatenations (for example, "hello" + new char[]{'w','o','r','l','d'}).
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion"
    -	 *     - possible values:   { "error", "warning", "ignore" }
    -	 *     - default:           "warning"
    -	 *
    -	 * COMPILER / Setting Source Compatibility Mode
    -	 *    Specify whether source is 1.3 or 1.4 compatible. From 1.4 on, 'assert' is a keyword
    -	 *    reserved for assertion support. Also note, than when toggling to 1.4 mode, the target VM
    -	 *   level should be set to "1.4" and the compliance mode should be "1.4".
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.source"
    -	 *     - possible values:   { "1.3", "1.4" }
    -	 *     - default:           "1.3"
    -	 * 
    -	 * COMPILER / Setting Compliance Level
    -	 *    Select the compliance level for the compiler. In "1.3" mode, source and target settings
    -	 *    should not go beyond "1.3" level.
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.compliance"
    -	 *     - possible values:   { "1.3", "1.4" }
    -	 *     - default:           "1.3"
    -	 * 
    -	 * COMPILER / Maximum number of problems reported per compilation unit
    -	 *    Specify the maximum number of problems reported on each compilation unit.
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.maxProblemPerUnit"
    -	 *     - possible values:	"" where  is zero or a positive integer (if zero then all problems are reported).
    -	 *     - default:           "100"
    -	 * 
    -	 * COMPILER / Define the Automatic Task Tags
    -	 *    When the tag list is not empty, the compiler will issue a task marker whenever it encounters
    -	 *    one of the corresponding tag inside any comment in Java source code.
    -	 *    Generated task messages will include the tag, and range until the next line separator or comment ending.
    -	 *    Note that tasks messages are trimmed.
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.taskTags"
    -	 *     - possible values:   { "[,]*" } where  is a String without any wild-card or leading/trailing spaces 
    -	 *     - default:           ""
    -	 * 
    -	 * COMPILER / Define the Automatic Task Priorities
    -	 *    In parallel with the Automatic Task Tags, this list defines the priorities (high, normal or low)
    -	 *    of the task markers issued by the compiler.
    -	 *    If the default is specified, the priority of each task marker is "NORMAL".
    -	 *     - option id:         "org.eclipse.jdt.core.compiler.taskPriorities"
    -	 *     - possible values:   { "[,]*" } where  is one of "HIGH", "NORMAL" or "LOW"
    -	 *     - default:           ""
    -	 *
    -	 * BUILDER / Specifying Filters for Resource Copying Control
    -	 *    Allow to specify some filters to control the resource copy process.
    -	 *     - option id:         "org.eclipse.jdt.core.builder.resourceCopyExclusionFilter"
    -	 *     - possible values:   { "[,]* } where  is a file name pattern (* and ? wild-cards allowed)
    -	 *       or the name of a folder which ends with '/'
    -	 *     - default:           ""
    -	 * 
    -	 * BUILDER / Abort if Invalid Classpath
    -	 *    Allow to toggle the builder to abort if the classpath is invalid
    -	 *     - option id:         "org.eclipse.jdt.core.builder.invalidClasspath"
    -	 *     - possible values:   { "abort", "ignore" }
    -	 *     - default:           "abort"
    -	 * 
    -	 * BUILDER / Cleaning Output Folder(s)
    -	 *    Indicate whether the JavaBuilder is allowed to clean the output folders
    -	 *    when performing full build operations.
    -	 *     - option id:         "org.eclipse.jdt.core.builder.cleanOutputFolder"
    -	 *     - possible values:   { "clean", "ignore" }
    -	 *     - default:           "clean"
    -	 * 
    -	 * BUILDER / Reporting Duplicate Resources
    -	 *    Indicate the severity of the problem reported when more than one occurrence
    -	 *    of a resource is to be copied into the output location.
    -	 *     - option id:         "org.eclipse.jdt.core.builder.duplicateResourceTask"
    -	 *     - possible values:   { "error", "warning" }
    -	 *     - default:           "warning"
    -	 * 
    -	 * JAVACORE / Computing Project Build Order
    -	 *    Indicate whether JavaCore should enforce the project build order to be based on
    -	 *    the classpath prerequisite chain. When requesting to compute, this takes over
    -	 *    the platform default order (based on project references).
    -	 *     - option id:         "org.eclipse.jdt.core.computeJavaBuildOrder"
    -	 *     - possible values:   { "compute", "ignore" }
    -	 *     - default:           "ignore"	 
    -	 * 
    -	 * JAVACORE / Specify Default Source Encoding Format
    -	 *    Get the encoding format for compiled sources. This setting is read-only, it is equivalent
    -	 *    to 'ResourcesPlugin.getEncoding()'.
    -	 *     - option id:         "org.eclipse.jdt.core.encoding"
    -	 *     - possible values:   { any of the supported encoding name}.
    -	 *     - default:           
    -	 * 
    -	 * JAVACORE / Reporting Incomplete Classpath
    -	 *    Indicate the severity of the problem reported when an entry on the classpath does not exist, 
    -	 *    is not legite or is not visible (for example, a referenced project is closed).
    -	 *     - option id:         "org.eclipse.jdt.core.incompleteClasspath"
    -	 *     - possible values:   { "error", "warning"}
    -	 *     - default:           "error"
    -	 * 
    -	 * JAVACORE / Reporting Classpath Cycle
    -	 *    Indicate the severity of the problem reported when a project is involved in a cycle.
    -	 *     - option id:         "org.eclipse.jdt.core.circularClasspath"
    -	 *     - possible values:   { "error", "warning" }
    -	 *     - default:           "error"
    -	 * 
    -	 * JAVACORE / Enabling Usage of Classpath Exclusion Patterns
    -	 *    When disabled, no entry on a project classpath can be associated with
    -	 *    an exclusion pattern.
    -	 *     - option id:         "org.eclipse.jdt.core.classpath.exclusionPatterns"
    -	 *     - possible values:   { "enabled", "disabled" }
    -	 *     - default:           "enabled"
    -	 * 
    -	 * JAVACORE / Enabling Usage of Classpath Multiple Output Locations
    -	 *    When disabled, no entry on a project classpath can be associated with
    -	 *    a specific output location, preventing thus usage of multiple output locations.
    -	 *     - option id:         "org.eclipse.jdt.core.classpath.multipleOutputLocations"
    -	 *     - possible values:   { "enabled", "disabled" }
    -	 *     - default:           "enabled"
    -	 * 
    -	 *	FORMATTER / Inserting New Line Before Opening Brace
    -	 *    When Insert, a new line is inserted before an opening brace, otherwise nothing
    -	 *    is inserted
    -	 *     - option id:         "org.eclipse.jdt.core.formatter.newline.openingBrace"
    -	 *     - possible values:   { "insert", "do not insert" }
    -	 *     - default:           "do not insert"
    -	 * 
    -	 *	FORMATTER / Inserting New Line Inside Control Statement
    -	 *    When Insert, a new line is inserted between } and following else, catch, finally
    -	 *     - option id:         "org.eclipse.jdt.core.formatter.newline.controlStatement"
    -	 *     - possible values:   { "insert", "do not insert" }
    -	 *     - default:           "do not insert"
    -	 * 
    -	 *	FORMATTER / Clearing Blank Lines
    -	 *    When Clear all, all blank lines are removed. When Preserve one, only one is kept
    -	 *    and all others removed.
    -	 *     - option id:         "org.eclipse.jdt.core.formatter.newline.clearAll"
    -	 *     - possible values:   { "clear all", "preserve one" }
    -	 *     - default:           "preserve one"
    -	 * 
    -	 *	FORMATTER / Inserting New Line Between Else/If 
    -	 *    When Insert, a blank line is inserted between an else and an if when they are 
    -	 *    contiguous. When choosing to not insert, else-if will be kept on the same
    -	 *    line when possible.
    -	 *     - option id:         "org.eclipse.jdt.core.formatter.newline.elseIf"
    -	 *     - possible values:   { "insert", "do not insert" }
    -	 *     - default:           "do not insert"
    -	 * 
    -	 *	FORMATTER / Inserting New Line In Empty Block
    -	 *    When insert, a line break is inserted between contiguous { and }, if } is not followed
    -	 *    by a keyword.
    -	 *     - option id:         "org.eclipse.jdt.core.formatter.newline.emptyBlock"
    -	 *     - possible values:   { "insert", "do not insert" }
    -	 *     - default:           "insert"
    -	 * 
    -	 *	FORMATTER / Splitting Lines Exceeding Length
    -	 *    Enable splitting of long lines (exceeding the configurable length). Length of 0 will
    -	 *    disable line splitting
    -	 *     - option id:         "org.eclipse.jdt.core.formatter.lineSplit"
    -	 *     - possible values:	"", where n is zero or a positive integer
    -	 *     - default:           "80"
    -	 * 
    -	 *	FORMATTER / Compacting Assignment
    -	 *    Assignments can be formatted asymmetrically, for example 'int x= 2;', when Normal, a space
    -	 *    is inserted before the assignment operator
    -	 *     - option id:         "org.eclipse.jdt.core.formatter.style.assignment"
    -	 *     - possible values:   { "compact", "normal" }
    -	 *     - default:           "normal"
    -	 * 
    -	 *	FORMATTER / Defining Indentation Character
    -	 *    Either choose to indent with tab characters or spaces
    -	 *     - option id:         "org.eclipse.jdt.core.formatter.tabulation.char"
    -	 *     - possible values:   { "tab", "space" }
    -	 *     - default:           "tab"
    -	 * 
    -	 *	FORMATTER / Defining Space Indentation Length
    -	 *    When using spaces, set the amount of space characters to use for each 
    -	 *    indentation mark.
    -	 *     - option id:         "org.eclipse.jdt.core.formatter.tabulation.size"
    -	 *     - possible values:	"", where n is a positive integer
    -	 *     - default:           "4"
    -	 * 
    -	 *	FORMATTER / Inserting space in cast expression
    -	 *    When Insert, a space is added between the type and the expression in a cast expression.
    -	 *     - option id:         "org.eclipse.jdt.core.formatter.space.castexpression"
    -	 *     - possible values:   { "insert", "do not insert" }
    -	 *     - default:           "insert"
    -	 * 
    -	 *	CODEASSIST / Activate Visibility Sensitive Completion
    -	 *    When active, completion doesn't show that you can not see
    -	 *    (for example, you can not see private methods of a super class).
    -	 *     - option id:         "org.eclipse.jdt.core.codeComplete.visibilityCheck"
    -	 *     - possible values:   { "enabled", "disabled" }
    -	 *     - default:           "disabled"
    -	 * 
    -	 *	CODEASSIST / Automatic Qualification of Implicit Members
    -	 *    When active, completion automatically qualifies completion on implicit
    -	 *    field references and message expressions.
    -	 *     - option id:         "org.eclipse.jdt.core.codeComplete.forceImplicitQualification"
    -	 *     - possible values:   { "enabled", "disabled" }
    -	 *     - default:           "disabled"
    -	 * 
    -	 *  CODEASSIST / Define the Prefixes for Field Name
    -	 *    When the prefixes is non empty, completion for field name will begin with
    -	 *    one of the proposed prefixes.
    -	 *     - option id:         "org.eclipse.jdt.core.codeComplete.fieldPrefixes"
    -	 *     - possible values:   { "[,]*" } where  is a String without any wild-card 
    -	 *     - default:           ""
    -	 * 
    -	 *  CODEASSIST / Define the Prefixes for Static Field Name
    -	 *    When the prefixes is non empty, completion for static field name will begin with
    -	 *    one of the proposed prefixes.
    -	 *     - option id:         "org.eclipse.jdt.core.codeComplete.staticFieldPrefixes"
    -	 *     - possible values:   { "[,]*" } where  is a String without any wild-card 
    -	 *     - default:           ""
    -	 * 
    -	 *  CODEASSIST / Define the Prefixes for Local Variable Name
    -	 *    When the prefixes is non empty, completion for local variable name will begin with
    -	 *    one of the proposed prefixes.
    -	 *     - option id:         "org.eclipse.jdt.core.codeComplete.localPrefixes"
    -	 *     - possible values:   { "[,]*" } where  is a String without any wild-card 
    -	 *     - default:           ""
    -	 * 
    -	 *  CODEASSIST / Define the Prefixes for Argument Name
    -	 *    When the prefixes is non empty, completion for argument name will begin with
    -	 *    one of the proposed prefixes.
    -	 *     - option id:         "org.eclipse.jdt.core.codeComplete.argumentPrefixes"
    -	 *     - possible values:   { "[,]*" } where  is a String without any wild-card 
    -	 *     - default:           ""
    -	 * 
    -	 *  CODEASSIST / Define the Suffixes for Field Name
    -	 *    When the suffixes is non empty, completion for field name will end with
    -	 *    one of the proposed suffixes.
    -	 *     - option id:         "org.eclipse.jdt.core.codeComplete.fieldSuffixes"
    -	 *     - possible values:   { "[,]*" } where  is a String without any wild-card 
    -	 *     - default:           ""
    -	 * 
    -	 *  CODEASSIST / Define the Suffixes for Static Field Name
    -	 *    When the suffixes is non empty, completion for static field name will end with
    -	 *    one of the proposed suffixes.
    -	 *     - option id:         "org.eclipse.jdt.core.codeComplete.staticFieldSuffixes"
    -	 *     - possible values:   { "[,]*" } where  is a String without any wild-card 
    -	 *     - default:           ""
    -	 * 
    -	 *  CODEASSIST / Define the Suffixes for Local Variable Name
    -	 *    When the suffixes is non empty, completion for local variable name will end with
    -	 *    one of the proposed suffixes.
    -	 *     - option id:         "org.eclipse.jdt.core.codeComplete.localSuffixes"
    -	 *     - possible values:   { "[,]*" } where  is a String without any wild-card 
    -	 *     - default:           ""
    -	 * 
    -	 *  CODEASSIST / Define the Suffixes for Argument Name
    -	 *    When the suffixes is non empty, completion for argument name will end with
    -	 *    one of the proposed suffixes.
    -	 *     - option id:         "org.eclipse.jdt.core.codeComplete.argumentSuffixes"
    -	 *     - possible values:   { "[,]*" } where  is a String without any wild-card 
    -	 *     - default:           ""
    -	 * 
    - * - * @return a mutable table containing the default settings of all known options - * (key type: String; value type: String) - * @see #setOptions - */ - public static Hashtable getDefaultOptions(){ - - Hashtable defaultOptions = new Hashtable(10); - - // see #initializeDefaultPluginPreferences() for changing default settings - Preferences preferences = getPlugin().getPluginPreferences(); - HashSet optionNames = JavaModelManager.OptionNames; - - // get preferences set to their default - String[] defaultPropertyNames = preferences.defaultPropertyNames(); - for (int i = 0; i < defaultPropertyNames.length; i++){ - String propertyName = defaultPropertyNames[i]; - if (optionNames.contains(propertyName)) { - defaultOptions.put(propertyName, preferences.getDefaultString(propertyName)); - } - } - // get preferences not set to their default - String[] propertyNames = preferences.propertyNames(); - for (int i = 0; i < propertyNames.length; i++){ - String propertyName = propertyNames[i]; - if (optionNames.contains(propertyName)) { - defaultOptions.put(propertyName, preferences.getDefaultString(propertyName)); - } - } - // get encoding through resource plugin - defaultOptions.put(CORE_ENCODING, ResourcesPlugin.getEncoding()); - - return defaultOptions; - } - - /** - * Returns the single instance of the Java core plug-in runtime class. - * Equivalent to (JavaCore) getPlugin(). - * - * @return the single instance of the Java core plug-in runtime class - */ - public static JavaCore getJavaCore() { - return (JavaCore) getPlugin(); - } - - /** - * Helper method for returning one option value only. Equivalent to (String)JavaCore.getOptions().get(optionName) - * Note that it may answer null if this option does not exist. - *

    - * For a complete description of the configurable options, see getDefaultOptions. - *

    - * - * @param optionName the name of an option - * @return the String value of a given option - * @see JavaCore#getDefaultOptions - * @since 2.0 - */ - public static String getOption(String optionName) { - - if (CORE_ENCODING.equals(optionName)){ - return ResourcesPlugin.getEncoding(); - } - if (JavaModelManager.OptionNames.contains(optionName)){ - Preferences preferences = getPlugin().getPluginPreferences(); - return preferences.getString(optionName).trim(); - } - return null; - } - - /** - * Returns the table of the current options. Initially, all options have their default values, - * and this method returns a table that includes all known options. - *

    - * For a complete description of the configurable options, see getDefaultOptions. - *

    - * - * @return table of current settings of all options - * (key type: String; value type: String) - * @see JavaCore#getDefaultOptions - */ - public static Hashtable getOptions() { - - Hashtable options = new Hashtable(10); - - // see #initializeDefaultPluginPreferences() for changing default settings - Plugin plugin = getPlugin(); - if (plugin != null) { - Preferences preferences = getPlugin().getPluginPreferences(); - HashSet optionNames = JavaModelManager.OptionNames; - - // get preferences set to their default - String[] defaultPropertyNames = preferences.defaultPropertyNames(); - for (int i = 0; i < defaultPropertyNames.length; i++){ - String propertyName = defaultPropertyNames[i]; - if (optionNames.contains(propertyName)){ - options.put(propertyName, preferences.getDefaultString(propertyName)); - } - } - // get preferences not set to their default - String[] propertyNames = preferences.propertyNames(); - for (int i = 0; i < propertyNames.length; i++){ - String propertyName = propertyNames[i]; - if (optionNames.contains(propertyName)){ - options.put(propertyName, preferences.getString(propertyName).trim()); - } - } - // get encoding through resource plugin - options.put(CORE_ENCODING, ResourcesPlugin.getEncoding()); - } - return options; - } - - /** - * Returns the single instance of the Java core plug-in runtime class. - * - * @return the single instance of the Java core plug-in runtime class - */ - public static Plugin getPlugin() { - return JAVA_CORE_PLUGIN; - } - - /** - * This is a helper method, which returns the resolved classpath entry denoted - * by a given entry (if it is a variable entry). It is obtained by resolving the variable - * reference in the first segment. Returns null if unable to resolve using - * the following algorithm: - *
      - *
    • if variable segment cannot be resolved, returns null
    • - *
    • finds a project, JAR or binary folder in the workspace at the resolved path location
    • - *
    • if none finds an external JAR file or folder outside the workspace at the resolved path location
    • - *
    • if none returns null
    • - *
    - *

    - * Variable source attachment path and root path are also resolved and recorded in the resulting classpath entry. - *

    - * NOTE: This helper method does not handle classpath containers, for which should rather be used - * JavaCore#getClasspathContainer(IPath, IJavaProject). - *

    - * - * @param entry the given variable entry - * @return the resolved library or project classpath entry, or null - * if the given variable entry could not be resolved to a valid classpath entry - */ -// public static IClasspathEntry getResolvedClasspathEntry(IClasspathEntry entry) { -// -// if (entry.getEntryKind() != IClasspathEntry.CPE_VARIABLE) -// return entry; -// -// IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); -// IPath resolvedPath = JavaCore.getResolvedVariablePath(entry.getPath()); -// if (resolvedPath == null) -// return null; -// -// Object target = JavaModel.getTarget(workspaceRoot, resolvedPath, false); -// if (target == null) -// return null; -// -// // inside the workspace -// if (target instanceof IResource) { -// IResource resolvedResource = (IResource) target; -// if (resolvedResource != null) { -// switch (resolvedResource.getType()) { -// -// case IResource.PROJECT : -// // internal project -// return JavaCore.newProjectEntry(resolvedPath, entry.isExported()); -// -// case IResource.FILE : -// if (Util.isArchiveFileName(resolvedResource.getName())) { -// // internal binary archive -// return JavaCore.newLibraryEntry( -// resolvedPath, -// getResolvedVariablePath(entry.getSourceAttachmentPath()), -// getResolvedVariablePath(entry.getSourceAttachmentRootPath()), -// entry.isExported()); -// } -// break; -// -// case IResource.FOLDER : -// // internal binary folder -// return JavaCore.newLibraryEntry( -// resolvedPath, -// getResolvedVariablePath(entry.getSourceAttachmentPath()), -// getResolvedVariablePath(entry.getSourceAttachmentRootPath()), -// entry.isExported()); -// } -// } -// } -// // outside the workspace -// if (target instanceof File) { -// File externalFile = (File) target; -// if (externalFile.isFile()) { -// String fileName = externalFile.getName().toLowerCase(); -// if (fileName.endsWith(".jar" //$NON-NLS-1$ -// ) || fileName.endsWith(".zip" //$NON-NLS-1$ -// )) { // external binary archive -// return JavaCore.newLibraryEntry( -// resolvedPath, -// getResolvedVariablePath(entry.getSourceAttachmentPath()), -// getResolvedVariablePath(entry.getSourceAttachmentRootPath()), -// entry.isExported()); -// } -// } else { // external binary folder -// if (resolvedPath.isAbsolute()){ -// return JavaCore.newLibraryEntry( -// resolvedPath, -// getResolvedVariablePath(entry.getSourceAttachmentPath()), -// getResolvedVariablePath(entry.getSourceAttachmentRootPath()), -// entry.isExported()); -// } -// } -// } -// return null; -// } - - - /** - * Resolve a variable path (helper method). - * - * @param variablePath the given variable path - * @return the resolved variable path or null if none - */ -// public static IPath getResolvedVariablePath(IPath variablePath) { -// -// if (variablePath == null) -// return null; -// int count = variablePath.segmentCount(); -// if (count == 0) -// return null; -// -// // lookup variable -// String variableName = variablePath.segment(0); -// IPath resolvedPath = JavaCore.getClasspathVariable(variableName); -// if (resolvedPath == null) -// return null; -// -// // append path suffix -// if (count > 1) { -// resolvedPath = resolvedPath.append(variablePath.removeFirstSegments(1)); -// } -// return resolvedPath; -// } - - /** - * Answers the shared working copies currently registered for this buffer factory. - * Working copies can be shared by several clients using the same buffer factory,see - * IWorkingCopy.getSharedWorkingCopy. - * - * @param factory the given buffer factory - * @return the list of shared working copies for a given buffer factory - * @see IWorkingCopy - * @since 2.0 - */ - public static IWorkingCopy[] getSharedWorkingCopies(IBufferFactory factory){ - - // if factory is null, default factory must be used - if (factory == null) factory = BufferManager.getDefaultBufferManager().getDefaultBufferFactory(); - Map sharedWorkingCopies = JavaModelManager.getJavaModelManager().sharedWorkingCopies; - - Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory); - if (perFactoryWorkingCopies == null) return JavaModelManager.NoWorkingCopy; - Collection copies = perFactoryWorkingCopies.values(); - IWorkingCopy[] result = new IWorkingCopy[copies.size()]; - copies.toArray(result); - return result; - } - - /** - * Initializes the default preferences settings for this plug-in. - */ - protected void initializeDefaultPluginPreferences() { - - Preferences preferences = getPluginPreferences(); - HashSet optionNames = JavaModelManager.OptionNames; - - // Compiler settings - preferences.setDefault(COMPILER_LOCAL_VARIABLE_ATTR, GENERATE); - optionNames.add(COMPILER_LOCAL_VARIABLE_ATTR); - - preferences.setDefault(COMPILER_LINE_NUMBER_ATTR, GENERATE); - optionNames.add(COMPILER_LINE_NUMBER_ATTR); - - preferences.setDefault(COMPILER_SOURCE_FILE_ATTR, GENERATE); - optionNames.add(COMPILER_SOURCE_FILE_ATTR); - - preferences.setDefault(COMPILER_CODEGEN_UNUSED_LOCAL, PRESERVE); - optionNames.add(COMPILER_CODEGEN_UNUSED_LOCAL); - - preferences.setDefault(COMPILER_CODEGEN_TARGET_PLATFORM, VERSION_1_1); - optionNames.add(COMPILER_CODEGEN_TARGET_PLATFORM); - - preferences.setDefault(COMPILER_PB_UNREACHABLE_CODE, ERROR); - optionNames.add(COMPILER_PB_UNREACHABLE_CODE); - - preferences.setDefault(COMPILER_PB_INVALID_IMPORT, ERROR); - optionNames.add(COMPILER_PB_INVALID_IMPORT); - - preferences.setDefault(COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD, WARNING); - optionNames.add(COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD); - - preferences.setDefault(COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME, WARNING); - optionNames.add(COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME); - - preferences.setDefault(COMPILER_PB_DEPRECATION, WARNING); - optionNames.add(COMPILER_PB_DEPRECATION); - - preferences.setDefault(COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE, DISABLED); - optionNames.add(COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE); - - preferences.setDefault(COMPILER_PB_HIDDEN_CATCH_BLOCK, WARNING); - optionNames.add(COMPILER_PB_HIDDEN_CATCH_BLOCK); - - preferences.setDefault(COMPILER_PB_UNUSED_LOCAL, IGNORE); - optionNames.add(COMPILER_PB_UNUSED_LOCAL); - - preferences.setDefault(COMPILER_PB_UNUSED_PARAMETER, IGNORE); - optionNames.add(COMPILER_PB_UNUSED_PARAMETER); - - preferences.setDefault(COMPILER_PB_UNUSED_PARAMETER_WHEN_IMPLEMENTING_ABSTRACT, DISABLED); - optionNames.add(COMPILER_PB_UNUSED_PARAMETER_WHEN_IMPLEMENTING_ABSTRACT); - - preferences.setDefault(COMPILER_PB_UNUSED_PARAMETER_WHEN_OVERRIDING_CONCRETE, DISABLED); - optionNames.add(COMPILER_PB_UNUSED_PARAMETER_WHEN_OVERRIDING_CONCRETE); - - preferences.setDefault(COMPILER_PB_UNUSED_IMPORT, WARNING); - optionNames.add(COMPILER_PB_UNUSED_IMPORT); - - preferences.setDefault(COMPILER_PB_UNUSED_PRIVATE_MEMBER, IGNORE); - optionNames.add(COMPILER_PB_UNUSED_PRIVATE_MEMBER); - - preferences.setDefault(COMPILER_PB_SYNTHETIC_ACCESS_EMULATION, IGNORE); - optionNames.add(COMPILER_PB_SYNTHETIC_ACCESS_EMULATION); - - preferences.setDefault(COMPILER_PB_NON_NLS_STRING_LITERAL, IGNORE); - optionNames.add(COMPILER_PB_NON_NLS_STRING_LITERAL); - - preferences.setDefault(COMPILER_PB_ASSERT_IDENTIFIER, IGNORE); - optionNames.add(COMPILER_PB_ASSERT_IDENTIFIER); - - preferences.setDefault(COMPILER_PB_STATIC_ACCESS_RECEIVER, WARNING); - optionNames.add(COMPILER_PB_STATIC_ACCESS_RECEIVER); - - preferences.setDefault(COMPILER_PB_NO_EFFECT_ASSIGNMENT, WARNING); - optionNames.add(COMPILER_PB_NO_EFFECT_ASSIGNMENT); - - preferences.setDefault(COMPILER_PB_INCOMPATIBLE_NON_INHERITED_INTERFACE_METHOD, WARNING); - optionNames.add(COMPILER_PB_INCOMPATIBLE_NON_INHERITED_INTERFACE_METHOD); - - preferences.setDefault(COMPILER_PB_CHAR_ARRAY_IN_STRING_CONCATENATION, WARNING); - optionNames.add(COMPILER_PB_CHAR_ARRAY_IN_STRING_CONCATENATION); - - preferences.setDefault(COMPILER_TASK_TAGS, DEFAULT_TASK_TAG); //$NON-NLS-1$ - optionNames.add(COMPILER_TASK_TAGS); - - preferences.setDefault(COMPILER_TASK_PRIORITIES, DEFAULT_TASK_PRIORITY); //$NON-NLS-1$ - optionNames.add(COMPILER_TASK_PRIORITIES); - - preferences.setDefault(COMPILER_SOURCE, VERSION_1_3); - optionNames.add(COMPILER_SOURCE); - - preferences.setDefault(COMPILER_COMPLIANCE, VERSION_1_3); - optionNames.add(COMPILER_COMPLIANCE); - - preferences.setDefault(COMPILER_PB_MAX_PER_UNIT, "100"); //$NON-NLS-1$ - optionNames.add(COMPILER_PB_MAX_PER_UNIT); - - // Builder settings - preferences.setDefault(CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, ""); //$NON-NLS-1$ - optionNames.add(CORE_JAVA_BUILD_RESOURCE_COPY_FILTER); - - preferences.setDefault(CORE_JAVA_BUILD_INVALID_CLASSPATH, ABORT); - optionNames.add(CORE_JAVA_BUILD_INVALID_CLASSPATH); - - preferences.setDefault(CORE_JAVA_BUILD_DUPLICATE_RESOURCE, WARNING); - optionNames.add(CORE_JAVA_BUILD_DUPLICATE_RESOURCE); - - preferences.setDefault(CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, CLEAN); - optionNames.add(CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER); - - // JavaCore settings - preferences.setDefault(CORE_JAVA_BUILD_ORDER, IGNORE); - optionNames.add(CORE_JAVA_BUILD_ORDER); - - preferences.setDefault(CORE_CIRCULAR_CLASSPATH, ERROR); - optionNames.add(CORE_CIRCULAR_CLASSPATH); - - preferences.setDefault(CORE_INCOMPLETE_CLASSPATH, ERROR); - optionNames.add(CORE_INCOMPLETE_CLASSPATH); - - preferences.setDefault(CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, ENABLED); - optionNames.add(CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS); - - preferences.setDefault(CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, ENABLED); - optionNames.add(CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS); - - // encoding setting comes from resource plug-in - optionNames.add(CORE_ENCODING); - - // Formatter settings - preferences.setDefault(FORMATTER_NEWLINE_OPENING_BRACE, DO_NOT_INSERT); - optionNames.add(FORMATTER_NEWLINE_OPENING_BRACE); - - preferences.setDefault(FORMATTER_NEWLINE_CONTROL, DO_NOT_INSERT); - optionNames.add(FORMATTER_NEWLINE_CONTROL); - - preferences.setDefault(FORMATTER_CLEAR_BLANK_LINES, PRESERVE_ONE); - optionNames.add(FORMATTER_CLEAR_BLANK_LINES); - - preferences.setDefault(FORMATTER_NEWLINE_ELSE_IF, DO_NOT_INSERT); - optionNames.add(FORMATTER_NEWLINE_ELSE_IF); - - preferences.setDefault(FORMATTER_NEWLINE_EMPTY_BLOCK, INSERT); - optionNames.add(FORMATTER_NEWLINE_EMPTY_BLOCK); - - preferences.setDefault(FORMATTER_LINE_SPLIT, "80"); //$NON-NLS-1$ - optionNames.add(FORMATTER_LINE_SPLIT); - - preferences.setDefault(FORMATTER_COMPACT_ASSIGNMENT, NORMAL); - optionNames.add(FORMATTER_COMPACT_ASSIGNMENT); - - preferences.setDefault(FORMATTER_TAB_CHAR, TAB); - optionNames.add(FORMATTER_TAB_CHAR); - - preferences.setDefault(FORMATTER_TAB_SIZE, "4"); //$NON-NLS-1$ - optionNames.add(FORMATTER_TAB_SIZE); - - preferences.setDefault(FORMATTER_SPACE_CASTEXPRESSION, INSERT); //$NON-NLS-1$ - optionNames.add(FORMATTER_SPACE_CASTEXPRESSION); - - // CodeAssist settings - preferences.setDefault(CODEASSIST_VISIBILITY_CHECK, DISABLED); //$NON-NLS-1$ - optionNames.add(CODEASSIST_VISIBILITY_CHECK); - - preferences.setDefault(CODEASSIST_IMPLICIT_QUALIFICATION, DISABLED); //$NON-NLS-1$ - optionNames.add(CODEASSIST_IMPLICIT_QUALIFICATION); - - preferences.setDefault(CODEASSIST_FIELD_PREFIXES, ""); //$NON-NLS-1$ - optionNames.add(CODEASSIST_FIELD_PREFIXES); - - preferences.setDefault(CODEASSIST_STATIC_FIELD_PREFIXES, ""); //$NON-NLS-1$ - optionNames.add(CODEASSIST_STATIC_FIELD_PREFIXES); - - preferences.setDefault(CODEASSIST_LOCAL_PREFIXES, ""); //$NON-NLS-1$ - optionNames.add(CODEASSIST_LOCAL_PREFIXES); - - preferences.setDefault(CODEASSIST_ARGUMENT_PREFIXES, ""); //$NON-NLS-1$ - optionNames.add(CODEASSIST_ARGUMENT_PREFIXES); - - preferences.setDefault(CODEASSIST_FIELD_SUFFIXES, ""); //$NON-NLS-1$ - optionNames.add(CODEASSIST_FIELD_SUFFIXES); - - preferences.setDefault(CODEASSIST_STATIC_FIELD_SUFFIXES, ""); //$NON-NLS-1$ - optionNames.add(CODEASSIST_STATIC_FIELD_SUFFIXES); - - preferences.setDefault(CODEASSIST_LOCAL_SUFFIXES, ""); //$NON-NLS-1$ - optionNames.add(CODEASSIST_LOCAL_SUFFIXES); - - preferences.setDefault(CODEASSIST_ARGUMENT_SUFFIXES, ""); //$NON-NLS-1$ - optionNames.add(CODEASSIST_ARGUMENT_SUFFIXES); - } - - /** - * Returns whether the given marker references the given Java element. - * Used for markers, which denote a Java element rather than a resource. - * - * @param element the element - * @param marker the marker - * @return true if the marker references the element, false otherwise - * @exception CoreException if the IMarker.getAttribute on the marker fails - */ - public static boolean isReferencedBy(IJavaElement element, IMarker marker) throws CoreException { - - // only match units or classfiles - if (element instanceof IMember){ - IMember member = (IMember) element; - if (member.isBinary()){ - element = null; //member.getClassFile(); - } else { - element = member.getCompilationUnit(); - } - } - if (element == null) return false; - if (marker == null) return false; - - String markerHandleId = (String)marker.getAttribute(ATT_HANDLE_ID); - if (markerHandleId == null) return false; - - IJavaElement markerElement = JavaCore.create(markerHandleId); -// while (true){ - if (element.equals(markerElement)) return true; // external elements may still be equal with different handleIDs. - - // cycle through enclosing types in case marker is associated with a classfile (15568) -// if (markerElement instanceof IClassFile){ -// IType enclosingType = ((IClassFile)markerElement).getType().getDeclaringType(); -// if (enclosingType != null){ -// markerElement = enclosingType.getClassFile(); // retry with immediate enclosing classfile -// continue; -// } -// } -// break; -// } - return false; - } - - /** - * Returns whether the given marker delta references the given Java element. - * Used for markers deltas, which denote a Java element rather than a resource. - * - * @param element the element - * @param markerDelta the marker delta - * @return true if the marker delta references the element - * @exception CoreException if the IMarkerDelta.getAttribute on the marker delta fails - */ - public static boolean isReferencedBy(IJavaElement element, IMarkerDelta markerDelta) throws CoreException { - - // only match units or classfiles - if (element instanceof IMember){ - IMember member = (IMember) element; - if (member.isBinary()){ - element = null; //member.getClassFile(); - } else { - element = member.getCompilationUnit(); - } - } - if (element == null) return false; - if (markerDelta == null) return false; - - String markerDeltarHandleId = (String)markerDelta.getAttribute(ATT_HANDLE_ID); - if (markerDeltarHandleId == null) return false; - - IJavaElement markerElement = JavaCore.create(markerDeltarHandleId); -// while (true){ - if (element.equals(markerElement)) return true; // external elements may still be equal with different handleIDs. - - // cycle through enclosing types in case marker is associated with a classfile (15568) -// if (markerElement instanceof IClassFile){ -// IType enclosingType = ((IClassFile)markerElement).getType().getDeclaringType(); -// if (enclosingType != null){ -// markerElement = enclosingType.getClassFile(); // retry with immediate enclosing classfile -// continue; -// } -// } -// break; -// } - return false; - } - - /** - * Creates and returns a new classpath entry of kind CPE_CONTAINER - * for the given path. The path of the container will be used during resolution so as to map this - * container entry to a set of other classpath entries the container is acting for. - *

    - * A container entry allows to express indirect references to a set of libraries, projects and variable entries, - * which can be interpreted differently for each Java project where it is used. - * A classpath container entry can be resolved using JavaCore.getResolvedClasspathContainer, - * and updated with JavaCore.classpathContainerChanged - *

    - * A container is exclusively resolved by a ClasspathContainerInitializer registered onto the - * extension point "org.eclipse.jdt.core.classpathContainerInitializer". - *

    - * A container path must be formed of at least one segment, where:

      - *
    • the first segment is a unique ID identifying the target container, there must be a container initializer registered - * onto this ID through the extension point "org.eclipse.jdt.core.classpathContainerInitializer".
    • - *
    • the remaining segments will be passed onto the initializer, and can be used as additional - * hints during the initialization phase.
    • - *
    - *

    - * Example of an ClasspathContainerInitializer for a classpath container denoting a default JDK container: - * - * containerEntry = JavaCore.newContainerEntry(new Path("MyProvidedJDK/default")); - * - * - * - *

    - * Note that this operation does not attempt to validate classpath containers - * or access the resources at the given paths. - *

    - * The resulting entry is not exported to dependent projects. This method is equivalent to - * newContainerEntry(-,false). - *

    - * @param containerPath the path identifying the container, it must be formed of two - * segments - * @return a new container classpath entry - * - * @see JavaCore#getClasspathContainer(IPath, IJavaProject) - * @see JavaCore#newContainerEntry(IPath, boolean) - * @since 2.0 - */ -// public static IClasspathEntry newContainerEntry(IPath containerPath) { -// -// return newContainerEntry(containerPath, false); -// } - - /** - * Creates and returns a new classpath entry of kind CPE_CONTAINER - * for the given path. The path of the container will be used during resolution so as to map this - * container entry to a set of other classpath entries the container is acting for. - *

    - * A container entry allows to express indirect references to a set of libraries, projects and variable entries, - * which can be interpreted differently for each Java project where it is used. - * A classpath container entry can be resolved using JavaCore.getResolvedClasspathContainer, - * and updated with JavaCore.classpathContainerChanged - *

    - * A container is exclusively resolved by a ClasspathContainerInitializer registered onto the - * extension point "org.eclipse.jdt.core.classpathContainerInitializer". - *

    - * A container path must be formed of at least one segment, where:

      - *
    • the first segment is a unique ID identifying the target container, there must be a container initializer registered - * onto this ID through the extension point "org.eclipse.jdt.core.classpathContainerInitializer".
    • - *
    • the remaining segments will be passed onto the initializer, and can be used as additional - * hints during the initialization phase.
    • - *
    - *

    - * Example of an ClasspathContainerInitializer for a classpath container denoting a default JDK container: - * - * containerEntry = JavaCore.newContainerEntry(new Path("MyProvidedJDK/default")); - * - * - * - *

    - * Note that this operation does not attempt to validate classpath containers - * or access the resources at the given paths. - *

    - * @param containerPath the path identifying the container, it must be formed of at least - * one segment (ID+hints) - * @param isExported a boolean indicating whether this entry is contributed to dependent - * projects in addition to the output location - * @return a new container classpath entry - * - * @see JavaCore#getClasspathContainer(IPath, IJavaProject) - * @see JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], IProgressMonitor) - * @see JavaCore#newContainerEntry(IPath, boolean) - * @since 2.0 - */ -// public static IClasspathEntry newContainerEntry(IPath containerPath, boolean isExported) { -// -// if (containerPath == null || containerPath.segmentCount() < 1) { -// Assert.isTrue( -// false, -// "Illegal classpath container path: \'" + containerPath.makeRelative().toString() + "\', must have at least one segment (containerID+hints)"); //$NON-NLS-1$//$NON-NLS-2$ -// } -// return new ClasspathEntry( -// IPackageFragmentRoot.K_SOURCE, -// IClasspathEntry.CPE_CONTAINER, -// containerPath, -// ClasspathEntry.NO_EXCLUSION_PATTERNS, -// null, // source attachment -// null, // source attachment root -// null, // specific output folder -// isExported); -// } - - /** - * Creates and returns a new non-exported classpath entry of kind CPE_LIBRARY for the - * JAR or folder identified by the given absolute path. This specifies that all package fragments - * within the root will have children of type IClassFile. - *

    - * A library entry is used to denote a prerequisite JAR or root folder containing binaries. - * The target JAR or folder can either be defined internally to the workspace (absolute path relative - * to the workspace root) or externally to the workspace (absolute path in the file system). - *

    - * e.g. Here are some examples of binary path usage

      - *
    • "c:/jdk1.2.2/jre/lib/rt.jar" - reference to an external JAR
    • - *
    • "/Project/someLib.jar" - reference to an internal JAR
    • - *
    • "c:/classes/" - reference to an external binary folder
    • - *
    - * Note that this operation does not attempt to validate or access the - * resources at the given paths. - *

    - * The resulting entry is not exported to dependent projects. This method is equivalent to - * newLibraryEntry(-,-,-,false). - *

    - * - * @param path the absolute path of the binary archive - * @param sourceAttachmentPath the absolute path of the corresponding source archive or folder, - * or null if none - * @param sourceAttachmentRootPath the location of the root within the source archive or folder - * or null if this location should be automatically detected. - * @return a new library classpath entry - * - * @see #newLibraryEntry(IPath, IPath, IPath, boolean) - */ -// public static IClasspathEntry newLibraryEntry( -// IPath path, -// IPath sourceAttachmentPath, -// IPath sourceAttachmentRootPath) { -// -// return newLibraryEntry(path, sourceAttachmentPath, sourceAttachmentRootPath, false); -// } - - /** - * Creates and returns a new classpath entry of kind CPE_LIBRARY for the JAR or folder - * identified by the given absolute path. This specifies that all package fragments within the root - * will have children of type IClassFile. - *

    - * A library entry is used to denote a prerequisite JAR or root folder containing binaries. - * The target JAR or folder can either be defined internally to the workspace (absolute path relative - * to the workspace root) or externally to the workspace (absolute path in the file system). - *

    - * e.g. Here are some examples of binary path usage

      - *
    • "c:/jdk1.2.2/jre/lib/rt.jar" - reference to an external JAR
    • - *
    • "/Project/someLib.jar" - reference to an internal JAR
    • - *
    • "c:/classes/" - reference to an external binary folder
    • - *
    - * Note that this operation does not attempt to validate or access the - * resources at the given paths. - *

    - * - * @param path the absolute path of the binary archive - * @param sourceAttachmentPath the absolute path of the corresponding source archive or folder, - * or null if none - * @param sourceAttachmentRootPath the location of the root within the source archive or folder - * or null if this location should be automatically detected. - * @param isExported indicates whether this entry is contributed to dependent - * projects in addition to the output location - * @return a new library classpath entry - * @since 2.0 - */ -// public static IClasspathEntry newLibraryEntry( -// IPath path, -// IPath sourceAttachmentPath, -// IPath sourceAttachmentRootPath, -// boolean isExported) { -// -// if (!path.isAbsolute()) Assert.isTrue(false, "Path for IClasspathEntry must be absolute"); //$NON-NLS-1$ -// -// return new ClasspathEntry( -// IPackageFragmentRoot.K_BINARY, -// IClasspathEntry.CPE_LIBRARY, -// JavaProject.canonicalizedPath(path), -// ClasspathEntry.NO_EXCLUSION_PATTERNS, -// sourceAttachmentPath, -// sourceAttachmentRootPath, -// null, // specific output folder -// isExported); -// } - - /** - * Creates and returns a new non-exported classpath entry of kind CPE_PROJECT - * for the project identified by the given absolute path. - *

    - * A project entry is used to denote a prerequisite project on a classpath. - * The referenced project will be contributed as a whole, either as sources (in the Java Model, it - * contributes all its package fragment roots) or as binaries (when building, it contributes its - * whole output location). - *

    - * A project reference allows to indirect through another project, independently from its internal layout. - *

    - * The prerequisite project is referred to using an absolute path relative to the workspace root. - *

    - * The resulting entry is not exported to dependent projects. This method is equivalent to - * newProjectEntry(_,false). - *

    - * - * @param path the absolute path of the binary archive - * @return a new project classpath entry - * - * @see JavaCore#newProjectEntry(IPath, boolean) - */ -// public static IClasspathEntry newProjectEntry(IPath path) { -// return newProjectEntry(path, false); -// } - - /** - * Creates and returns a new classpath entry of kind CPE_PROJECT - * for the project identified by the given absolute path. - *

    - * A project entry is used to denote a prerequisite project on a classpath. - * The referenced project will be contributed as a whole, either as sources (in the Java Model, it - * contributes all its package fragment roots) or as binaries (when building, it contributes its - * whole output location). - *

    - * A project reference allows to indirect through another project, independently from its internal layout. - *

    - * The prerequisite project is referred to using an absolute path relative to the workspace root. - *

    - * - * @param path the absolute path of the prerequisite project - * @param isExported indicates whether this entry is contributed to dependent - * projects in addition to the output location - * @return a new project classpath entry - * @since 2.0 - */ -// public static IClasspathEntry newProjectEntry(IPath path, boolean isExported) { -// -// if (!path.isAbsolute()) Assert.isTrue(false, "Path for IClasspathEntry must be absolute"); //$NON-NLS-1$ -// -// return new ClasspathEntry( -// IPackageFragmentRoot.K_SOURCE, -// IClasspathEntry.CPE_PROJECT, -// path, -// ClasspathEntry.NO_EXCLUSION_PATTERNS, -// null, // source attachment -// null, // source attachment root -// null, // specific output folder -// isExported); -// } - - /** - * Returns a new empty region. - * - * @return a new empty region - */ - public static IRegion newRegion() { - return new Region(); - } - - /** - * Creates and returns a new classpath entry of kind CPE_SOURCE - * for the project's source folder identified by the given absolute - * workspace-relative path. This specifies that all package fragments - * within the root will have children of type ICompilationUnit. - *

    - * The source folder is referred to using an absolute path relative to the - * workspace root, e.g. /Project/src. A project's source - * folders are located with that project. That is, a source classpath - * entry specifying the path /P1/src is only usable for - * project P1. - *

    - *

    - * The source classpath entry created by this method includes all source - * files below the given workspace-relative path. To selectively exclude - * some of these source files, use the factory method - * JavaCore.newSourceEntry(IPath,IPath[]) instead. - *

    - *

    - * Note that all sources/binaries inside a project are contributed as a whole through - * a project entry (see JavaCore.newProjectEntry). Particular - * source entries cannot be selectively exported. - *

    - * - * @param path the absolute workspace-relative path of a source folder - * @return a new source classpath entry with not exclusion patterns - * - * @see #newSourceEntry(org.eclipse.core.runtime.IPath,org.eclipse.core.runtime.IPath[]) - */ -// public static IClasspathEntry newSourceEntry(IPath path) { -// -// return newSourceEntry(path, ClasspathEntry.NO_EXCLUSION_PATTERNS, null /*output location*/); -// } - - /** - * Creates and returns a new classpath entry of kind CPE_SOURCE - * for the project's source folder identified by the given absolute - * workspace-relative path but excluding all source files with paths - * matching any of the given patterns. This specifies that all package - * fragments within the root will have children of type - * ICompilationUnit. - *

    - * The source folder is referred to using an absolute path relative to the - * workspace root, e.g. /Project/src. A project's source - * folders are located with that project. That is, a source classpath - * entry specifying the path /P1/src is only usable for - * project P1. - *

    - *

    - * The source classpath entry created by this method includes all source - * files below the given workspace-relative path except for those matched - * by one (or more) of the given exclusion patterns. Each exclusion pattern - * is represented by a relative path, which is interpreted as relative to - * the source folder. For example, if the source folder path is - * /Project/src and the exclusion pattern is - * com/xyz/tests/**, then source files - * like /Project/src/com/xyz/Foo.java - * and /Project/src/com/xyz/utils/Bar.java would be included, - * whereas /Project/src/com/xyz/tests/T1.java - * and /Project/src/com/xyz/tests/quick/T2.java would be - * excluded. Exclusion patterns can contain can contain '**', '*' or '?' - * wildcards; see IClasspathEntry.getExclusionPatterns - * for the full description of the syntax and semantics of exclusion - * patterns. - *

    - * If the empty list of exclusion patterns is specified, the source folder - * will automatically include all resources located inside the source - * folder. In that case, the result is entirely equivalent to using the - * factory method JavaCore.newSourceEntry(IPath). - *

    - *

    - * Note that all sources/binaries inside a project are contributed as a whole through - * a project entry (see JavaCore.newProjectEntry). Particular - * source entries cannot be selectively exported. - *

    - * - * @param path the absolute workspace-relative path of a source folder - * @param exclusionPatterns the possibly empty list of exclusion patterns - * represented as relative paths - * @return a new source classpath entry with the given exclusion patterns - * @see #newSourceEntry(org.eclipse.core.runtime.IPath) - * @see IClasspathEntry#getExclusionPatterns - * - * @since 2.1 - */ -// public static IClasspathEntry newSourceEntry(IPath path, IPath[] exclusionPatterns) { -// -// return newSourceEntry(path, exclusionPatterns, null /*output location*/); -// } - - /** - * Creates and returns a new classpath entry of kind CPE_SOURCE - * for the project's source folder identified by the given absolute - * workspace-relative path but excluding all source files with paths - * matching any of the given patterns, and associated with a specific output location - * (that is, ".class" files are not going to the project default output location). - * All package fragments within the root will have children of type - * ICompilationUnit. - *

    - * The source folder is referred to using an absolute path relative to the - * workspace root, e.g. /Project/src. A project's source - * folders are located with that project. That is, a source classpath - * entry specifying the path /P1/src is only usable for - * project P1. - *

    - *

    - * The source classpath entry created by this method includes all source - * files below the given workspace-relative path except for those matched - * by one (or more) of the given exclusion patterns. Each exclusion pattern - * is represented by a relative path, which is interpreted as relative to - * the source folder. For example, if the source folder path is - * /Project/src and the exclusion pattern is - * com/xyz/tests/**, then source files - * like /Project/src/com/xyz/Foo.java - * and /Project/src/com/xyz/utils/Bar.java would be included, - * whereas /Project/src/com/xyz/tests/T1.java - * and /Project/src/com/xyz/tests/quick/T2.java would be - * excluded. Exclusion patterns can contain can contain '**', '*' or '?' - * wildcards; see IClasspathEntry.getExclusionPatterns - * for the full description of the syntax and semantics of exclusion - * patterns. - *

    - * If the empty list of exclusion patterns is specified, the source folder - * will automatically include all resources located inside the source - * folder. In that case, the result is entirely equivalent to using the - * factory method JavaCore.newSourceEntry(IPath). - *

    - *

    - * Additionally, a source entry can be associated with a specific output location. - * By doing so, the Java builder will ensure that the generated ".class" files will - * be issued inside this output location, as opposed to be generated into the - * project default output location (when output location is null). - * Note that multiple source entries may target the same output location. - * The output location is referred to using an absolute path relative to the - * workspace root, e.g. "/Project/bin", it must be located inside - * the same project as the source folder. - *

    - *

    - * Also note that all sources/binaries inside a project are contributed as a whole through - * a project entry (see JavaCore.newProjectEntry). Particular - * source entries cannot be selectively exported. - *

    - * - * @param path the absolute workspace-relative path of a source folder - * @param exclusionPatterns the possibly empty list of exclusion patterns - * represented as relative paths - * @param outputLocation the specific output location for this source entry (null if using project default ouput location) - * @return a new source classpath entry with the given exclusion patterns - * @see #newSourceEntry(org.eclipse.core.runtime.IPath) - * @see IClasspathEntry#getExclusionPatterns - * @see IClasspathEntry#getOutputLocation() - * - * @since 2.1 - */ -// public static IClasspathEntry newSourceEntry(IPath path, IPath[] exclusionPatterns, IPath specificOutputLocation) { -// -// if (!path.isAbsolute()) Assert.isTrue(false, "Path for IClasspathEntry must be absolute"); //$NON-NLS-1$ -// if (exclusionPatterns == null) Assert.isTrue(false, "Exclusion pattern set cannot be null"); //$NON-NLS-1$ -// -// return new ClasspathEntry( -// IPackageFragmentRoot.K_SOURCE, -// IClasspathEntry.CPE_SOURCE, -// path, -// exclusionPatterns, -// null, // source attachment -// null, // source attachment root -// specificOutputLocation, // custom output location -// false); -// } - - /** - * Creates and returns a new non-exported classpath entry of kind CPE_VARIABLE - * for the given path. The first segment of the path is the name of a classpath variable. - * The trailing segments of the path will be appended to resolved variable path. - *

    - * A variable entry allows to express indirect references on a classpath to other projects or libraries, - * depending on what the classpath variable is referring. - *

    - * It is possible to register an automatic initializer (ClasspathVariableInitializer), - * which will be invoked through the extension point "org.eclipse.jdt.core.classpathVariableInitializer". - * After resolution, a classpath variable entry may either correspond to a project or a library entry.

  • - *

    - * e.g. Here are some examples of variable path usage

      - *
    • "JDTCORE" where variable JDTCORE is - * bound to "c:/jars/jdtcore.jar". The resolved classpath entry is denoting the library "c:\jars\jdtcore.jar"
    • - *
    • "JDTCORE" where variable JDTCORE is - * bound to "/Project_JDTCORE". The resolved classpath entry is denoting the project "/Project_JDTCORE"
    • - *
    • "PLUGINS/com.example/example.jar" where variable PLUGINS - * is bound to "c:/eclipse/plugins". The resolved classpath entry is denoting the library "c:/eclipse/plugins/com.example/example.jar"
    • - *
    - * Note that this operation does not attempt to validate classpath variables - * or access the resources at the given paths. - *

    - * The resulting entry is not exported to dependent projects. This method is equivalent to - * newVariableEntry(-,-,-,false). - *

    - * - * @param variablePath the path of the binary archive; first segment is the - * name of a classpath variable - * @param variableSourceAttachmentPath the path of the corresponding source archive, - * or null if none; if present, the first segment is the - * name of a classpath variable (not necessarily the same variable - * as the one that begins variablePath) - * @param sourceAttachmentRootPath the location of the root within the source archive - * or null if archivePath is also null - * @return a new library classpath entry - * - * @see JavaCore#newVariableEntry(IPath, IPath, IPath, boolean) - */ -// public static IClasspathEntry newVariableEntry( -// IPath variablePath, -// IPath variableSourceAttachmentPath, -// IPath sourceAttachmentRootPath) { -// -// return newVariableEntry(variablePath, variableSourceAttachmentPath, sourceAttachmentRootPath, false); -// } - - /** - * Creates and returns a new non-exported classpath entry of kind CPE_VARIABLE - * for the given path. The first segment of the path is the name of a classpath variable. - * The trailing segments of the path will be appended to resolved variable path. - *

    - * A variable entry allows to express indirect references on a classpath to other projects or libraries, - * depending on what the classpath variable is referring. - *

    - * It is possible to register an automatic initializer (ClasspathVariableInitializer), - * which will be invoked through the extension point "org.eclipse.jdt.core.classpathVariableInitializer". - * After resolution, a classpath variable entry may either correspond to a project or a library entry. - *

    - * e.g. Here are some examples of variable path usage

      - *
    • "JDTCORE" where variable JDTCORE is - * bound to "c:/jars/jdtcore.jar". The resolved classpath entry is denoting the library "c:\jars\jdtcore.jar"
    • - *
    • "JDTCORE" where variable JDTCORE is - * bound to "/Project_JDTCORE". The resolved classpath entry is denoting the project "/Project_JDTCORE"
    • - *
    • "PLUGINS/com.example/example.jar" where variable PLUGINS - * is bound to "c:/eclipse/plugins". The resolved classpath entry is denoting the library "c:/eclipse/plugins/com.example/example.jar"
    • - *
    - * Note that this operation does not attempt to validate classpath variables - * or access the resources at the given paths. - *

    - * - * @param variablePath the path of the binary archive; first segment is the - * name of a classpath variable - * @param variableSourceAttachmentPath the path of the corresponding source archive, - * or null if none; if present, the first segment is the - * name of a classpath variable (not necessarily the same variable - * as the one that begins variablePath) - * @param sourceAttachmentRootPath the location of the root within the source archive - * or null if archivePath is also null - * @param isExported indicates whether this entry is contributed to dependent - * projects in addition to the output location - * @return a new variable classpath entry - * @since 2.0 - */ -// public static IClasspathEntry newVariableEntry( -// IPath variablePath, -// IPath variableSourceAttachmentPath, -// IPath variableSourceAttachmentRootPath, -// boolean isExported) { -// -// if (variablePath == null || variablePath.segmentCount() < 1) { -// Assert.isTrue( -// false, -// "Illegal classpath variable path: \'" + variablePath.makeRelative().toString() + "\', must have at least one segment"); //$NON-NLS-1$//$NON-NLS-2$ -// } -// -// return new ClasspathEntry( -// IPackageFragmentRoot.K_SOURCE, -// IClasspathEntry.CPE_VARIABLE, -// variablePath, -// ClasspathEntry.NO_EXCLUSION_PATTERNS, -// variableSourceAttachmentPath, // source attachment -// variableSourceAttachmentRootPath, // source attachment root -// null, // specific output folder -// isExported); -// } - - /** - * Removed the given classpath variable. Does nothing if no value was - * set for this classpath variable. - *

    - * This functionality cannot be used while the resource tree is locked. - *

    - * Classpath variable values are persisted locally to the workspace, and - * are preserved from session to session. - *

    - * - * @param variableName the name of the classpath variable - * @see #setClasspathVariable - * - * @deprecated - use version with extra IProgressMonitor - */ -// public static void removeClasspathVariable(String variableName) { -// removeClasspathVariable(variableName, null); -// } - - /** - * Removed the given classpath variable. Does nothing if no value was - * set for this classpath variable. - *

    - * This functionality cannot be used while the resource tree is locked. - *

    - * Classpath variable values are persisted locally to the workspace, and - * are preserved from session to session. - *

    - * - * @param variableName the name of the classpath variable - * @param monitor the progress monitor to report progress - * @see #setClasspathVariable - */ -// public static void removeClasspathVariable( -// String variableName, -// IProgressMonitor monitor) { -// -// try { -// updateVariableValues(new String[]{ variableName}, new IPath[]{ null }, monitor); -// } catch (JavaModelException e) { -// } -// } - - /** - * Removes the given element changed listener. - * Has no affect if an identical listener is not registered. - * - * @param listener the listener - */ - public static void removeElementChangedListener(IElementChangedListener listener) { - JavaModelManager.getJavaModelManager().removeElementChangedListener(listener); - } - /** - * Runs the given action as an atomic Java model operation. - *

    - * After running a method that modifies Java elements, - * registered listeners receive after-the-fact notification of - * what just transpired, in the form of a element changed event. - * This method allows clients to call a number of - * methods that modify java elements and only have element - * changed event notifications reported at the end of the entire - * batch. - *

    - *

    - * If this method is called outside the dynamic scope of another such - * call, this method runs the action and then reports a single - * element changed event describing the net effect of all changes - * done to java elements by the action. - *

    - *

    - * If this method is called in the dynamic scope of another such - * call, this method simply runs the action. - *

    - * - * @param action the action to perform - * @param monitor a progress monitor, or null if progress - * reporting and cancellation are not desired - * @exception CoreException if the operation failed. - * @since 2.1 - */ - public static void run(IWorkspaceRunnable action, IProgressMonitor monitor) throws CoreException { - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - if (workspace.isTreeLocked()) { - new BatchOperation(action).run(monitor); - } else { - // use IWorkspace.run(...) to ensure that a build will be done in autobuild mode - workspace.run(new BatchOperation(action), monitor); - } - } - /** - * Bind a container reference path to some actual containers (IClasspathContainer). - * This API must be invoked whenever changes in container need to be reflected onto the JavaModel. - * Containers can have distinct values in different projects, therefore this API considers a - * set of projects with their respective containers. - *

    - * containerPath is the path under which these values can be referenced through - * container classpath entries (IClasspathEntry#CPE_CONTAINER). A container path - * is formed by a first ID segment followed with extra segments, which can be used as additional hints - * for the resolution. The container ID is used to identify a ClasspathContainerInitializer - * registered on the extension point "org.eclipse.jdt.core.classpathContainerInitializer". - *

    - * There is no assumption that each individual container value passed in argument - * (respectiveContainers) must answer the exact same path when requested - * IClasspathContainer#getPath. - * Indeed, the containerPath is just an indication for resolving it to an actual container object. It can be - * delegated to a ClasspathContainerInitializer, which can be activated through the extension - * point "org.eclipse.jdt.core.ClasspathContainerInitializer"). - *

    - * In reaction to changing container values, the JavaModel will be updated to reflect the new - * state of the updated container. - *

    - * This functionality cannot be used while the resource tree is locked. - *

    - * Classpath container values are persisted locally to the workspace, but - * are not preserved from a session to another. It is thus highly recommended to register a - * ClasspathContainerInitializer for each referenced container - * (through the extension point "org.eclipse.jdt.core.ClasspathContainerInitializer"). - *

    - * Note: setting a container to null will cause it to be lazily resolved again whenever - * its value is required. In particular, this will cause a registered initializer to be invoked - * again. - *

    - * @param containerPath - the name of the container reference, which is being updated - * @param affectedProjects - the set of projects for which this container is being bound - * @param respectiveContainers - the set of respective containers for the affected projects - * @param monitor a monitor to report progress - * - * @see ClasspathContainerInitializer - * @see #getClasspathContainer(IPath, IJavaProject) - * @see IClasspathContainer - * @since 2.0 - */ -// public static void setClasspathContainer(final IPath containerPath, IJavaProject[] affectedProjects, IClasspathContainer[] respectiveContainers, IProgressMonitor monitor) throws JavaModelException { -// -// if (affectedProjects.length != respectiveContainers.length) Assert.isTrue(false, "Projects and containers collections should have the same size"); //$NON-NLS-1$ -// -// if (monitor != null && monitor.isCanceled()) return; -// -// if (JavaModelManager.CP_RESOLVE_VERBOSE){ -// System.out.println("CPContainer SET - setting container: ["+containerPath+"] for projects: {" //$NON-NLS-1$ //$NON-NLS-2$ -// + (Util.toString(affectedProjects, -// new Util.Displayable(){ -// public String displayString(Object o) { return ((IJavaProject) o).getElementName(); } -// })) -// + "} with values: " //$NON-NLS-1$ -// + (Util.toString(respectiveContainers, -// new Util.Displayable(){ -// public String displayString(Object o) { return ((IClasspathContainer) o).getDescription(); } -// })) -// ); -// } -// -// final int projectLength = affectedProjects.length; -// final IJavaProject[] modifiedProjects; -// System.arraycopy(affectedProjects, 0, modifiedProjects = new IJavaProject[projectLength], 0, projectLength); -// final IClasspathEntry[][] oldResolvedPaths = new IClasspathEntry[projectLength][]; -// -// // filter out unmodified project containers -// int remaining = 0; -// for (int i = 0; i < projectLength; i++){ -// -// if (monitor != null && monitor.isCanceled()) return; -// -// IJavaProject affectedProject = affectedProjects[i]; -// IClasspathContainer newContainer = respectiveContainers[i]; -// if (newContainer == null) newContainer = JavaModelManager.ContainerInitializationInProgress; // 30920 - prevent infinite loop -// boolean found = false; -// if (JavaProject.hasJavaNature(affectedProject.getProject())){ -// IClasspathEntry[] rawClasspath = affectedProject.getRawClasspath(); -// for (int j = 0, cpLength = rawClasspath.length; j - * This functionality cannot be used while the resource tree is locked. - *

    - * Classpath variable values are persisted locally to the workspace, and - * are preserved from session to session. - *

    - * - * @param variableName the name of the classpath variable - * @param path the path - * @see #getClasspathVariable - * - * @deprecated - use API with IProgressMonitor - */ -// public static void setClasspathVariable(String variableName, IPath path) -// throws JavaModelException { -// -// setClasspathVariable(variableName, path, null); -// } - - /** - * Sets the value of the given classpath variable. - * The path must not be null. - *

    - * This functionality cannot be used while the resource tree is locked. - *

    - * Classpath variable values are persisted locally to the workspace, and - * are preserved from session to session. - *

    - * Updating a variable with the same value has no effect. - * - * @param variableName the name of the classpath variable - * @param path the path - * @param monitor a monitor to report progress - * @see #getClasspathVariable - */ -// public static void setClasspathVariable( -// String variableName, -// IPath path, -// IProgressMonitor monitor) -// throws JavaModelException { -// -// if (path == null) Assert.isTrue(false, "Variable path cannot be null"); //$NON-NLS-1$ -// setClasspathVariables(new String[]{variableName}, new IPath[]{ path }, monitor); -// } - - /** - * Sets the values of all the given classpath variables at once. - * Null paths can be used to request corresponding variable removal. - *

    - * This functionality cannot be used while the resource tree is locked. - *

    - * Classpath variable values are persisted locally to the workspace, and - * are preserved from session to session. - *

    - * Updating a variable with the same value has no effect. - * - * @param variableNames an array of names for the updated classpath variables - * @param paths an array of path updates for the modified classpath variables (null - * meaning that the corresponding value will be removed - * @param monitor a monitor to report progress - * @see #getClasspathVariable - * @since 2.0 - */ -// public static void setClasspathVariables( -// String[] variableNames, -// IPath[] paths, -// IProgressMonitor monitor) -// throws JavaModelException { -// -// if (variableNames.length != paths.length) Assert.isTrue(false, "Variable names and paths collections should have the same size"); //$NON-NLS-1$ -// //TODO: should check that null cannot be used as variable paths -// updateVariableValues(variableNames, paths, monitor); -// } - - /* (non-Javadoc) - * Method declared on IExecutableExtension. - * Record any necessary initialization data from the plugin. - */ - public void setInitializationData( - IConfigurationElement cfig, - String propertyName, - Object data) - throws CoreException { - } - - /** - * Sets the current table of options. All and only the options explicitly included in the given table - * are remembered; all previous option settings are forgotten, including ones not explicitly - * mentioned. - *

    - * For a complete description of the configurable options, see getDefaultOptions. - *

    - * - * @param newOptions the new options (key type: String; value type: String), - * or null to reset all options to their default values - * @see JavaCore#getDefaultOptions - */ - public static void setOptions(Hashtable newOptions) { - - // see #initializeDefaultPluginPreferences() for changing default settings - Preferences preferences = getPlugin().getPluginPreferences(); - - if (newOptions == null){ - newOptions = JavaCore.getDefaultOptions(); - } - Enumeration keys = newOptions.keys(); - while (keys.hasMoreElements()){ - String key = (String)keys.nextElement(); - if (!JavaModelManager.OptionNames.contains(key)) continue; // unrecognized option - if (key.equals(CORE_ENCODING)) continue; // skipped, contributed by resource prefs - String value = (String)newOptions.get(key); - preferences.setValue(key, value); - } - - // persist options - getPlugin().savePluginPreferences(); - } - - /** - * Shutdown the JavaCore plug-in. - *

    - * De-registers the JavaModelManager as a resource changed listener and save participant. - *

    - * @see org.eclipse.core.runtime.Plugin#shutdown() - */ - public void shutdown() { - - savePluginPreferences(); - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - workspace.removeResourceChangeListener(JavaModelManager.getJavaModelManager().deltaProcessor); - workspace.removeSaveParticipant(this); - - ((JavaModelManager) JavaModelManager.getJavaModelManager()).shutdown(); - } - - /** - * Initiate the background indexing process. - * This should be deferred after the plugin activation. - */ -// private void startIndexing() { -// -// JavaModelManager.getJavaModelManager().getIndexManager().reset(); -// } - - /** - * Startup of the JavaCore plug-in. - *

    - * Registers the JavaModelManager as a resource changed listener and save participant. - * Starts the background indexing, and restore saved classpath variable values. - *

    - * @see org.eclipse.core.runtime.Plugin#startup() - */ - public void startup() { - - JavaModelManager manager = JavaModelManager.getJavaModelManager(); - try { - manager.configurePluginDebugOptions(); - - // request state folder creation (workaround 19885) - JavaCore.getPlugin().getStateLocation(); - - // retrieve variable values - JavaCore.getPlugin().getPluginPreferences().addPropertyChangeListener(new JavaModelManager.PluginPreferencesListener()); -// TODO khartlage temp-del -// manager.loadVariablesAndContainers(); - - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - workspace.addResourceChangeListener( - manager.deltaProcessor, - IResourceChangeEvent.PRE_AUTO_BUILD - | IResourceChangeEvent.POST_AUTO_BUILD - | IResourceChangeEvent.POST_CHANGE - | IResourceChangeEvent.PRE_DELETE - | IResourceChangeEvent.PRE_CLOSE); - -// startIndexing(); - workspace.addSaveParticipant(this, manager); - - } catch (CoreException e) { - } catch (RuntimeException e) { - manager.shutdown(); - throw e; - } - } - - - /** - * Internal updating of a variable values (null path meaning removal), allowing to change multiple variable values at once. - */ -// private static void updateVariableValues( -// String[] variableNames, -// IPath[] variablePaths, -// IProgressMonitor monitor) throws JavaModelException { -// -// if (monitor != null && monitor.isCanceled()) return; -// -// if (JavaModelManager.CP_RESOLVE_VERBOSE){ -// System.out.println("CPVariable SET - setting variables: {" + Util.toString(variableNames) //$NON-NLS-1$ -// + "} with values: " + Util.toString(variablePaths)); //$NON-NLS-1$ -// } -// -// int varLength = variableNames.length; -// -// // gather classpath information for updating -// final HashMap affectedProjects = new HashMap(5); -// JavaModelManager manager = JavaModelManager.getJavaModelManager(); -// IJavaModel model = manager.getJavaModel(); -// -// // filter out unmodified variables -// int discardCount = 0; -// for (int i = 0; i < varLength; i++){ -// String variableName = variableNames[i]; -// IPath oldPath = (IPath)JavaModelManager.variableGet(variableName); // if reentering will provide previous session value -// if (oldPath == JavaModelManager.VariableInitializationInProgress){ -// IPath previousPath = (IPath)JavaModelManager.PreviousSessionVariables.get(variableName); -// if (previousPath != null){ -// if (JavaModelManager.CP_RESOLVE_VERBOSE){ -// System.out.println("CPVariable INIT - reentering access to variable: " + variableName+ " during its initialization, will see previous value: "+ previousPath); //$NON-NLS-1$ //$NON-NLS-2$ -// } -// JavaModelManager.variablePut(variableName, previousPath); // replace value so reentering calls are seeing old value -// } -// oldPath = null; //33695 - cannot filter out restored variable, must update affected project to reset cached CP -// } -// if (oldPath != null && oldPath.equals(variablePaths[i])){ -// variableNames[i] = null; -// discardCount++; -// } -// } -// if (discardCount > 0){ -// if (discardCount == varLength) return; -// int changedLength = varLength - discardCount; -// String[] changedVariableNames = new String[changedLength]; -// IPath[] changedVariablePaths = new IPath[changedLength]; -// for (int i = 0, index = 0; i < varLength; i++){ -// if (variableNames[i] != null){ -// changedVariableNames[index] = variableNames[i]; -// changedVariablePaths[index] = variablePaths[i]; -// index++; -// } -// } -// variableNames = changedVariableNames; -// variablePaths = changedVariablePaths; -// varLength = changedLength; -// } -// -// if (monitor != null && monitor.isCanceled()) return; -// -// if (model != null) { -// IJavaProject[] projects = model.getJavaProjects(); -// nextProject : for (int i = 0, projectLength = projects.length; i < projectLength; i++){ -// IJavaProject project = projects[i]; -// -// // check to see if any of the modified variables is present on the classpath -// IClasspathEntry[] classpath = project.getRawClasspath(); -// for (int j = 0, cpLength = classpath.length; j < cpLength; j++){ -// -// IClasspathEntry entry = classpath[j]; -// for (int k = 0; k < varLength; k++){ -// -// String variableName = variableNames[k]; -// if (entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE){ -// -// if (variableName.equals(entry.getPath().segment(0))){ -// affectedProjects.put(project, project.getResolvedClasspath(true)); -// continue nextProject; -// } -// IPath sourcePath, sourceRootPath; -// if (((sourcePath = entry.getSourceAttachmentPath()) != null && variableName.equals(sourcePath.segment(0))) -// || ((sourceRootPath = entry.getSourceAttachmentRootPath()) != null && variableName.equals(sourceRootPath.segment(0)))) { -// -// affectedProjects.put(project, project.getResolvedClasspath(true)); -// continue nextProject; -// } -// } -// } -// } -// } -// } -// // update variables -// for (int i = 0; i < varLength; i++){ -// JavaModelManager.variablePut(variableNames[i], variablePaths[i]); -// } -// final String[] dbgVariableNames = variableNames; -// -// // update affected project classpaths -// if (!affectedProjects.isEmpty()) { -// try { -// JavaCore.run( -// new IWorkspaceRunnable() { -// public void run(IProgressMonitor monitor) throws CoreException { -// // propagate classpath change -// Iterator projectsToUpdate = affectedProjects.keySet().iterator(); -// while (projectsToUpdate.hasNext()) { -// -// if (monitor != null && monitor.isCanceled()) return; -// -// JavaProject project = (JavaProject) projectsToUpdate.next(); -// -// if (JavaModelManager.CP_RESOLVE_VERBOSE){ -// System.out.println("CPVariable SET - updating affected project: ["+project.getElementName()+"] due to setting variables: "+ Util.toString(dbgVariableNames)); //$NON-NLS-1$ //$NON-NLS-2$ -// } -// -// project -// .setRawClasspath( -// project.getRawClasspath(), -// SetClasspathOperation.ReuseOutputLocation, -// null, // don't call beginTask on the monitor (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=3717) -// !ResourcesPlugin.getWorkspace().isTreeLocked(), // can change resources -// (IClasspathEntry[]) affectedProjects.get(project), -// false, // updating - no validation -// false); // updating - no need to save -// } -// } -// }, -// monitor); -// } catch (CoreException e) { -// if (JavaModelManager.CP_RESOLVE_VERBOSE){ -// System.out.println("CPVariable SET - FAILED DUE TO EXCEPTION: "+Util.toString(dbgVariableNames)); //$NON-NLS-1$ -// e.printStackTrace(); -// } -// if (e instanceof JavaModelException) { -// throw (JavaModelException)e; -// } else { -// throw new JavaModelException(e); -// } -// } -// } -// } -} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/JavaModelException.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/JavaModelException.java index a8d59f9..cc88627 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/JavaModelException.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/JavaModelException.java @@ -105,10 +105,10 @@ public IJavaModelStatus getJavaModelStatus() { * @see IJavaModelStatus#isDoesNotExist * @see IJavaModelStatusConstants#ELEMENT_DOES_NOT_EXIST */ -//public boolean isDoesNotExist() { -// IJavaModelStatus javaModelStatus = getJavaModelStatus(); -// return javaModelStatus != null && javaModelStatus.isDoesNotExist(); -//} +public boolean isDoesNotExist() { + IJavaModelStatus javaModelStatus = getJavaModelStatus(); + return javaModelStatus != null && javaModelStatus.isDoesNotExist(); +} /** * Returns a printable representation of this exception suitable for debugging * purposes only. diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/Signature.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/Signature.java new file mode 100644 index 0000000..97eb0fd --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/Signature.java @@ -0,0 +1,1433 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core; + +import net.sourceforge.phpdt.core.compiler.CharOperation; + +/** + * Provides methods for encoding and decoding type and method signature strings. + *

    + * The syntax for a type signature is: + *

    + * typeSignature ::=
    + *     "B"  // byte
    + *   | "C"  // char
    + *   | "D"  // double
    + *   | "F"  // float
    + *   | "I"  // int
    + *   | "J"  // long
    + *   | "S"  // short
    + *   | "V"  // void
    + *   | "Z"  // boolean
    + *   | "L" + binaryTypeName + ";"  // resolved named type (in compiled code)
    + *   | "Q" + sourceTypeName + ";"  // unresolved named type (in source code)
    + *   | "[" + typeSignature  // array of type denoted by typeSignature
    + * 
    + *

    + *

    + * Examples: + *

      + *
    • "[[I" denotes int[][]
    • + *
    • "Ljava.lang.String;" denotes java.lang.String in compiled code
    • + *
    • "QString" denotes String in source code
    • + *
    • "Qjava.lang.String" denotes java.lang.String in source code
    • + *
    • "[QString" denotes String[] in source code
    • + *
    + *

    + *

    + * The syntax for a method signature is: + *

    + * methodSignature ::= "(" + paramTypeSignature* + ")" + returnTypeSignature
    + * paramTypeSignature ::= typeSignature
    + * returnTypeSignature ::= typeSignature
    + * 
    + *

    + * Examples: + *

      + *
    • "()I" denotes int foo()
    • + *
    • "([Ljava.lang.String;)V" denotes void foo(java.lang.String[]) in compiled code
    • + *
    • "(QString;)QObject;" denotes Object foo(String) in source code
    • + *
    + *

    + *

    + * This class provides static methods and constants only; it is not intended to be + * instantiated or subclassed by clients. + *

    + */ +public final class Signature { + + /** + * Character constant indicating the primitive type boolean in a signature. + * Value is 'Z'. + */ + public static final char C_BOOLEAN = 'Z'; + + /** + * Character constant indicating the primitive type byte in a signature. + * Value is 'B'. + */ + public static final char C_BYTE = 'B'; + + /** + * Character constant indicating the primitive type char in a signature. + * Value is 'C'. + */ + public static final char C_CHAR = 'C'; + + /** + * Character constant indicating the primitive type double in a signature. + * Value is 'D'. + */ + public static final char C_DOUBLE = 'D'; + + /** + * Character constant indicating the primitive type float in a signature. + * Value is 'F'. + */ + public static final char C_FLOAT = 'F'; + + /** + * Character constant indicating the primitive type int in a signature. + * Value is 'I'. + */ + public static final char C_INT = 'I'; + + /** + * Character constant indicating the semicolon in a signature. + * Value is ';'. + */ + public static final char C_SEMICOLON = ';'; + + /** + * Character constant indicating the primitive type long in a signature. + * Value is 'J'. + */ + public static final char C_LONG = 'J'; + + /** + * Character constant indicating the primitive type short in a signature. + * Value is 'S'. + */ + public static final char C_SHORT = 'S'; + + /** + * Character constant indicating result type void in a signature. + * Value is 'V'. + */ + public static final char C_VOID = 'V'; + + /** + * Character constant indicating the dot in a signature. + * Value is '.'. + */ + public static final char C_DOT = '.'; + + /** + * Character constant indicating the dollar in a signature. + * Value is '$'. + */ + public static final char C_DOLLAR = '$'; + + /** + * Character constant indicating an array type in a signature. + * Value is '['. + */ + public static final char C_ARRAY = '['; + + /** + * Character constant indicating the start of a resolved, named type in a + * signature. Value is 'L'. + */ + public static final char C_RESOLVED = 'L'; + + /** + * Character constant indicating the start of an unresolved, named type in a + * signature. Value is 'Q'. + */ + public static final char C_UNRESOLVED = 'Q'; + + /** + * Character constant indicating the end of a named type in a signature. + * Value is ';'. + */ + public static final char C_NAME_END = ';'; + + /** + * Character constant indicating the start of a parameter type list in a + * signature. Value is '('. + */ + public static final char C_PARAM_START = '('; + + /** + * Character constant indicating the end of a parameter type list in a + * signature. Value is ')'. + */ + public static final char C_PARAM_END = ')'; + + /** + * String constant for the signature of the primitive type boolean. + * Value is "Z". + */ + public static final String SIG_BOOLEAN = "Z"; //$NON-NLS-1$ + + /** + * String constant for the signature of the primitive type byte. + * Value is "B". + */ + public static final String SIG_BYTE = "B"; //$NON-NLS-1$ + + /** + * String constant for the signature of the primitive type char. + * Value is "C". + */ + public static final String SIG_CHAR = "C"; //$NON-NLS-1$ + + /** + * String constant for the signature of the primitive type double. + * Value is "D". + */ + public static final String SIG_DOUBLE = "D"; //$NON-NLS-1$ + + /** + * String constant for the signature of the primitive type float. + * Value is "F". + */ + public static final String SIG_FLOAT = "F"; //$NON-NLS-1$ + + /** + * String constant for the signature of the primitive type int. + * Value is "I". + */ + public static final String SIG_INT = "I"; //$NON-NLS-1$ + + /** + * String constant for the signature of the primitive type long. + * Value is "J". + */ + public static final String SIG_LONG = "J"; //$NON-NLS-1$ + + /** + * String constant for the signature of the primitive type short. + * Value is "S". + */ + public static final String SIG_SHORT = "S"; //$NON-NLS-1$ + + /** String constant for the signature of result type void. + * Value is "V". + */ + public static final String SIG_VOID = "V"; //$NON-NLS-1$ + + private static final char[] BOOLEAN = {'b', 'o', 'o', 'l', 'e', 'a', 'n'}; + private static final char[] BYTE = {'b', 'y', 't', 'e'}; + private static final char[] CHAR = {'c', 'h', 'a', 'r'}; + private static final char[] DOUBLE = {'d', 'o', 'u', 'b', 'l', 'e'}; + private static final char[] FLOAT = {'f', 'l', 'o', 'a', 't'}; + private static final char[] INT = {'i', 'n', 't'}; + private static final char[] LONG = {'l', 'o', 'n', 'g'}; + private static final char[] SHORT = {'s', 'h', 'o', 'r', 't'}; + private static final char[] VOID = {'v', 'o', 'i', 'd'}; + + private static final String EMPTY = new String(CharOperation.NO_CHAR); + +/** + * Not instantiable. + */ +private Signature() {} + +private static long copyType(char[] signature, int sigPos, char[] dest, int index, boolean fullyQualifyTypeNames) { + int arrayCount = 0; + loop: while (true) { + switch (signature[sigPos++]) { + case C_ARRAY : + arrayCount++; + break; + case C_BOOLEAN : + int length = BOOLEAN.length; + System.arraycopy(BOOLEAN, 0, dest, index, length); + index += length; + break loop; + case C_BYTE : + length = BYTE.length; + System.arraycopy(BYTE, 0, dest, index, length); + index += length; + break loop; + case C_CHAR : + length = CHAR.length; + System.arraycopy(CHAR, 0, dest, index, length); + index += length; + break loop; + case C_DOUBLE : + length = DOUBLE.length; + System.arraycopy(DOUBLE, 0, dest, index, length); + index += length; + break loop; + case C_FLOAT : + length = FLOAT.length; + System.arraycopy(FLOAT, 0, dest, index, length); + index += length; + break loop; + case C_INT : + length = INT.length; + System.arraycopy(INT, 0, dest, index, length); + index += length; + break loop; + case C_LONG : + length = LONG.length; + System.arraycopy(LONG, 0, dest, index, length); + index += length; + break loop; + case C_SHORT : + length = SHORT.length; + System.arraycopy(SHORT, 0, dest, index, length); + index += length; + break loop; + case C_VOID : + length = VOID.length; + System.arraycopy(VOID, 0, dest, index, length); + index += length; + break loop; + case C_RESOLVED : + case C_UNRESOLVED : + int end = CharOperation.indexOf(C_SEMICOLON, signature, sigPos); + if (end == -1) throw new IllegalArgumentException(); + int start; + if (fullyQualifyTypeNames) { + start = sigPos; + } else { + start = CharOperation.lastIndexOf(C_DOT, signature, sigPos, end)+1; + if (start == 0) start = sigPos; + } + length = end-start; + System.arraycopy(signature, start, dest, index, length); + sigPos = end+1; + index += length; + break loop; + } + } + while (arrayCount-- > 0) { + dest[index++] = '['; + dest[index++] = ']'; + } + return (((long) index) << 32) + sigPos; +} +/** + * Creates a new type signature with the given amount of array nesting added + * to the given type signature. + * + * @param typeSignature the type signature + * @param arrayCount the desired number of levels of array nesting + * @return the encoded array type signature + * + * @since 2.0 + */ +public static char[] createArraySignature(char[] typeSignature, int arrayCount) { + if (arrayCount == 0) return typeSignature; + int sigLength = typeSignature.length; + char[] result = new char[arrayCount + sigLength]; + for (int i = 0; i < arrayCount; i++) { + result[i] = C_ARRAY; + } + System.arraycopy(typeSignature, 0, result, arrayCount, sigLength); + return result; +} +/** + * Creates a new type signature with the given amount of array nesting added + * to the given type signature. + * + * @param typeSignature the type signature + * @param arrayCount the desired number of levels of array nesting + * @return the encoded array type signature + */ +public static String createArraySignature(String typeSignature, int arrayCount) { + return new String(createArraySignature(typeSignature.toCharArray(), arrayCount)); +} +/** + * Creates a method signature from the given parameter and return type + * signatures. The encoded method signature is dot-based. + * + * @param parameterTypes the list of parameter type signatures + * @param returnType the return type signature + * @return the encoded method signature + * + * @since 2.0 + */ +public static char[] createMethodSignature(char[][] parameterTypes, char[] returnType) { + int parameterTypesLength = parameterTypes.length; + int parameterLength = 0; + for (int i = 0; i < parameterTypesLength; i++) { + parameterLength += parameterTypes[i].length; + + } + int returnTypeLength = returnType.length; + char[] result = new char[1 + parameterLength + 1 + returnTypeLength]; + result[0] = C_PARAM_START; + int index = 1; + for (int i = 0; i < parameterTypesLength; i++) { + char[] parameterType = parameterTypes[i]; + int length = parameterType.length; + System.arraycopy(parameterType, 0, result, index, length); + index += length; + } + result[index] = C_PARAM_END; + System.arraycopy(returnType, 0, result, index+1, returnTypeLength); + return result; +} +/** + * Creates a method signature from the given parameter and return type + * signatures. The encoded method signature is dot-based. + * + * @param parameterTypes the list of parameter type signatures + * @param returnType the return type signature + * @return the encoded method signature + */ +public static String createMethodSignature(String[] parameterTypes, String returnType) { + int parameterTypesLenth = parameterTypes.length; + char[][] parameters = new char[parameterTypesLenth][]; + for (int i = 0; i < parameterTypesLenth; i++) { + parameters[i] = parameterTypes[i].toCharArray(); + } + return new String(createMethodSignature(parameters, returnType.toCharArray())); +} +/** + * Creates a new type signature from the given type name encoded as a character + * array. This method is equivalent to + * createTypeSignature(new String(typeName),isResolved), although + * more efficient for callers with character arrays rather than strings. If the + * type name is qualified, then it is expected to be dot-based. + * + * @param typeName the possibly qualified type name + * @param isResolved true if the type name is to be considered + * resolved (for example, a type name from a binary class file), and + * false if the type name is to be considered unresolved + * (for example, a type name found in source code) + * @return the encoded type signature + * @see #createTypeSignature(java.lang.String,boolean) + */ +public static String createTypeSignature(char[] typeName, boolean isResolved) { + return new String(createCharArrayTypeSignature(typeName, isResolved)); +} +/** + * Creates a new type signature from the given type name encoded as a character + * array. This method is equivalent to + * createTypeSignature(new String(typeName),isResolved).toCharArray(), although + * more efficient for callers with character arrays rather than strings. If the + * type name is qualified, then it is expected to be dot-based. + * + * @param typeName the possibly qualified type name + * @param isResolved true if the type name is to be considered + * resolved (for example, a type name from a binary class file), and + * false if the type name is to be considered unresolved + * (for example, a type name found in source code) + * @return the encoded type signature + * @see #createTypeSignature(java.lang.String,boolean) + * + * @since 2.0 + */ +public static char[] createCharArrayTypeSignature(char[] typeName, boolean isResolved) { + + if (typeName == null) throw new IllegalArgumentException("null"); //$NON-NLS-1$ + int length = typeName.length; + if (length == 0) throw new IllegalArgumentException(new String(typeName)); + + int arrayCount = CharOperation.occurencesOf('[', typeName); + char[] sig; + + switch (typeName[0]) { + // primitive type? + case 'b' : + if (CharOperation.fragmentEquals(BOOLEAN, typeName, 0, true)) { + sig = new char[arrayCount+1]; + sig[arrayCount] = C_BOOLEAN; + break; + } else if (CharOperation.fragmentEquals(BYTE, typeName, 0, true)) { + sig = new char[arrayCount+1]; + sig[arrayCount] = C_BYTE; + break; + } + case 'c': + if (CharOperation.fragmentEquals(CHAR, typeName, 0, true)) { + sig = new char[arrayCount+1]; + sig[arrayCount] = C_CHAR; + break; + } + case 'd': + if (CharOperation.fragmentEquals(DOUBLE, typeName, 0, true)) { + sig = new char[arrayCount+1]; + sig[arrayCount] = C_DOUBLE; + break; + } + case 'f': + if (CharOperation.fragmentEquals(FLOAT, typeName, 0, true)) { + sig = new char[arrayCount+1]; + sig[arrayCount] = C_FLOAT; + break; + } + case 'i': + if (CharOperation.fragmentEquals(INT, typeName, 0, true)) { + sig = new char[arrayCount+1]; + sig[arrayCount] = C_INT; + break; + } + case 'l': + if (CharOperation.fragmentEquals(LONG, typeName, 0, true)) { + sig = new char[arrayCount+1]; + sig[arrayCount] = C_LONG; + break; + } + case 's': + if (CharOperation.fragmentEquals(SHORT, typeName, 0, true)) { + sig = new char[arrayCount+1]; + sig[arrayCount] = C_SHORT; + break; + } + case 'v': + if (CharOperation.fragmentEquals(VOID, typeName, 0, true)) { + sig = new char[arrayCount+1]; + sig[arrayCount] = C_VOID; + break; + } + default: + // non primitive type + int sigLength = arrayCount + 1 + length + 1; // for example '[[[Ljava.lang.String;' + sig = new char[sigLength]; + int sigIndex = arrayCount+1; // index in sig + int startID = 0; // start of current ID in typeName + int index = 0; // index in typeName + while (index < length) { + char currentChar = typeName[index]; + switch (currentChar) { + case '.': + if (startID == -1) throw new IllegalArgumentException(new String(typeName)); + if (startID < index) { + sig = CharOperation.append(sig, sigIndex, typeName, startID, index); + sigIndex += index-startID; + } + sig[sigIndex++] = C_DOT; + index++; + startID = index; + break; + case '[': + if (startID != -1) { + if (startID < index) { + sig = CharOperation.append(sig, sigIndex, typeName, startID, index); + sigIndex += index-startID; + } + startID = -1; // no more id after [] + } + index++; + break; + default : + if (startID != -1 && CharOperation.isWhitespace(currentChar)) { + if (startID < index) { + sig = CharOperation.append(sig, sigIndex, typeName, startID, index); + sigIndex += index-startID; + } + startID = index+1; + } + index++; + break; + } + } + // last id + if (startID != -1 && startID < index) { + sig = CharOperation.append(sig, sigIndex, typeName, startID, index); + sigIndex += index-startID; + } + + // add L (or Q) at the beigininig and ; at the end + sig[arrayCount] = isResolved ? C_RESOLVED : C_UNRESOLVED; + sig[sigIndex++] = C_NAME_END; + + // resize if needed + if (sigLength > sigIndex) { + System.arraycopy(sig, 0, sig = new char[sigIndex], 0, sigIndex); + } + } + + // add array info + for (int i = 0; i < arrayCount; i++) { + sig[i] = C_ARRAY; + } + + return sig; +} +/** + * Creates a new type signature from the given type name. If the type name is qualified, + * then it is expected to be dot-based. + *

    + * For example: + *

    + * 
    + * createTypeSignature("int", hucairz) -> "I"
    + * createTypeSignature("java.lang.String", true) -> "Ljava.lang.String;"
    + * createTypeSignature("String", false) -> "QString;"
    + * createTypeSignature("java.lang.String", false) -> "Qjava.lang.String;"
    + * createTypeSignature("int []", false) -> "[I"
    + * 
    + * 
    + *

    + * + * @param typeName the possibly qualified type name + * @param isResolved true if the type name is to be considered + * resolved (for example, a type name from a binary class file), and + * false if the type name is to be considered unresolved + * (for example, a type name found in source code) + * @return the encoded type signature + */ +public static String createTypeSignature(String typeName, boolean isResolved) { + return createTypeSignature(typeName == null ? null : typeName.toCharArray(), isResolved); +} +/** + * Returns the array count (array nesting depth) of the given type signature. + * + * @param typeSignature the type signature + * @return the array nesting depth, or 0 if not an array + * @exception IllegalArgumentException if the signature is not syntactically + * correct + * + * @since 2.0 + */ +public static int getArrayCount(char[] typeSignature) throws IllegalArgumentException { + try { + int count = 0; + while (typeSignature[count] == C_ARRAY) { + ++count; + } + return count; + } catch (ArrayIndexOutOfBoundsException e) { // signature is syntactically incorrect if last character is C_ARRAY + throw new IllegalArgumentException(); + } +} +/** + * Returns the array count (array nesting depth) of the given type signature. + * + * @param typeSignature the type signature + * @return the array nesting depth, or 0 if not an array + * @exception IllegalArgumentException if the signature is not syntactically + * correct + */ +public static int getArrayCount(String typeSignature) throws IllegalArgumentException { + return getArrayCount(typeSignature.toCharArray()); +} +/** + * Returns the type signature without any array nesting. + *

    + * For example: + *

    + * 
    + * getElementType({'[', '[', 'I'}) --> {'I'}.
    + * 
    + * 
    + *

    + * + * @param typeSignature the type signature + * @return the type signature without arrays + * @exception IllegalArgumentException if the signature is not syntactically + * correct + * + * @since 2.0 + */ +public static char[] getElementType(char[] typeSignature) throws IllegalArgumentException { + int count = getArrayCount(typeSignature); + if (count == 0) return typeSignature; + int length = typeSignature.length; + char[] result = new char[length-count]; + System.arraycopy(typeSignature, count, result, 0, length-count); + return result; +} +/** + * Returns the type signature without any array nesting. + *

    + * For example: + *

    + * 
    + * getElementType("[[I") --> "I".
    + * 
    + * 
    + *

    + * + * @param typeSignature the type signature + * @return the type signature without arrays + * @exception IllegalArgumentException if the signature is not syntactically + * correct + */ +public static String getElementType(String typeSignature) throws IllegalArgumentException { + return new String(getElementType(typeSignature.toCharArray())); +} +/** + * Returns the number of parameter types in the given method signature. + * + * @param methodSignature the method signature + * @return the number of parameters + * @exception IllegalArgumentException if the signature is not syntactically + * correct + * @since 2.0 + */ +public static int getParameterCount(char[] methodSignature) throws IllegalArgumentException { + try { + int count = 0; + int i = CharOperation.indexOf(C_PARAM_START, methodSignature) + 1; + if (i == 0) + throw new IllegalArgumentException(); + for (;;) { + char c = methodSignature[i++]; + switch (c) { + case C_ARRAY : + break; + case C_BOOLEAN : + case C_BYTE : + case C_CHAR : + case C_DOUBLE : + case C_FLOAT : + case C_INT : + case C_LONG : + case C_SHORT : + case C_VOID : + ++count; + break; + case C_RESOLVED : + case C_UNRESOLVED : + i = CharOperation.indexOf(C_SEMICOLON, methodSignature, i) + 1; + if (i == 0) + throw new IllegalArgumentException(); + ++count; + break; + case C_PARAM_END : + return count; + default : + throw new IllegalArgumentException(); + } + } + } catch (ArrayIndexOutOfBoundsException e) { + throw new IllegalArgumentException(); + } +} +/** + * Returns the number of parameter types in the given method signature. + * + * @param methodSignature the method signature + * @return the number of parameters + * @exception IllegalArgumentException if the signature is not syntactically + * correct + */ +public static int getParameterCount(String methodSignature) throws IllegalArgumentException { + return getParameterCount(methodSignature.toCharArray()); +} +/** + * Extracts the parameter type signatures from the given method signature. + * The method signature is expected to be dot-based. + * + * @param methodSignature the method signature + * @return the list of parameter type signatures + * @exception IllegalArgumentException if the signature is syntactically + * incorrect + * + * @since 2.0 + */ +public static char[][] getParameterTypes(char[] methodSignature) throws IllegalArgumentException { + try { + int count = getParameterCount(methodSignature); + char[][] result = new char[count][]; + if (count == 0) + return result; + int i = CharOperation.indexOf(C_PARAM_START, methodSignature) + 1; + count = 0; + int start = i; + for (;;) { + char c = methodSignature[i++]; + switch (c) { + case C_ARRAY : + // array depth is i - start; + break; + case C_BOOLEAN : + case C_BYTE : + case C_CHAR : + case C_DOUBLE : + case C_FLOAT : + case C_INT : + case C_LONG : + case C_SHORT : + case C_VOID : + // common case of base types + if (i - start == 1) { + switch (c) { + case C_BOOLEAN : + result[count++] = new char[] {C_BOOLEAN}; + break; + case C_BYTE : + result[count++] = new char[] {C_BYTE}; + break; + case C_CHAR : + result[count++] = new char[] {C_CHAR}; + break; + case C_DOUBLE : + result[count++] = new char[] {C_DOUBLE}; + break; + case C_FLOAT : + result[count++] = new char[] {C_FLOAT}; + break; + case C_INT : + result[count++] = new char[] {C_INT}; + break; + case C_LONG : + result[count++] = new char[] {C_LONG}; + break; + case C_SHORT : + result[count++] = new char[] {C_SHORT}; + break; + case C_VOID : + result[count++] = new char[] {C_VOID}; + break; + } + } else { + result[count++] = CharOperation.subarray(methodSignature, start, i); + } + start = i; + break; + case C_RESOLVED : + case C_UNRESOLVED : + i = CharOperation.indexOf(C_SEMICOLON, methodSignature, i) + 1; + if (i == 0) + throw new IllegalArgumentException(); + result[count++] = CharOperation.subarray(methodSignature, start, i); + start = i; + break; + case C_PARAM_END: + return result; + default : + throw new IllegalArgumentException(); + } + } + } catch (ArrayIndexOutOfBoundsException e) { + throw new IllegalArgumentException(); + } +} +/** + * Extracts the parameter type signatures from the given method signature. + * The method signature is expected to be dot-based. + * + * @param methodSignature the method signature + * @return the list of parameter type signatures + * @exception IllegalArgumentException if the signature is syntactically + * incorrect + */ +public static String[] getParameterTypes(String methodSignature) throws IllegalArgumentException { + char[][] parameterTypes = getParameterTypes(methodSignature.toCharArray()); + int length = parameterTypes.length; + String[] result = new String[length]; + for (int i = 0; i < length; i++) { + result[i] = new String(parameterTypes[i]); + } + return result; +} +/** + * Returns a char array containing all but the last segment of the given + * dot-separated qualified name. Returns the empty char array if it is not qualified. + *

    + * For example: + *

    + * 
    + * getQualifier({'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'O', 'b', 'j', 'e', 'c', 't'}) -> {'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g'}
    + * getQualifier({'O', 'u', 't', 'e', 'r', '.', 'I', 'n', 'n', 'e', 'r'}) -> {'O', 'u', 't', 'e', 'r'}
    + * 
    + * 
    + *

    + * + * @param name the name + * @return the qualifier prefix, or the empty char array if the name contains no + * dots + * @exception NullPointerException if name is null + * @since 2.0 + */ +public static char[] getQualifier(char[] name) { + int lastDot = CharOperation.lastIndexOf(C_DOT, name); + if (lastDot == -1) { + return CharOperation.NO_CHAR; + } + return CharOperation.subarray(name, 0, lastDot); +} +/** + * Returns a string containing all but the last segment of the given + * dot-separated qualified name. Returns the empty string if it is not qualified. + *

    + * For example: + *

    + * 
    + * getQualifier("java.lang.Object") -> "java.lang"
    + * getQualifier("Outer.Inner") -> "Outer"
    + * 
    + * 
    + *

    + * + * @param name the name + * @return the qualifier prefix, or the empty string if the name contains no + * dots + * @exception NullPointerException if name is null + */ +public static String getQualifier(String name) { + int lastDot = name.lastIndexOf(C_DOT); + if (lastDot == -1) { + return EMPTY; + } + return name.substring(0, lastDot); +} +/** + * Extracts the return type from the given method signature. The method signature is + * expected to be dot-based. + * + * @param methodSignature the method signature + * @return the type signature of the return type + * @exception IllegalArgumentException if the signature is syntactically + * incorrect + * + * @since 2.0 + */ +public static char[] getReturnType(char[] methodSignature) throws IllegalArgumentException { + int i = CharOperation.lastIndexOf(C_PARAM_END, methodSignature); + if (i == -1) { + throw new IllegalArgumentException(); + } + return CharOperation.subarray(methodSignature, i + 1, methodSignature.length); +} +/** + * Extracts the return type from the given method signature. The method signature is + * expected to be dot-based. + * + * @param methodSignature the method signature + * @return the type signature of the return type + * @exception IllegalArgumentException if the signature is syntactically + * incorrect + */ +public static String getReturnType(String methodSignature) throws IllegalArgumentException { + return new String(getReturnType(methodSignature.toCharArray())); +} +/** + * Returns the last segment of the given dot-separated qualified name. + * Returns the given name if it is not qualified. + *

    + * For example: + *

    + * 
    + * getSimpleName({'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'O', 'b', 'j', 'e', 'c', 't'}) -> {'O', 'b', 'j', 'e', 'c', 't'}
    + * 
    + * 
    + *

    + * + * @param name the name + * @return the last segment of the qualified name + * @exception NullPointerException if name is null + * @since 2.0 + */ +public static char[] getSimpleName(char[] name) { + int lastDot = CharOperation.lastIndexOf(C_DOT, name); + if (lastDot == -1) { + return name; + } + return CharOperation.subarray(name, lastDot + 1, name.length); +} +/** + * Returns the last segment of the given dot-separated qualified name. + * Returns the given name if it is not qualified. + *

    + * For example: + *

    + * 
    + * getSimpleName("java.lang.Object") -> "Object"
    + * 
    + * 
    + *

    + * + * @param name the name + * @return the last segment of the qualified name + * @exception NullPointerException if name is null + */ +public static String getSimpleName(String name) { + int lastDot = name.lastIndexOf(C_DOT); + if (lastDot == -1) { + return name; + } + return name.substring(lastDot + 1, name.length()); +} +/** + * Returns all segments of the given dot-separated qualified name. + * Returns an array with only the given name if it is not qualified. + * Returns an empty array if the name is empty. + *

    + * For example: + *

    + * 
    + * getSimpleNames({'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'O', 'b', 'j', 'e', 'c', 't'}) -> {{'j', 'a', 'v', 'a'}, {'l', 'a', 'n', 'g'}, {'O', 'b', 'j', 'e', 'c', 't'}}
    + * getSimpleNames({'O', 'b', 'j', 'e', 'c', 't'}) -> {{'O', 'b', 'j', 'e', 'c', 't'}}
    + * getSimpleNames("") -> {}
    + * 
    + * 
    + * + * @param name the name + * @return the list of simple names, possibly empty + * @exception NullPointerException if name is null + * @since 2.0 + */ +public static char[][] getSimpleNames(char[] name) { + if (name.length == 0) { + return CharOperation.NO_CHAR_CHAR; + } + int dot = CharOperation.indexOf(C_DOT, name); + if (dot == -1) { + return new char[][] {name}; + } + int n = 1; + while ((dot = CharOperation.indexOf(C_DOT, name, dot + 1)) != -1) { + ++n; + } + char[][] result = new char[n + 1][]; + int segStart = 0; + for (int i = 0; i < n; ++i) { + dot = CharOperation.indexOf(C_DOT, name, segStart); + result[i] = CharOperation.subarray(name, segStart, dot); + segStart = dot + 1; + } + result[n] = CharOperation.subarray(name, segStart, name.length); + return result; +} +/** + * Returns all segments of the given dot-separated qualified name. + * Returns an array with only the given name if it is not qualified. + * Returns an empty array if the name is empty. + *

    + * For example: + *

    + * 
    + * getSimpleNames("java.lang.Object") -> {"java", "lang", "Object"}
    + * getSimpleNames("Object") -> {"Object"}
    + * getSimpleNames("") -> {}
    + * 
    + * 
    + * + * @param name the name + * @return the list of simple names, possibly empty + * @exception NullPointerException if name is null + */ +public static String[] getSimpleNames(String name) { + char[][] simpleNames = getSimpleNames(name.toCharArray()); + int length = simpleNames.length; + String[] result = new String[length]; + for (int i = 0; i < length; i++) { + result[i] = new String(simpleNames[i]); + } + return result; +} +/** + * Converts the given method signature to a readable form. The method signature is expected to + * be dot-based. + *

    + * For example: + *

    + * 
    + * toString("([Ljava.lang.String;)V", "main", new String[] {"args"}, false, true) -> "void main(String[] args)"
    + * 
    + * 
    + *

    + * + * @param methodSignature the method signature to convert + * @param methodName the name of the method to insert in the result, or + * null if no method name is to be included + * @param parameterNames the parameter names to insert in the result, or + * null if no parameter names are to be included; if supplied, + * the number of parameter names must match that of the method signature + * @param fullyQualifyTypeNames true if type names should be fully + * qualified, and false to use only simple names + * @param includeReturnType true if the return type is to be + * included + * @return the char array representation of the method signature + * + * @since 2.0 + */ +public static char[] toCharArray(char[] methodSignature, char[] methodName, char[][] parameterNames, boolean fullyQualifyTypeNames, boolean includeReturnType) { + try { + int firstParen = CharOperation.indexOf(C_PARAM_START, methodSignature); + if (firstParen == -1) throw new IllegalArgumentException(); + + int sigLength = methodSignature.length; + + // compute result length + + // method signature + int paramCount = 0; + int lastParen = -1; + int resultLength = 0; + signature: for (int i = firstParen; i < sigLength; i++) { + switch (methodSignature[i]) { + case C_ARRAY : + resultLength += 2; // [] + continue signature; + case C_BOOLEAN : + resultLength += BOOLEAN.length; + break; + case C_BYTE : + resultLength += BYTE.length; + break; + case C_CHAR : + resultLength += CHAR.length; + break; + case C_DOUBLE : + resultLength += DOUBLE.length; + break; + case C_FLOAT : + resultLength += FLOAT.length; + break; + case C_INT : + resultLength += INT.length; + break; + case C_LONG : + resultLength += LONG.length; + break; + case C_SHORT : + resultLength += SHORT.length; + break; + case C_VOID : + resultLength += VOID.length; + break; + case C_RESOLVED : + case C_UNRESOLVED : + int end = CharOperation.indexOf(C_SEMICOLON, methodSignature, i); + if (end == -1) throw new IllegalArgumentException(); + int start; + if (fullyQualifyTypeNames) { + start = i+1; + } else { + start = CharOperation.lastIndexOf(C_DOT, methodSignature, i, end) + 1; + if (start == 0) start = i+1; + } + resultLength += end-start; + i = end; + break; + case C_PARAM_START : + // add space for "(" + resultLength++; + continue signature; + case C_PARAM_END : + lastParen = i; + if (includeReturnType) { + if (paramCount > 0) { + // remove space for ", " that was added with last parameter and remove space that is going to be added for ", " after return type + // and add space for ") " + resultLength -= 2; + } //else + // remove space that is going to be added for ", " after return type + // and add space for ") " + // -> noop + + // decrement param count because it is going to be added for return type + paramCount--; + continue signature; + } else { + if (paramCount > 0) { + // remove space for ", " that was added with last parameter and add space for ")" + resultLength--; + } else { + // add space for ")" + resultLength++; + } + break signature; + } + default : + throw new IllegalArgumentException(); + } + resultLength += 2; // add space for ", " + paramCount++; + } + + // parameter names + int parameterNamesLength = parameterNames == null ? 0 : parameterNames.length; + for (int i = 0; i >> 32); + result[index++] = ' '; + } + + // selector + if (methodName != null) { + System.arraycopy(methodName, 0, result, index, selectorLength); + index += selectorLength; + } + + // parameters + result[index++] = C_PARAM_START; + int sigPos = firstParen+1; + for (int i = 0; i < paramCount; i++) { + long pos = copyType(methodSignature, sigPos, result, index, fullyQualifyTypeNames); + index = (int) (pos >>> 32); + sigPos = (int)pos; + if (parameterNames != null) { + result[index++] = ' '; + char[] parameterName = parameterNames[i]; + int paramLength = parameterName.length; + System.arraycopy(parameterName, 0, result, index, paramLength); + index += paramLength; + } + if (i != paramCount-1) { + result[index++] = ','; + result[index++] = ' '; + } + } + if (sigPos >= sigLength) { + throw new IllegalArgumentException(); // should be on last paren + } + result[index++] = C_PARAM_END; + + return result; + } catch (ArrayIndexOutOfBoundsException e) { + throw new IllegalArgumentException(); + } +} +/** + * Converts the given type signature to a readable string. The signature is expected to + * be dot-based. + * + *

    + * For example: + *

    + * 
    + * toString({'[', 'L', 'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'S', 't', 'r', 'i', 'n', 'g', ';'}) -> {'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'S', 't', 'r', 'i', 'n', 'g', '[', ']'}
    + * toString({'I'}) -> {'i', 'n', 't'}
    + * 
    + * 
    + *

    + *

    + * Note: This method assumes that a type signature containing a '$' + * is an inner type signature. While this is correct in most cases, someone could + * define a non-inner type name containing a '$'. Handling this + * correctly in all cases would have required resolving the signature, which + * generally not feasible. + *

    + * + * @param signature the type signature + * @return the string representation of the type + * @exception IllegalArgumentException if the signature is not syntactically + * correct + * + * @since 2.0 + */ +public static char[] toCharArray(char[] signature) throws IllegalArgumentException { + try { + int sigLength = signature.length; + + if (sigLength == 0 || signature[0] == C_PARAM_START) { + return toCharArray(signature, CharOperation.NO_CHAR, null, true, true); + } + + // compute result length + int resultLength = 0; + int index = -1; + while (signature[++index] == C_ARRAY) { + resultLength += 2; // [] + } + switch (signature[index]) { + case C_BOOLEAN : + resultLength += BOOLEAN.length; + break; + case C_BYTE : + resultLength += BYTE.length; + break; + case C_CHAR : + resultLength += CHAR.length; + break; + case C_DOUBLE : + resultLength += DOUBLE.length; + break; + case C_FLOAT : + resultLength += FLOAT.length; + break; + case C_INT : + resultLength += INT.length; + break; + case C_LONG : + resultLength += LONG.length; + break; + case C_SHORT : + resultLength += SHORT.length; + break; + case C_VOID : + resultLength += VOID.length; + break; + case C_RESOLVED : + case C_UNRESOLVED : + int end = CharOperation.indexOf(C_SEMICOLON, signature, index); + if (end == -1) throw new IllegalArgumentException(); + int start = index + 1; + resultLength += end-start; + break; + default : + throw new IllegalArgumentException(); + } + + char[] result = new char[resultLength]; + copyType(signature, 0, result, 0, true); + + /** + * Converts '$' separated type signatures into '.' separated type signature. + * NOTE: This assumes that the type signature is an inner type signature. + * This is true in most cases, but someone can define a non-inner type + * name containing a '$'. However to tell the difference, we would have + * to resolve the signature, which cannot be done at this point. + */ + CharOperation.replace(result, C_DOLLAR, C_DOT); + + return result; + } catch (ArrayIndexOutOfBoundsException e) { + throw new IllegalArgumentException(); + } +} +/** + * Converts the given array of qualified name segments to a qualified name. + *

    + * For example: + *

    + * 
    + * toQualifiedName({{'j', 'a', 'v', 'a'}, {'l', 'a', 'n', 'g'}, {'O', 'b', 'j', 'e', 'c', 't'}}) -> {'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'O', 'b', 'j', 'e', 'c', 't'}
    + * toQualifiedName({{'O', 'b', 'j', 'e', 'c', 't'}}) -> {'O', 'b', 'j', 'e', 'c', 't'}
    + * toQualifiedName({{}}) -> {}
    + * 
    + * 
    + *

    + * + * @param segments the list of name segments, possibly empty + * @return the dot-separated qualified name, or the empty string + * + * @since 2.0 + */ +public static char[] toQualifiedName(char[][] segments) { + int length = segments.length; + if (length == 0) return CharOperation.NO_CHAR; + if (length == 1) return segments[0]; + + int resultLength = 0; + for (int i = 0; i < length; i++) { + resultLength += segments[i].length+1; + } + resultLength--; + char[] result = new char[resultLength]; + int index = 0; + for (int i = 0; i < length; i++) { + char[] segment = segments[i]; + int segmentLength = segment.length; + System.arraycopy(segment, 0, result, index, segmentLength); + index += segmentLength; + if (i != length-1) { + result[index++] = C_DOT; + } + } + return result; +} +/** + * Converts the given array of qualified name segments to a qualified name. + *

    + * For example: + *

    + * 
    + * toQualifiedName(new String[] {"java", "lang", "Object"}) -> "java.lang.Object"
    + * toQualifiedName(new String[] {"Object"}) -> "Object"
    + * toQualifiedName(new String[0]) -> ""
    + * 
    + * 
    + *

    + * + * @param segments the list of name segments, possibly empty + * @return the dot-separated qualified name, or the empty string + */ +public static String toQualifiedName(String[] segments) { + int length = segments.length; + char[][] charArrays = new char[length][]; + for (int i = 0; i < length; i++) { + charArrays[i] = segments[i].toCharArray(); + } + return new String(toQualifiedName(charArrays)); +} +/** + * Converts the given type signature to a readable string. The signature is expected to + * be dot-based. + * + *

    + * For example: + *

    + * 
    + * toString("[Ljava.lang.String;") -> "java.lang.String[]"
    + * toString("I") -> "int"
    + * 
    + * 
    + *

    + *

    + * Note: This method assumes that a type signature containing a '$' + * is an inner type signature. While this is correct in most cases, someone could + * define a non-inner type name containing a '$'. Handling this + * correctly in all cases would have required resolving the signature, which + * generally not feasible. + *

    + * + * @param signature the type signature + * @return the string representation of the type + * @exception IllegalArgumentException if the signature is not syntactically + * correct + */ +public static String toString(String signature) throws IllegalArgumentException { + return new String(toCharArray(signature.toCharArray())); +} +/** + * Converts the given method signature to a readable string. The method signature is expected to + * be dot-based. + *

    + * For example: + *

    + * 
    + * toString("([Ljava.lang.String;)V", "main", new String[] {"args"}, false, true) -> "void main(String[] args)"
    + * 
    + * 
    + *

    + * + * @param methodSignature the method signature to convert + * @param methodName the name of the method to insert in the result, or + * null if no method name is to be included + * @param parameterNames the parameter names to insert in the result, or + * null if no parameter names are to be included; if supplied, + * the number of parameter names must match that of the method signature + * @param fullyQualifyTypeNames true if type names should be fully + * qualified, and false to use only simple names + * @param includeReturnType true if the return type is to be + * included + * @return the string representation of the method signature + */ +public static String toString(String methodSignature, String methodName, String[] parameterNames, boolean fullyQualifyTypeNames, boolean includeReturnType) { + char[][] params; + if (parameterNames == null) { + params = null; + } else { + int paramLength = parameterNames.length; + params = new char[paramLength][]; + for (int i = 0; i < paramLength; i++) { + params[i] = parameterNames[i].toCharArray(); + } + } + return new String(toCharArray(methodSignature.toCharArray(), methodName == null ? null : methodName.toCharArray(), params, fullyQualifyTypeNames, includeReturnType)); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/compiler/IProblem.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/compiler/IProblem.java deleted file mode 100644 index 903396b..0000000 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/compiler/IProblem.java +++ /dev/null @@ -1,519 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2002 IBM Corp. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * IBM Corporation - added the following constants - * NonStaticAccessToStaticField - * NonStaticAccessToStaticMethod - * Task - * NoOpAssignment - * IBM Corporation - added the following constants - * TooManySyntheticArgumentSlots - * TooManyArrayDimensions - * TooManyBytesForStringConstant - * TooManyMethods - * TooManyFields - * NonBlankFinalLocalAssignment - * ObjectCannotHaveSuperTypes - * MissingSemiColon - * InvalidExpressionAsName - ****************************************************************************/ -package net.sourceforge.phpdt.core.compiler; - -import net.sourceforge.phpdt.internal.compiler.lookup.ProblemReasons; - -/** - * Description of a Java problem, as detected by the compiler or some of the underlying - * technology reusing the compiler. - * A problem provides access to: - *
      - *
    • its location (originating source file name, source position, line number),
    • - *
    • its message description and a predicate to check its severity (warning or error).
    • - *
    • its ID : an number identifying the very nature of this problem. All possible IDs are listed - * as constants on this interface.
    • - *
    - * - * Note: the compiler produces IProblems internally, which are turned into markers by the JavaBuilder - * so as to persist problem descriptions. This explains why there is no API allowing to reach IProblem detected - * when compiling. However, the Java problem markers carry equivalent information to IProblem, in particular - * their ID (attribute "id") is set to one of the IDs defined on this interface. - * - * @since 2.0 - */ -public interface IProblem { - - /** - * Answer back the original arguments recorded into the problem. - * @return the original arguments recorded into the problem - */ - String[] getArguments(); - - /** - * Returns the problem id - * - * @return the problem id - */ - int getID(); - - /** - * Answer a localized, human-readable message string which describes the problem. - * - * @return a localized, human-readable message string which describes the problem - */ - String getMessage(); - - /** - * Answer the file name in which the problem was found. - * - * @return the file name in which the problem was found - */ - char[] getOriginatingFileName(); - - /** - * Answer the end position of the problem (inclusive), or -1 if unknown. - * - * @return the end position of the problem (inclusive), or -1 if unknown - */ - int getSourceEnd(); - - /** - * Answer the line number in source where the problem begins. - * - * @return the line number in source where the problem begins - */ - int getSourceLineNumber(); - - /** - * Answer the start position of the problem (inclusive), or -1 if unknown. - * - * @return the start position of the problem (inclusive), or -1 if unknown - */ - int getSourceStart(); - - /** - * Checks the severity to see if the Error bit is set. - * - * @return true if the Error bit is set for the severity, false otherwise - */ - boolean isError(); - - /** - * Checks the severity to see if the Error bit is not set. - * - * @return true if the Error bit is not set for the severity, false otherwise - */ - boolean isWarning(); - - /** - * Set the end position of the problem (inclusive), or -1 if unknown. - * Used for shifting problem positions. - * - * @param sourceEnd the given end position - */ - void setSourceEnd(int sourceEnd); - - /** - * Set the line number in source where the problem begins. - * - * @param lineNumber the given line number - */ - void setSourceLineNumber(int lineNumber); - - /** - * Set the start position of the problem (inclusive), or -1 if unknown. - * Used for shifting problem positions. - * - * @param the given start position - */ - void setSourceStart(int sourceStart); - - /** - * Problem Categories - * The high bits of a problem ID contains information about the category of a problem. - * e.g. (problemID & TypeRelated) != 0, indicates that this problem is type related. - * - * A problem category can help to implement custom problem filters. Indeed, when numerous problems - * are listed, focusing on import related problems first might be relevant. - * - * When a problem is tagged as Internal, it means that no change other than a local source code change - * can fix the corresponding problem. - */ - int TypeRelated = 0x01000000; - int FieldRelated = 0x02000000; - int MethodRelated = 0x04000000; - int ConstructorRelated = 0x08000000; - int ImportRelated = 0x10000000; - int Internal = 0x20000000; - int Syntax = 0x40000000; - - /** - * Mask to use in order to filter out the category portion of the problem ID. - */ - int IgnoreCategoriesMask = 0xFFFFFF; - - /** - * Below are listed all available problem IDs. Note that this list could be augmented in the future, - * as new features are added to the Java core implementation. - */ - - /** - * ID reserved for referencing an internal error inside the JavaCore implementation which - * may be surfaced as a problem associated with the compilation unit which caused it to occur. - */ - int Unclassified = 0; - - /** - * Generic type related problems - */ - int ObjectHasNoSuperclass = TypeRelated + 1; - int UndefinedType = TypeRelated + 2; - int NotVisibleType = TypeRelated + 3; - int AmbiguousType = TypeRelated + 4; - int UsingDeprecatedType = TypeRelated + 5; - int InternalTypeNameProvided = TypeRelated + 6; - - int IncompatibleTypesInEqualityOperator = TypeRelated + 15; - int IncompatibleTypesInConditionalOperator = TypeRelated + 16; - int TypeMismatch = TypeRelated + 17; - - /** - * Inner types related problems - */ - int MissingEnclosingInstanceForConstructorCall = TypeRelated + 20; - int MissingEnclosingInstance = TypeRelated + 21; - int IncorrectEnclosingInstanceReference = TypeRelated + 22; - int IllegalEnclosingInstanceSpecification = TypeRelated + 23; - int CannotDefineStaticInitializerInLocalType = Internal + 24; - int OuterLocalMustBeFinal = Internal + 25; - int CannotDefineInterfaceInLocalType = Internal + 26; - int IllegalPrimitiveOrArrayTypeForEnclosingInstance = TypeRelated + 27; - int AnonymousClassCannotExtendFinalClass = TypeRelated + 29; - - // variables - int UndefinedName = 50; - int UninitializedLocalVariable = Internal + 51; - int VariableTypeCannotBeVoid = Internal + 52; - int VariableTypeCannotBeVoidArray = Internal + 53; - int CannotAllocateVoidArray = Internal + 54; - // local variables - int RedefinedLocal = Internal + 55; - int RedefinedArgument = Internal + 56; - // final local variables - int DuplicateFinalLocalInitialization = Internal + 57; - /** @since 2.1 */ - int NonBlankFinalLocalAssignment = Internal + 58; - int FinalOuterLocalAssignment = Internal + 60; - int LocalVariableIsNeverUsed = Internal + 61; - int ArgumentIsNeverUsed = Internal + 62; - int BytecodeExceeds64KLimit = Internal + 63; - int BytecodeExceeds64KLimitForClinit = Internal + 64; - int TooManyArgumentSlots = Internal + 65; - int TooManyLocalVariableSlots = Internal + 66; - /** @since 2.1 */ - int TooManySyntheticArgumentSlots = Internal + 67; - /** @since 2.1 */ - int TooManyArrayDimensions = Internal + 68; - - // fields - int UndefinedField = FieldRelated + 70; - int NotVisibleField = FieldRelated + 71; - int AmbiguousField = FieldRelated + 72; - int UsingDeprecatedField = FieldRelated + 73; - int NonStaticFieldFromStaticInvocation = FieldRelated + 74; - int ReferenceToForwardField = FieldRelated + Internal + 75; - /** @since 2.1 */ - int NonStaticAccessToStaticField = Internal + FieldRelated + 76; - - // blank final fields - int FinalFieldAssignment = FieldRelated + 80; - int UninitializedBlankFinalField = FieldRelated + 81; - int DuplicateBlankFinalFieldInitialization = FieldRelated + 82; - - // methods - int UndefinedMethod = MethodRelated + 100; - int NotVisibleMethod = MethodRelated + 101; - int AmbiguousMethod = MethodRelated + 102; - int UsingDeprecatedMethod = MethodRelated + 103; - int DirectInvocationOfAbstractMethod = MethodRelated + 104; - int VoidMethodReturnsValue = MethodRelated + 105; - int MethodReturnsVoid = MethodRelated + 106; - int MethodRequiresBody = Internal + MethodRelated + 107; - int ShouldReturnValue = Internal + MethodRelated + 108; - int MethodButWithConstructorName = MethodRelated + 110; - int MissingReturnType = TypeRelated + 111; - int BodyForNativeMethod = Internal + MethodRelated + 112; - int BodyForAbstractMethod = Internal + MethodRelated + 113; - int NoMessageSendOnBaseType = MethodRelated + 114; - int ParameterMismatch = MethodRelated + 115; - int NoMessageSendOnArrayType = MethodRelated + 116; - /** @since 2.1 */ - int NonStaticAccessToStaticMethod = Internal + MethodRelated + 117; - - // constructors - int UndefinedConstructor = ConstructorRelated + 130; - int NotVisibleConstructor = ConstructorRelated + 131; - int AmbiguousConstructor = ConstructorRelated + 132; - int UsingDeprecatedConstructor = ConstructorRelated + 133; - // explicit constructor calls - int InstanceFieldDuringConstructorInvocation = ConstructorRelated + 135; - int InstanceMethodDuringConstructorInvocation = ConstructorRelated + 136; - int RecursiveConstructorInvocation = ConstructorRelated + 137; - int ThisSuperDuringConstructorInvocation = ConstructorRelated + 138; - // implicit constructor calls - int UndefinedConstructorInDefaultConstructor = ConstructorRelated + 140; - int NotVisibleConstructorInDefaultConstructor = ConstructorRelated + 141; - int AmbiguousConstructorInDefaultConstructor = ConstructorRelated + 142; - int UndefinedConstructorInImplicitConstructorCall = ConstructorRelated + 143; - int NotVisibleConstructorInImplicitConstructorCall = ConstructorRelated + 144; - int AmbiguousConstructorInImplicitConstructorCall = ConstructorRelated + 145; - int UnhandledExceptionInDefaultConstructor = TypeRelated + 146; - int UnhandledExceptionInImplicitConstructorCall = TypeRelated + 147; - - // expressions - int ArrayReferenceRequired = Internal + 150; - int NoImplicitStringConversionForCharArrayExpression = Internal + 151; - // constant expressions - int StringConstantIsExceedingUtf8Limit = Internal + 152; - int NonConstantExpression = 153; - int NumericValueOutOfRange = Internal + 154; - // cast expressions - int IllegalCast = TypeRelated + 156; - // allocations - int InvalidClassInstantiation = TypeRelated + 157; - int CannotDefineDimensionExpressionsWithInit = Internal + 158; - int MustDefineEitherDimensionExpressionsOrInitializer = Internal + 159; - // operators - int InvalidOperator = Internal + 160; - // statements - int CodeCannotBeReached = Internal + 161; - int CannotReturnInInitializer = Internal + 162; - int InitializerMustCompleteNormally = Internal + 163; - - // assert - int InvalidVoidExpression = Internal + 164; - // try - int MaskedCatch = TypeRelated + 165; - int DuplicateDefaultCase = 166; - int UnreachableCatch = TypeRelated + MethodRelated + 167; - int UnhandledException = TypeRelated + 168; - // switch - int IncorrectSwitchType = TypeRelated + 169; - int DuplicateCase = FieldRelated + 170; - // labelled - int DuplicateLabel = Internal + 171; - int InvalidBreak = Internal + 172; - int InvalidContinue = Internal + 173; - int UndefinedLabel = Internal + 174; - //synchronized - int InvalidTypeToSynchronized = Internal + 175; - int InvalidNullToSynchronized = Internal + 176; - // throw - int CannotThrowNull = Internal + 177; - // assignment - /** @since 2.1 */ - int AssignmentHasNoEffect = Internal + 178; - - // inner emulation - int NeedToEmulateFieldReadAccess = FieldRelated + 190; - int NeedToEmulateFieldWriteAccess = FieldRelated + 191; - int NeedToEmulateMethodAccess = MethodRelated + 192; - int NeedToEmulateConstructorAccess = MethodRelated + 193; - - //inherited name hides enclosing name (sort of ambiguous) - int InheritedMethodHidesEnclosingName = MethodRelated + 195; - int InheritedFieldHidesEnclosingName = FieldRelated + 196; - int InheritedTypeHidesEnclosingName = TypeRelated + 197; - - // miscellaneous - int ThisInStaticContext = Internal + 200; - int StaticMethodRequested = Internal + MethodRelated + 201; - int IllegalDimension = Internal + 202; - int InvalidTypeExpression = Internal + 203; - int ParsingError = Syntax + Internal + 204; - int ParsingErrorNoSuggestion = Syntax + Internal + 205; - int InvalidUnaryExpression = Syntax + Internal + 206; - - // syntax errors - int InterfaceCannotHaveConstructors = Syntax + Internal + 207; - int ArrayConstantsOnlyInArrayInitializers = Syntax + Internal + 208; - int ParsingErrorOnKeyword = Syntax + Internal + 209; - int ParsingErrorOnKeywordNoSuggestion = Syntax + Internal + 210; - - int UnmatchedBracket = Syntax + Internal + 220; - int NoFieldOnBaseType = FieldRelated + 221; - int InvalidExpressionAsStatement = Syntax + Internal + 222; - int ExpressionShouldBeAVariable = Syntax + Internal + 223; - int MissingSemiColon = Syntax + Internal + 224; - - // scanner errors - int EndOfSource = Syntax + Internal + 250; - int InvalidHexa = Syntax + Internal + 251; - int InvalidOctal = Syntax + Internal + 252; - int InvalidCharacterConstant = Syntax + Internal + 253; - int InvalidEscape = Syntax + Internal + 254; - int InvalidInput = Syntax + Internal + 255; - int InvalidUnicodeEscape = Syntax + Internal + 256; - int InvalidFloat = Syntax + Internal + 257; - int NullSourceString = Syntax + Internal + 258; - int UnterminatedString = Syntax + Internal + 259; - int UnterminatedComment = Syntax + Internal + 260; - - // type related problems - int InterfaceCannotHaveInitializers = TypeRelated + 300; - int DuplicateModifierForType = TypeRelated + 301; - int IllegalModifierForClass = TypeRelated + 302; - int IllegalModifierForInterface = TypeRelated + 303; - int IllegalModifierForMemberClass = TypeRelated + 304; - int IllegalModifierForMemberInterface = TypeRelated + 305; - int IllegalModifierForLocalClass = TypeRelated + 306; - - int IllegalModifierCombinationFinalAbstractForClass = TypeRelated + 308; - int IllegalVisibilityModifierForInterfaceMemberType = TypeRelated + 309; - int IllegalVisibilityModifierCombinationForMemberType = TypeRelated + 310; - int IllegalStaticModifierForMemberType = TypeRelated + 311; - int SuperclassMustBeAClass = TypeRelated + 312; - int ClassExtendFinalClass = TypeRelated + 313; - int DuplicateSuperInterface = TypeRelated + 314; - int SuperInterfaceMustBeAnInterface = TypeRelated + 315; - int HierarchyCircularitySelfReference = TypeRelated + 316; - int HierarchyCircularity = TypeRelated + 317; - int HidingEnclosingType = TypeRelated + 318; - int DuplicateNestedType = TypeRelated + 319; - int CannotThrowType = TypeRelated + 320; - int PackageCollidesWithType = TypeRelated + 321; - int TypeCollidesWithPackage = TypeRelated + 322; - int DuplicateTypes = TypeRelated + 323; -// int IsClassPathCorrect = TypeRelated + 324; - int PublicClassMustMatchFileName = TypeRelated + 325; - int MustSpecifyPackage = 326; - int HierarchyHasProblems = TypeRelated + 327; - int PackageIsNotExpectedPackage = 328; - int ObjectCannotHaveSuperTypes = 329; - - // int InvalidSuperclassBase = TypeRelated + 329; // reserved to 334 included - int SuperclassNotFound = TypeRelated + 329 + ProblemReasons.NotFound; // TypeRelated + 330 - int SuperclassNotVisible = TypeRelated + 329 + ProblemReasons.NotVisible; // TypeRelated + 331 - int SuperclassAmbiguous = TypeRelated + 329 + ProblemReasons.Ambiguous; // TypeRelated + 332 - int SuperclassInternalNameProvided = TypeRelated + 329 + ProblemReasons.InternalNameProvided; // TypeRelated + 333 - int SuperclassInheritedNameHidesEnclosingName = TypeRelated + 329 + ProblemReasons.InheritedNameHidesEnclosingName; // TypeRelated + 334 - - // int InvalidInterfaceBase = TypeRelated + 334; // reserved to 339 included - int InterfaceNotFound = TypeRelated + 334 + ProblemReasons.NotFound; // TypeRelated + 335 - int InterfaceNotVisible = TypeRelated + 334 + ProblemReasons.NotVisible; // TypeRelated + 336 - int InterfaceAmbiguous = TypeRelated + 334 + ProblemReasons.Ambiguous; // TypeRelated + 337 - int InterfaceInternalNameProvided = TypeRelated + 334 + ProblemReasons.InternalNameProvided; // TypeRelated + 338 - int InterfaceInheritedNameHidesEnclosingName = TypeRelated + 334 + ProblemReasons.InheritedNameHidesEnclosingName; // TypeRelated + 339 - - // field related problems - int DuplicateField = FieldRelated + 340; - int DuplicateModifierForField = FieldRelated + 341; - int IllegalModifierForField = FieldRelated + 342; - int IllegalModifierForInterfaceField = FieldRelated + 343; - int IllegalVisibilityModifierCombinationForField = FieldRelated + 344; - int IllegalModifierCombinationFinalVolatileForField = FieldRelated + 345; - int UnexpectedStaticModifierForField = FieldRelated + 346; - - // int FieldTypeProblemBase = FieldRelated + 349; //reserved to 354 - int FieldTypeNotFound = FieldRelated + 349 + ProblemReasons.NotFound; // FieldRelated + 350 - int FieldTypeNotVisible = FieldRelated + 349 + ProblemReasons.NotVisible; // FieldRelated + 351 - int FieldTypeAmbiguous = FieldRelated + 349 + ProblemReasons.Ambiguous; // FieldRelated + 352 - int FieldTypeInternalNameProvided = FieldRelated + 349 + ProblemReasons.InternalNameProvided; // FieldRelated + 353 - int FieldTypeInheritedNameHidesEnclosingName = FieldRelated + 349 + ProblemReasons.InheritedNameHidesEnclosingName; // FieldRelated + 354 - - // method related problems - int DuplicateMethod = MethodRelated + 355; - int IllegalModifierForArgument = MethodRelated + 356; - int DuplicateModifierForMethod = MethodRelated + 357; - int IllegalModifierForMethod = MethodRelated + 358; - int IllegalModifierForInterfaceMethod = MethodRelated + 359; - int IllegalVisibilityModifierCombinationForMethod = MethodRelated + 360; - int UnexpectedStaticModifierForMethod = MethodRelated + 361; - int IllegalAbstractModifierCombinationForMethod = MethodRelated + 362; - int AbstractMethodInAbstractClass = MethodRelated + 363; - int ArgumentTypeCannotBeVoid = MethodRelated + 364; - int ArgumentTypeCannotBeVoidArray = MethodRelated + 365; - int ReturnTypeCannotBeVoidArray = MethodRelated + 366; - int NativeMethodsCannotBeStrictfp = MethodRelated + 367; - int DuplicateModifierForArgument = MethodRelated + 368; - - // int ArgumentProblemBase = MethodRelated + 369; // reserved to 374 included. - int ArgumentTypeNotFound = MethodRelated + 369 + ProblemReasons.NotFound; // MethodRelated + 370 - int ArgumentTypeNotVisible = MethodRelated + 369 + ProblemReasons.NotVisible; // MethodRelated + 371 - int ArgumentTypeAmbiguous = MethodRelated + 369 + ProblemReasons.Ambiguous; // MethodRelated + 372 - int ArgumentTypeInternalNameProvided = MethodRelated + 369 + ProblemReasons.InternalNameProvided; // MethodRelated + 373 - int ArgumentTypeInheritedNameHidesEnclosingName = MethodRelated + 369 + ProblemReasons.InheritedNameHidesEnclosingName; // MethodRelated + 374 - - // int ExceptionTypeProblemBase = MethodRelated + 374; // reserved to 379 included. - int ExceptionTypeNotFound = MethodRelated + 374 + ProblemReasons.NotFound; // MethodRelated + 375 - int ExceptionTypeNotVisible = MethodRelated + 374 + ProblemReasons.NotVisible; // MethodRelated + 376 - int ExceptionTypeAmbiguous = MethodRelated + 374 + ProblemReasons.Ambiguous; // MethodRelated + 377 - int ExceptionTypeInternalNameProvided = MethodRelated + 374 + ProblemReasons.InternalNameProvided; // MethodRelated + 378 - int ExceptionTypeInheritedNameHidesEnclosingName = MethodRelated + 374 + ProblemReasons.InheritedNameHidesEnclosingName; // MethodRelated + 379 - - // int ReturnTypeProblemBase = MethodRelated + 379; - int ReturnTypeNotFound = MethodRelated + 379 + ProblemReasons.NotFound; // MethodRelated + 380 - int ReturnTypeNotVisible = MethodRelated + 379 + ProblemReasons.NotVisible; // MethodRelated + 381 - int ReturnTypeAmbiguous = MethodRelated + 379 + ProblemReasons.Ambiguous; // MethodRelated + 382 - int ReturnTypeInternalNameProvided = MethodRelated + 379 + ProblemReasons.InternalNameProvided; // MethodRelated + 383 - int ReturnTypeInheritedNameHidesEnclosingName = MethodRelated + 379 + ProblemReasons.InheritedNameHidesEnclosingName; // MethodRelated + 384 - - // import related problems - int ConflictingImport = ImportRelated + 385; - int DuplicateImport = ImportRelated + 386; - int CannotImportPackage = ImportRelated + 387; - int UnusedImport = ImportRelated + 388; - - // int ImportProblemBase = ImportRelated + 389; - int ImportNotFound = ImportRelated + 389 + ProblemReasons.NotFound; // ImportRelated + 390 - int ImportNotVisible = ImportRelated + 389 + ProblemReasons.NotVisible; // ImportRelated + 391 - int ImportAmbiguous = ImportRelated + 389 + ProblemReasons.Ambiguous; // ImportRelated + 392 - int ImportInternalNameProvided = ImportRelated + 389 + ProblemReasons.InternalNameProvided; // ImportRelated + 393 - int ImportInheritedNameHidesEnclosingName = ImportRelated + 389 + ProblemReasons.InheritedNameHidesEnclosingName; // ImportRelated + 394 - - - // local variable related problems - int DuplicateModifierForVariable = MethodRelated + 395; - int IllegalModifierForVariable = MethodRelated + 396; - - // method verifier problems - int AbstractMethodMustBeImplemented = MethodRelated + 400; - int FinalMethodCannotBeOverridden = MethodRelated + 401; - int IncompatibleExceptionInThrowsClause = MethodRelated + 402; - int IncompatibleExceptionInInheritedMethodThrowsClause = MethodRelated + 403; - int IncompatibleReturnType = MethodRelated + 404; - int InheritedMethodReducesVisibility = MethodRelated + 405; - int CannotOverrideAStaticMethodWithAnInstanceMethod = MethodRelated + 406; - int CannotHideAnInstanceMethodWithAStaticMethod = MethodRelated + 407; - int StaticInheritedMethodConflicts = MethodRelated + 408; - int MethodReducesVisibility = MethodRelated + 409; - int OverridingNonVisibleMethod = MethodRelated + 410; - int AbstractMethodCannotBeOverridden = MethodRelated + 411; - int OverridingDeprecatedMethod = MethodRelated + 412; - - // code snippet support - int CodeSnippetMissingClass = Internal + 420; - int CodeSnippetMissingMethod = Internal + 421; - int NonExternalizedStringLiteral = Internal + 261; - int CannotUseSuperInCodeSnippet = Internal + 422; - - //constant pool - int TooManyConstantsInConstantPool = Internal + 430; - int TooManyBytesForStringConstant = Internal + 431; - - // static constraints - int TooManyFields = Internal + 432; - int TooManyMethods = Internal + 433; - - // 1.4 features - // assertion warning - int UseAssertAsAnIdentifier = Internal + 440; - - // detected task - /** @since 2.1 */ - int Task = Internal + 450; -} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/compiler/ITerminalSymbols.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/compiler/ITerminalSymbols.java index 4c77716..adab9e7 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/compiler/ITerminalSymbols.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/compiler/ITerminalSymbols.java @@ -159,4 +159,17 @@ public interface ITerminalSymbols { public final static int TokenNamefalse = 1045; public final static int TokenNametrue = 1046; public final static int TokenNamethis = 1047; + // + public final static int TokenNameabstract = 1050; + public final static int TokenNamecatch = 1051; + public final static int TokenNamefinally = 1052; + public final static int TokenNametry = 1053; + public final static int TokenNameprivate = 1054; + public final static int TokenNameprotected = 1055; + public final static int TokenNamepublic = 1056; + public final static int TokenNameinterface = 1057; + public final static int TokenNameimplements = 1058; + public final static int TokenNameinstanceof = 1059; + public final static int TokenNamesuper = 1060; + public final static int TokenNamethrow = 1061; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/DOMException.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/DOMException.java new file mode 100644 index 0000000..79b002a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/DOMException.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core.jdom; + +/** + * Unchecked exception thrown when an illegal manipulation of the JDOM is + * performed, or when an attempt is made to access/set an attribute of a + * JDOM node that source indexes cannot be determined for (in case the source + * was syntactically incorrect). + */ +public class DOMException extends RuntimeException { +/** + * Creates a new exception with no detail message. + */ +public DOMException() {} +/** + * Creates a new exception with the given detail message. + * + * @param message the detail message + */ +public DOMException(String message) { + super(message); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/DOMFactory.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/DOMFactory.java new file mode 100644 index 0000000..0e61752 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/DOMFactory.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core.jdom; + +import net.sourceforge.phpdt.internal.core.Util; +import net.sourceforge.phpdt.internal.core.jdom.DOMBuilder; +import net.sourceforge.phpdt.internal.core.jdom.SimpleDOMBuilder; + + +/** + * Standard implementation of IDOMFactory, and the only means + * of creating JDOMs and document fragments. + *

    + * This class may be instantiated; it is not intended to be subclassed. + *

    + */ +public class DOMFactory implements IDOMFactory { +/** + * Creates a new DOM factory. + */ +public DOMFactory() {} +/* (non-Javadoc) + * Method declared on IDOMFactory. + */ +public IDOMCompilationUnit createCompilationUnit() { + return (new DOMBuilder()).createCompilationUnit(); +} +/* (non-Javadoc) + * Method declared on IDOMFactory. + */ +public IDOMCompilationUnit createCompilationUnit(char[] sourceCode, String name) { + if(sourceCode == null) { + return null; + } + return (new SimpleDOMBuilder()).createCompilationUnit(sourceCode, name.toCharArray()); +} +/* (non-Javadoc) + * Method declared on IDOMFactory. + */ +public IDOMCompilationUnit createCompilationUnit(String sourceCode, String name) { + if(sourceCode == null) { + return null; + } + return (new SimpleDOMBuilder()).createCompilationUnit(sourceCode.toCharArray(), name.toCharArray()); +} +/* (non-Javadoc) + * Method declared on IDOMFactory. + */ +//public IDOMField createField() { +// return createField("Object aField;"+ Util.LINE_SEPARATOR); //$NON-NLS-1$ +//} +///* (non-Javadoc) +// * Method declared on IDOMFactory. +// */ +//public IDOMField createField(String sourceCode) { +// if(sourceCode == null) { +// return null; +// } +// return (new DOMBuilder()).createField(sourceCode.toCharArray()); +//} +/* (non-Javadoc) + * Method declared on IDOMFactory. + */ +//public IDOMImport createImport() { +// return (new DOMBuilder()).createImport(); +//} +///* (non-Javadoc) +// * Method declared on IDOMFactory. +// */ +//public IDOMImport createImport(String sourceCode) { +// if(sourceCode == null) { +// return null; +// } +// return (new DOMBuilder()).createImport(sourceCode.toCharArray()); +//} +/* (non-Javadoc) + * Method declared on IDOMFactory. + */ +//public IDOMInitializer createInitializer() { +// return createInitializer("static {}"+ Util.LINE_SEPARATOR); //$NON-NLS-1$ +//} +///* (non-Javadoc) +// * Method declared on IDOMFactory. +// */ +//public IDOMInitializer createInitializer(String sourceCode) { +// if(sourceCode == null) { +// return null; +// } +// return (new DOMBuilder()).createInitializer(sourceCode.toCharArray()); +//} +/* (non-Javadoc) + * Method declared on IDOMFactory. + */ +//public IDOMMethod createMethod() { +// return createMethod("public void newMethod() {"+ Util.LINE_SEPARATOR+"}"+ Util.LINE_SEPARATOR); //$NON-NLS-2$ //$NON-NLS-1$ +//} +///* (non-Javadoc) +// * Method declared on IDOMFactory. +// */ +//public IDOMMethod createMethod(String sourceCode) { +// if(sourceCode == null) { +// return null; +// } +// return (new DOMBuilder()).createMethod(sourceCode.toCharArray()); +//} +/* (non-Javadoc) + * Method declared on IDOMFactory. + */ +public IDOMPackage createPackage() { + return (new DOMBuilder()).createPackage(); +} +/* (non-Javadoc) + * Method declared on IDOMFactory. + */ +//public IDOMPackage createPackage(String sourceCode) { +// if(sourceCode == null) { +// return null; +// } +// return (new DOMBuilder()).createPackage(sourceCode.toCharArray()); +//} +///* (non-Javadoc) +// * Method declared on IDOMFactory. +// */ +//public IDOMType createType() { +// return createType("public class AClass {"+ Util.LINE_SEPARATOR +"}"+ Util.LINE_SEPARATOR); //$NON-NLS-2$ //$NON-NLS-1$ +//} +/* (non-Javadoc) + * Method declared on IDOMFactory. + */ +//public IDOMType createClass() { +// return createType("public class AClass {"+ Util.LINE_SEPARATOR +"}"+ Util.LINE_SEPARATOR); //$NON-NLS-2$ //$NON-NLS-1$ +//} +///* (non-Javadoc) +// * Method declared on IDOMFactory. +// */ +//public IDOMType createInterface() { +// return createType("public interface AnInterface {"+ Util.LINE_SEPARATOR +"}"+ Util.LINE_SEPARATOR); //$NON-NLS-2$ //$NON-NLS-1$ +//} +/* (non-Javadoc) + * Method declared on IDOMFactory. + */ +//public IDOMType createType(String sourceCode) { +// if(sourceCode == null) { +// return null; +// } +// return (new DOMBuilder()).createType(sourceCode.toCharArray()); +//} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMCompilationUnit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMCompilationUnit.java new file mode 100644 index 0000000..37f0537 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMCompilationUnit.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core.jdom; + +/** + * Represents a Java compilation unit (.java source file). + * The corresponding syntactic unit is CompilationUnit (JLS2 7.3). + * Allowable child types for a compilation unit are IDOMPackage, IDOMImport, + * and IDOMType. + *

    + * This interface is not intended to be implemented by clients. + *

    + */ +public interface IDOMCompilationUnit extends IDOMNode { +/** + * Returns the header comment for this compilation unit. The header comment + * appears before the first declaration in a compilation unit. + * The syntax for a comment corresponds to Comments (JLS2 3.7), including + * comment delimiters. + * + * @return the header comment for this compilation unit, or null if + * no header comment is present + */ +public String getHeader(); +/** + * The IDOMCompilationNode refinement of this IDOMNode + * method returns the name of this compilation unit. + * + *

    The name of a compilation unit is the name of the first top-level public type + * defined in the compilation unit, suffixed with ".java". For example, if the first + * top-level public type defined in this compilation unit has the name "Hanoi", + * then name of this compilation unit is "Hanoi.java".

    + * + *

    In the absence of a public top-level type, the name of the first top-level + * type is used. In the absence of any type, the name of the compilation unit + * is null.

    + * + * @return the name of this compilation unit, or null if none + */ +public String getName(); +/** + * Sets the header comment for this compilation unit. The header comment + * appears before the first declaration in a compilation unit. + * The syntax for a comment corresponds to Comments (JLS2 3.7), including + * comment delimiters. + * + * @param comment the header comment for this compilation unit, or null if + * indicating no header comment + */ +public void setHeader(String comment); +/** + * The IDOMCompilationNode refinement of this IDOMNode + * method has no effect (the name is computed from the types declared within it). + */ +public void setName(String name); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMFactory.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMFactory.java new file mode 100644 index 0000000..eea0df1 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMFactory.java @@ -0,0 +1,197 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core.jdom; + +/** + * A factory used to create document fragment (DF) nodes. An + * IDOMCompilationUnit represents the root of a complete JDOM (that + * is, a ".java" file). Other node types represent fragments of a compilation + * unit. + *

    + * The factory can be used to create empty DFs or it can create DFs from source + * strings. All DFs created empty are assigned default values as required, such + * that a call to IDOMNode.getContents will generate a valid source + * string. See individual create methods for details on the default + * values supplied. The factory does its best to recognize Java structures in + * the source provided. If the factory is completely unable to recognize source + * constructs, the factory method returns null. + *

    + *

    + * Even if a DF is created successfully from source code, it does not guarantee + * that the source code will compile error free. Similarly, the contents of a DF + * are not guaranteed to compile error free. However, syntactically correct + * source code is guaranteed to be recognized and successfully generate a DF. + * Similarly, if all of the fragments of a JDOM are syntactically correct, the + * contents of the entire document will be correct too. + *

    + *

    + * The factory does not perform or provide any code formatting. Document + * fragments created on source strings must be pre-formatted. The JDOM attempts + * to maintain the formatting of documents as best as possible. For this reason, + * document fragments created for nodes that are to be strung together should + * end with a new-line character. Failing to do so will result in a document + * that has elements strung together on the same line. This is especially + * important if a source string ends with a // comment. In this case, it would + * be syntactically incorrect to omit the new line character. + *

    + *

    + * This interface is not intended to be implemented by clients. + *

    + * + * @see IDOMNode + */ +public interface IDOMFactory { +/** + * Creates and return an empty JDOM. The initial content is an empty string. + * + * @return the new compilation unit + */ +public IDOMCompilationUnit createCompilationUnit(); +/** + * Creates a JDOM on the given source code. The syntax for the given source + * code corresponds to CompilationUnit (JLS2 7.3). + * + * @param sourceCode the source code character array, or null + * @param name the name of the compilation unit + * @return the new compilation unit, or null if unable to recognize + * the source code, or if the source code is null + */ +public IDOMCompilationUnit createCompilationUnit(char[] sourceCode, String name); +/** + * Creates a JDOM on the given source code. The syntax for the given source + * code corresponds to CompilationUnit (JLS2 7.3). + * + * @param sourceCode the source code string, or null + * @param name the name of the compilation unit + * @return the new compilation unit, or null if unable to recognize + * the source code, or if the source code is null + */ +public IDOMCompilationUnit createCompilationUnit(String sourceCode, String name); +/** + * Creates a default field document fragment. Initially the field will have + * default protection, type "Object", name "aField", + * no comment, and no initializer. + * + * @return the new field + */ +//public IDOMField createField(); +/** + * Creates a field document fragment on the given source code. The given source + * string corresponds to FieldDeclaration (JLS2 8.3) and ConstantDeclaration + * (JLS2 9.3) restricted to a single VariableDeclarator clause. + * + * @param sourceCode the source code + * @return the new field, or null if unable to recognize + * the source code, if the source code is null, or when the source + * contains more than one VariableDeclarator clause + */ +//public IDOMField createField(String sourceCode); +/** + * Creates an empty import document fragment. Initially the import will have + * name "java.lang.*". + * + * @return the new import + */ +//public IDOMImport createImport(); +/** + * Creates an import document fragment on the given source code. The syntax for + * the given source string corresponds to ImportDeclaration (JLS2 7.5). + * + * @param sourceCode the source code + * @return the new import, or null if unable to recognize + * the source code, or if the source code is null + */ +//public IDOMImport createImport(String sourceCode); +/** + * Creates an empty initializer document fragment. Initially the initializer + * will be static and have no body or comment. + * + * @return the new initializer + */ +//public IDOMInitializer createInitializer(); +/** + * Creates an initializer document fragment from the given source code. The + * syntax for the given source string corresponds to InstanceInitializer + * (JLS2 8.6) and StaticDeclaration (JLS2 8.7). + * + * @param sourceCode the source code + * @return the new initializer, or null if unable to recognize + * the source code, or if the source code is null + */ +//public IDOMInitializer createInitializer(String sourceCode); +/** + * Creates a default method document fragment. Initially the method + * will have public visibility, return type "void", be named + * "newMethod", have no parameters, no comment, and an empty body. + * + * @return the new method + */ +//public IDOMMethod createMethod(); +/** + * Creates a method document fragment on the given source code. The syntax for + * the given source string corresponds to MethodDeclaration (JLS2 8.4), + * ConstructorDeclaration (JLS2 8.8), and AbstractMethodDeclaration (JLS2 9.4). + * + * @param sourceCode the source code + * @return the new method, or null if unable to recognize + * the source code, or if the source code is null + */ +//public IDOMMethod createMethod(String sourceCode); +/** + * Creates an empty package document fragment. Initially the package + * declaration will have no name. + * + * @return the new package + */ +//public IDOMPackage createPackage(); +/** + * Creates a package document fragment on the given source code. The syntax for + * the given source string corresponds to PackageDeclaration (JLS2 7.4). + * + * @param sourceCode the source code + * @return the new package, or null if unable to recognize + * the source code, or if the source code is null + */ +//public IDOMPackage createPackage(String sourceCode); +/** + * Creates a default type document fragment. Initially the type will be + * a public class named "AClass", with no members or comment. + * + * @return the new type + */ +//public IDOMType createType(); +/** + * Creates a default type document fragment. Initially the type will be + * a public class named "AClass", with no members or comment. + * + * @return the new class + * @since 2.0 + */ +//public IDOMType createClass(); +/** + * Creates a default type document fragment. Initially the type will be + * a public interface named "AnInterface", with no members or comment. + * + * @return the new interface + * @since 2.0 + */ +//public IDOMType createInterface(); +/** + * Creates a type document fragment on the given source code. The syntax for the + * given source string corresponds to ClassDeclaration (JLS2 8.1) and + * InterfaceDeclaration (JLS2 9.1). + * + * @param sourceCode the source code + * @return the new type, or null if unable to recognize + * the source code, or if the source code is null + */ +//public IDOMType createType(String sourceCode); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMField.java new file mode 100644 index 0000000..72de2a6 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMField.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core.jdom; + +/** + * Represents a field declaration. The corresponding + * syntactic units are FieldDeclaration (JLS2 8.3) and ConstantDeclaration + * (JLS2 9.3) restricted to a single VariableDeclarator clause. + * A field has no children. The parent of a field is a type. + *

    + * This interface is not intended to be implemented by clients. + *

    + */ +public interface IDOMField extends IDOMMember { +/** + * Returns the initializer expression for this field. + * The syntax for an initializer corresponds to VariableInitializer (JLS2 8.3). + *

    + * Note: The expression does not include a "=". + *

    + * + * @return the initializer expression, or null if this field does + * not have an initializer + */ +public String getInitializer(); +/** + * The IDOMField refinement of this IDOMNode + * method returns the name of this field. The syntax for the name of a field + * corresponds to VariableDeclaratorId (JLS2 8.3). + */ +public String getName(); +/** + * Returns the type name of this field. The syntax for a type name of a field + * corresponds to Type in Field Declaration (JLS2 8.3). + * + * @return the type name + */ +public String getType(); +/** + * Sets the initializer expression for this field. + * The syntax for an initializer corresponds to VariableInitializer (JLS2 8.3). + *

    + * Note: The expression does not include a "=". + *

    + * + * @param initializer the initializer expression, or null indicating + * the field does not have an initializer + */ +public void setInitializer(String initializer); +/** + * The IDOMField refinement of this IDOMNode + * method sets the name of this field. The syntax for the name of a field + * corresponds to VariableDeclaratorId (JLS2 8.3). + * + * @exception IllegalArgumentException if null is specified + */ +public void setName(String name) throws IllegalArgumentException; +/** + * Sets the type name of this field. The syntax for a type name of a field + * corresponds to Type in Field Declaration (JLS2 8.3). Type names must be + * specified as they should appear in source code. For example: + * "String", "int[]", or "java.io.File". + * + * @param typeName the type name + * @exception IllegalArgumentException if null is specified + */ +public void setType(String typeName) throws IllegalArgumentException; +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMImport.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMImport.java new file mode 100644 index 0000000..47a6ffa --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMImport.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core.jdom; + +/** + * Represents an import declaration. + * The corresponding syntactic unit is ImportDeclaration (JLS2 7.5). + * An import has no children and its parent is a compilation unit. + *

    + * This interface is not intended to be implemented by clients. + *

    + */ +public interface IDOMImport extends IDOMNode { +/** + * The IDOMImport refinement of this IDOMNode + * method returns the name of this import. The syntax for an import name + * corresponds to a fully qualified type name, or to an on-demand package name + * as defined by ImportDeclaration (JLS2 7.5). + */ +public String getName(); +/** + * Returns whether this import declaration ends with ".*". + * + * @return true if this in an on-demand import + */ +public boolean isOnDemand(); +/** + * The IDOMImport refinement of this IDOMNode + * method sets the name of this import. The syntax for an import name + * corresponds to a fully qualified type name, or to an on-demand package name + * as defined by ImportDeclaration (JLS2 7.5). + * + * @exception IllegalArgumentException if null is specified + */ +public void setName(String name); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMInitializer.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMInitializer.java new file mode 100644 index 0000000..96c612e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMInitializer.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core.jdom; + +/** + * Represents an initializer. The corresponding syntactic + * units are InstanceInitializer (JLS2 8.6) and StaticDeclaration (JLS2 8.7). + * An initializer has no children and its parent is a type. + *

    + * This interface is not intended to be implemented by clients. + *

    + */ +public interface IDOMInitializer extends IDOMMember { +/** + * Returns the body of this initializer. The syntax for a body corresponds to + * InstanceInitializer (JLS2 8.6) and StaticDeclaration (JLS2 8.7). + * + * @return an initializer body, including braces, or null if + * no body is present + */ +public String getBody(); +/** + * The IDOMInitializer refinement of this IDOMNode + * method returns null. An initializer does not have a name. + */ +public String getName(); +/** + * Sets the body of this initializer. The syntax for a body corresponds to + * InstanceInitializer (JLS2 8.6) and StaticDeclaration (JLS2 8.7). No formatting + * or syntax checking is performed on the body. Braces must be included. + * + * @param body an initializer body, including braces, or null + * indicating no body + */ +public void setBody(String body); +/** + * The IDOMInitializer refinement of this IDOMNode + * method does nothing. + */ +public void setName(String name); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMMember.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMMember.java new file mode 100644 index 0000000..da5ea6b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMMember.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core.jdom; + +/** + * An IDOMMember defines functionality common to nodes, which + * can be members of types. + *

    + * This interface is not intended to be implemented by clients. + *

    + * + * @see IDOMType + * @see IDOMMethod + * @see IDOMField + * @see IDOMInitializer + */ +public interface IDOMMember extends IDOMNode { +/** + * Returns the comment associated with this member (including comment delimiters). + * + * @return the comment, or null if this member has no associated + * comment + */ +public String getComment(); +/** + * Returns the flags for this member. The flags can be examined using the + * Flags class. + * + * @return the flags + * @see org.eclipse.jdt.core.Flags + */ +public int getFlags(); +/** + * Sets the comment associated with this member. The comment will appear + * before the member in the source. The comment must be properly formatted, including + * delimiters. A null comment indicates no comment. This member's + * deprecated flag is automatically set to reflect the deprecated tag in the + * comment. + * + * @param comment the comment, including comment delimiters, or + * null indicating this member should have no associated comment + * @see #setFlags + */ +public void setComment(String comment); +/** + * Sets the flags for this member. The flags can be examined using the + * Flags class. The deprecated flag passed in is ignored. + * + * @param flags the flags + * @see org.eclipse.jdt.core.Flags + */ +public void setFlags(int flags); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMMethod.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMMethod.java new file mode 100644 index 0000000..4845a80 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMMethod.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core.jdom; + +/** + * Represents a method declaration. + * The corresponding syntactic units are MethodDeclaration (JLS2 8.4), + * ConstructorDeclaration (JLS2 8.8), and AbstractMethodDeclaration (JLS2 9.4). + * A method has no children and its parent is a type. + * Local classes are considered to be part of the body of a method, not a child. + *

    + * This interface is not intended to be implemented by clients. + *

    + */ +public interface IDOMMethod extends IDOMMember { +/** + * Adds the given exception to the end of the list of exceptions this method + * is declared to throw. + * The syntax for an exception type name is defined by Method Throws (JLS2 8.4.4). + * Type names must be specified as they would appear in source code. For + * example: "IOException" or "java.io.IOException". + * This is a convenience method for setExceptions. + * + * @param exceptionType the exception type + * @exception IllegalArgumentException if null is specified + * @see #setExceptions + */ +public void addException(String exceptionType) throws IllegalArgumentException; +/** + * Adds the given parameter to the end of the parameter list. + * This is a convenience method for setParameters. + * The syntax for parameter names is defined by Formal Parameters (JLS2 8.4.1). + * The syntax for type names is defined by Formal Parameters (JLS2 8.4.1). + * Type names must be specified as they would appear in source code. For + * example: "File", "java.io.File", or + * "int[]". + * + * @param type the type name + * @param name the parameter name + * @exception IllegalArgumentException if null is specified for + * either the type or the name + * @see #setParameters + */ +public void addParameter(String type, String name) throws IllegalArgumentException; +/** + * Returns the body of this method. The method body includes all code following + * the method declaration, including the enclosing braces. + * + * @return the body, or null if the method has no body (for + * example, for an abstract or native method) + */ +public String getBody(); +/** + * Returns the names of the exception types this method throws + * in the order in which they are declared in the source, or an empty array + * if this method declares no exception types. + * The syntax for an exception type name is defined by Method Throws (JLS2 8.4.4). + * Type names appear as they would in source code. For example: + * "IOException" or "java.io.IOException". + * + * @return the list of exception types + */ +public String[] getExceptions(); +/** + * The IDOMMethod refinement of this IDOMNode + * method returns the name of this method. Returns null for + * constructors. The syntax for a method name is defined by Identifier + * of MethodDeclarator (JLS2 8.4). + */ +public String getName(); +/** + * Returns the names of parameters in this method in the order they are declared, + * or null if no parameters are declared. + * The syntax for parameter names is defined by Formal Parameters (JLS2 8.4.1). + * + * @return the list of parameter names, or null if no parameters + * are declared + */ +public String[] getParameterNames(); +/** + * Returns the type names for the parameters of this method in the order they are declared, + * or null if no parameters are declared. + * The syntax for type names is defined by Formal Parameters (JLS2 8.4.1). + * Type names must be specified as they would appear in source code. For + * example: "File", "java.io.File", or + * "int[]". + * + * @return the list of parameter types, or null if no parameters + * are declared + */ +public String[] getParameterTypes(); +/** + * Returns the return type name, or null. + * Returns null for constructors. + * The syntax for return type name corresponds to ReturnType in + * MethodDeclaration (JLS2 8.4). Names are returned as they appear in the source + * code; for example: "File", "java.io.File", + * "int[]", or "void". + * + * @return the return type + */ +public String getReturnType(); +/** + * Returns whether this method is a constructor. + * + * @return true for constructors, and false for methods + */ +public boolean isConstructor(); +/** + * Sets the body of this method. The method body includes all code following + * the method declaration, including the enclosing braces. No formatting or + * syntax checking is performed on the body. + * + * @return the body, or null indicating the method has no body (for + * example, for an abstract or native method) + */ +public void setBody(String body); +/** + * Sets whether this method represents a constructor. + * + * @param b true for constructors, and false for methods + */ +public void setConstructor(boolean b); +/** + * Sets the names of the exception types this method throws, + * in the order in which they are declared in the source. An empty array + * indicates this method declares no exception types. + * The syntax for an exception type name is defined by Method Throws (JLS2 8.4.4). + * Type names must be specified as they would appear in source code. For + * example: "IOException" or "java.io.IOException". + * + * @param exceptionTypes the list of exception types + */ +public void setExceptions(String[] exceptionTypes); +/** + * The IDOMMethod refinement of this IDOMNode + * method sets the name of this method. The syntax for a method + * name is defined by Identifer of MethodDeclarator (JLS2 8.4). + *

    + * The name of a constructor is always null and thus it + * must not be set. + *

    + * + * @exception IllegalArgumentException if null is specified + */ +public void setName(String name) throws IllegalArgumentException; +/** + * Sets the types and names of parameters in this method in the order they are + * to be declared. If both types and names are null + * this indicates that this method has no parameters. + * The syntax for parameter names is defined by Formal Parameters (JLS2 8.4.1). + * The syntax for type names is defined by Formal Parameters (JLS2 8.4.1). + * Type names must be specified as they would appear in source code. For + * example: "File", "java.io.File", or + * "int[]". + * + * @param types the list of type names + * @param names the list of parameter name + * @exception IllegalArgumentException if the number of types and names do not + * match, or if either argument is null + */ +public void setParameters(String[] types, String[] names) throws IllegalArgumentException; +/** + * Sets the return type name. This has no effect on constructors. + * The syntax for return type name corresponds to ReturnType in + * MethodDeclaration (JLS2 8.4). Type names are specified as they appear in the + * source code; for example: "File", "java.io.File", + * "int[]", or "void". + * + * @param type the return type + * @exception IllegalArgumentException if null is specified + */ +public void setReturnType(String type) throws IllegalArgumentException; +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMNode.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMNode.java new file mode 100644 index 0000000..9c61412 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMNode.java @@ -0,0 +1,278 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core.jdom; + +import java.util.Enumeration; + +import net.sourceforge.phpdt.core.IJavaElement; + + +/** + * Nodes represent structural fragments of a Java source file, also known as document fragments. Their implementation + * is known as a DOM (Document Object Model) - in this case a JDOM (Java DOM). A root node (node + * with no parent or siblings) represents the root of a document fragment (DF). A complete Java document is + * represented by a compilation unit node (IDOMCompilationUnit). In this way, a DF is + * comprised of DFs, and a document itself (compilation unit) is also a DF. + *

    + * A DF may be created empty and programmatically filled, or it may be created from + * a source code string. The IDOMFactory allows the creation of all kinds + * of nodes from source code strings. Manipulations performed on a DF are immediately + * reflected in the DF's contents. + *

    + *

    + * Children fragments are represented as a linked list of nodes. Children are inserted via their parent node, and + * are automatically linked up with previous and next nodes. + *

    + *

    + * The contents of any node (DF) may be retrieved at any time. In this way it is possible to retrieve + * source code representing fragments of the compilation unit (for example, a type or a method), since + * the contents of any node (not just the root node) may be obtained. + *

    + *

    + * The following manipulations on DFs are distinct: + *

      + *
    • clone - this creates a stand-alone copy of the DF that is in no way dependent on the DF that it was cloned from
    • + *
    • remove - this orphans a DF from its host DF. The removed DF may still be dependent on its previous host + * (perhaps to generate its contents), and hanging onto the fragment means that its previous host is also + * retained in memory.
    • + *
    • add/insert - this splices an un-parented DF (one that has been cloned, removed, or created stand-alone), + * into an existing DF such that the newly inserted DF is only dependent on its new host.
    • + *
    + *

    + *

    + * Wherever types are specified in DOM APIs, type names must be specified as they would appear + * in source code. The DOM does not have a notion of type signatures, only raw text. Example type + * names are "Object", "java.io.File", and "int[]". + *

    + *

    + * This interface is not intended to be implemented by clients. + *

    + */ +public interface IDOMNode extends Cloneable { + + /** + * Node type constant indicating a compilation unit. + * Nodes of this type maybe by safely cast to IDOMCompilationUnit. + * @see #getNodeType + */ + public static int COMPILATION_UNIT= 1; + + /** + * Node type constant indicating a package declaration. + * Nodes of this type maybe by safely cast to IDOMPackage. + * @see #getNodeType + */ + public static int PACKAGE= 2; + + /** + * Node type constant indicating an import declaration. + * Nodes of this type maybe by safely cast to IDOMImport. + * @see #getNodeType + */ + public static int IMPORT= 3; + + /** + * Node type constant indicating a type declaration. + * Nodes of this type maybe by safely cast to IDOMType. + * @see #getNodeType + */ + public static int TYPE= 4; + + /** + * Node type constant indicating a field declaration. + * Nodes of this type maybe by safely cast to IDOMField. + * @see #getNodeType + */ + public static int FIELD= 5; + + /** + * Node type constant indicating a method (or constructor) declaration. + * Nodes of this type maybe by safely cast to IDOMMethod. + * @see #getNodeType + */ + public static int METHOD= 6; + + /** + * Node type constant indicating an initializer declaration. + * Nodes of this type maybe by safely cast to IDOMInitializer. + * @see #getNodeType + */ + public static int INITIALIZER= 7; + +/** + * Adds the given un-parented node (document fragment) as the last child of this node. + * + * @param child the new child node + * @exception DOMException if any of the following conditions hold:
      + *
    • this node is not allowed to have children,
    • + *
    • the child is not of an allowable type
    • + *
    • the child already has a parent
    • + *
    • the child is an ancestor of this node
    • + *
    + * @exception IllegalArgumentException if the child is null + * + * @see #insertSibling + * @see #remove + */ +public void addChild(IDOMNode child) throws DOMException, IllegalArgumentException; +/** + * Returns whether this node is allowed to have children. + * + * @return true if this node can have children + */ +public boolean canHaveChildren(); +/** + * Returns a stand-alone copy of the document fragment represented by this node that + * is in no way dependent on the document this node is part of. + * + * @return a copy of type IDOMNode + * @see #addChild + * @see #insertSibling + * @see #remove + */ +public Object clone(); +/** + * Returns the current contents of this document fragment as a character array. + *

    + * Note: To obtain complete source for the ".java" file, ask a compilation unit + * node for its contents. + *

    + * + * @return the contents, or null if this node has no contents + */ +public char[] getCharacters(); +/** + * Returns the first named child of this node with the given name. + * + * @param name the name + * @return the child node, or null if no such child exists + */ +public IDOMNode getChild(String name); +/** + * Returns an enumeration of children of this node. Returns an empty enumeration + * if this node has no children (including nodes that cannot have children). + * Children appear in the order in which they are declared in the source code. + * + * @return an enumeration of the children + */ +public Enumeration getChildren(); +/** + * Returns the current contents of this document fragment. + *

    + * Note: To obtain complete source for the ".java" file, ask a compilation unit + * node for its contents. + *

    + * + * @return the contents, or null if this node has no contents + */ +public String getContents(); +/** + * Returns the first child of this node. + * Children appear in the order in which they exist in the source code. + * + * @return the first child, or null if this node has no children + * @see #getChildren + */ +public IDOMNode getFirstChild(); +/** + * Returns a handle for the Java element associated with this + * document fragment, based on the parent Java element. + * + * @param parent the parent Java element + * @exception IllegalArgumentException if the parent element is not + * of a valid parent type for this node + */ +public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException; +/** + * Returns the name of this node. + * More details are provided in each of the subtypes. + * + * @return the name, or null if it has no name + */ +public String getName(); +/** + * Returns the sibling node immediately following this node. + * + * @return the next node, or null if there is no following node + */ +public IDOMNode getNextNode(); +/** + * Returns the type of this node. + * + * @return one of the node type constants defined in IDOMNode + */ +public int getNodeType(); +/** + * Returns the parent of this node. + * + * @return the parent node, or null if this node does not have a + * parent + */ +public IDOMNode getParent(); +/** + * Returns the sibling node immediately preceding this node. + * + * @return the previous node, or null if there is no preceding node + */ +public IDOMNode getPreviousNode(); +/** + * Inserts the given un-parented node as a sibling of this node, immediately before + * this node. + * + * @param sibling the new sibling node + * @exception DOMException if any of the following conditions hold:
      + *
    • this node is a document fragment root
    • + *
    • the sibling is not of the correct type
    • + *
    • the sibling already has a parent
    • + *
    • this sibling is an ancestor of this node
    • + *
    + * @exception IllegalArgumentException if the sibling is null + * + * @see #addChild + * @see #clone + * @see #remove + */ +public void insertSibling(IDOMNode sibling) throws DOMException, IllegalArgumentException; +/** + * Returns whether the given node is an allowable child for this node. + * + * @param node the potential child node + * @return true if the given node is an allowable child + */ +public boolean isAllowableChild(IDOMNode node); +/** + * Returns whether this node's signature is equivalent to the given + * node's signature. In other words, if the nodes were siblings, + * would the declarations collide because they represent the same declaration. + * + * @param node the other node + * @return true if the nodes have equivalent signatures + */ +public boolean isSignatureEqual(IDOMNode node); +/** + * Separates this node from its parent and siblings, maintaining any ties that this node + * has to the underlying document fragment. A document fragment that is removed + * from its host document may still be dependent on that host document until it is + * inserted into a different document. Removing a root node has no effect. + * + * @see #addChild + * @see #clone + * @see #insertSibling + */ +public void remove(); +/** + * Sets the name of this node. Name format depends on node type. + * More details are provided in each of the subtypes. + * + * @param name the name, or null to clear the name + */ +public void setName(String name); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMPackage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMPackage.java new file mode 100644 index 0000000..49333c8 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMPackage.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core.jdom; +/** + * Represents a package declaration. + * The corresponding syntactic unit is PackageDeclaration (JLS2 7.4). + * A Package has no children, and its parent is a compilation unit. + *

    + * This interface is not intended to be implemented by clients. + *

    + */ +public interface IDOMPackage extends IDOMNode { +/** + * The IDOMPackage refinement of this IDOMNode + * method returns the name of this package declaration, or null + * if it has none. The syntax for a package name corresponds to PackageName + * as defined by PackageDeclaration (JLS2 7.4). + */ +public String getName(); +/** + * The IDOMPackage refinement of this IDOMNode + * method sets the name of this package declaration. The syntax for a package + * name corresponds to PackageName as defined by PackageDeclaration (JLS2 7.4). + * A null name indicates an empty package declaration; that is, + * getContents returns the empty string. + */ +public void setName(String name); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMType.java new file mode 100644 index 0000000..5a4c62e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/IDOMType.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core.jdom; + +/** + * Represents a source type in a compilation unit, either as a top-level type or a member type. + * The corresponding syntactic units are ClassDeclaration (JLS2 8.1) and InterfaceDeclaration (JLS2 9.1). + *

    + * Allowable child types for a type are IDOMType, IDOMField, + * IDOMMethod, and IDOMInitializer. + * Children are listed in the order in which they appear in the source. The parent of a type + * is a type (in the case of a member type) or a compilation unit (in the case of a top-level type). + *

    + *

    + * This interface is not intended to be implemented by clients. + *

    + */ +public interface IDOMType extends IDOMMember { +/** + * Adds the given interface name to the names of interfaces that this type implements or extends + * (the name will be added after the existing interface names). This is a convenience method. + * + * For classes, this represents the interfaces that this class implements. + * For interfaces, this represents the interfaces that this interface extends. + * The name may or may not be fully qualified. + * + * @param interfaceName the syntax for an interface name is defined by + * Interfaces in ClassDeclaration (JLS2 8.1). Type names must be specified as they would + * appear in source code. For example: "Cloneable", "java.io.Serializable". + * + * @exception IllegalArgumentException if null is specified + */ +public void addSuperInterface(String interfaceName) throws IllegalArgumentException; +/** + * The IDOMType refinement of this IDOMNode + * method returns the name of this type. The name of a class is defined by + * ClassDeclaration (JLS2 8.1); the name of an interface is defined by + * InterfaceDeclaration (JLS2 9.1). + */ +public String getName(); +/** + * Returns the name of this type's superclass. The syntax for a superclass name + * is specified by Super in ClassDeclaration (JLS2 8.1). Type names must be + * specified as they would appear in source code. For example: + * "Object", or "java.io.File". + * + * @return the superclass name, or null if this type represents + * an interface or if no superclass has been assigned to this class + */ +public String getSuperclass(); +/** + * Returns the names of interfaces that this type implements or extends, + * in the order in which they are listed in the source, or an empty array + * if no superinterfaces are present. The syntax for interface names is + * defined by Interfaces in ClassDeclaration (JLS2 8.1). Type names appear + * as they would in source code. For example: "Cloneable", + * or "java.io.Serializable". + *

    + * For classes, this method returns the interfaces that this class implements. + * For interfaces, this method returns the interfaces that this interface extends. + *

    + * + * @return the list of interface names + */ +public String[] getSuperInterfaces(); +/** + * Returns whether this type is a class. + * + * @return true for classes, and false for interfaces + */ +public boolean isClass(); +/** + * Sets whether this type is a class or an interface. If this type is + * a class, and is changed to an interface, this type's superclass + * becomes null. When a class becomes an interface or an + * interface becomes a class, superinterfaces remain (as part of an + * implements clause for classes, or an extends + * clause for interfaces). + * + * @param b true for classes, and false for interfaces + */ +public void setClass(boolean b); +/** + * The IDOMType refinement of this IDOMNode + * method sets the name of this type. The name of a class is defined by + * ClassDeclaration (JLS2 8.1); the name of an interface is defined by + * InterfaceDeclaration (JLS2 9.1). + * + * @exception IllegalArgumentException if null is specified + */ +public void setName(String name) throws IllegalArgumentException; +/** + * Sets the name of this type's superclass. Has no effect if this type + * represents an interface. A null name indicates that no + * superclass name (extends clause) should appear in the source code. + * The syntax for a superclass name is specified by Super in ClassDeclaration + * (JLS2 8.1). Type names must be specified as they would appear in source code. + * For example: "Object", or "java.io.File". + * + * @param superclassName the superclass name, or null if this type + * should have to no explicitly specified superclass + */ +public void setSuperclass(String superclassName); +/** + * Sets the names of interfaces that this type implements or extends, + * in the order in which they are to be listed in the source. An empty array + * parameter indicates that no superinterfaces are present. The syntax for + * interface names is defined by Interfaces in ClassDeclaration (JLS2 8.1). + * Type names appear as they would in source code. For example: + * "Cloneable", or "java.io.Serializable". + *

    + * For classes, this method sets the interfaces that this class implements. + * For interfaces, this method sets the interfaces that this interface extends. + *

    + * + * @param interfaceNames the list of interface names + */ +public void setSuperInterfaces(String[] interfaceNames); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/package.html b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/package.html new file mode 100644 index 0000000..4fa6750 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/jdom/package.html @@ -0,0 +1,17 @@ + + + + + + + Package-level Javadoc + + +Provides a support for java document manipulation +through the JDOM model. +

    +Package Specification

    +This package provides a support for java document manipulation throught +the JDOM model. + + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/search/IJavaSearchConstants.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/search/IJavaSearchConstants.java new file mode 100644 index 0000000..1aec40e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/search/IJavaSearchConstants.java @@ -0,0 +1,174 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core.search; + + +/** + *

    + * This interface defines the constants used by the search engine. + *

    + *

    + * This interface declares constants only; it is not intended to be implemented. + *

    + * @see org.eclipse.jdt.core.search.SearchEngine + */ +public interface IJavaSearchConstants { + + /** + * The nature of searched element or the nature + * of match in unknown. + */ + int UNKNOWN = -1; + + /* Nature of searched element */ + + /** + * The searched element is a type. + */ + int TYPE= 0; + + /** + * The searched element is a method. + */ + int METHOD= 1; + + /** + * The searched element is a package. + */ + int PACKAGE= 2; + + /** + * The searched element is a constructor. + */ + int CONSTRUCTOR= 3; + + /** + * The searched element is a field. + */ + int FIELD= 4; + + /** + * The searched element is a class. + * More selective than using TYPE + */ + int CLASS= 5; + + /** + * The searched element is an interface. + * More selective than using TYPE + */ + int INTERFACE= 6; + + /* Nature of match */ + + /** + * The search result is a declaration. + * Can be used in conjunction with any of the nature of searched elements + * so as to better narrow down the search. + */ + int DECLARATIONS= 0; + + /** + * The search result is a type that implements an interface. + * Used in conjunction with either TYPE or CLASS or INTERFACE, it will + * respectively search for any type implementing/extending an interface, or + * rather exclusively search for classes implementing an interface, or interfaces + * extending an interface. + */ + int IMPLEMENTORS= 1; + + /** + * The search result is a reference. + * Can be used in conjunction with any of the nature of searched elements + * so as to better narrow down the search. + * References can contain implementers since they are more generic kind + * of matches. + */ + int REFERENCES= 2; + + /** + * The search result is a declaration, a reference, or an implementer + * of an interface. + * Can be used in conjunction with any of the nature of searched elements + * so as to better narrow down the search. + */ + int ALL_OCCURRENCES= 3; + + /** + * When searching for field matches, it will exclusively find read accesses, as + * opposed to write accesses. Note that some expressions are considered both + * as field read/write accesses: for example, x++; x+= 1; + * + * @since 2.0 + */ + int READ_ACCESSES = 4; + + /** + * When searching for field matches, it will exclusively find write accesses, as + * opposed to read accesses. Note that some expressions are considered both + * as field read/write accesses: for example, x++; x+= 1; + * + * @since 2.0 + */ + int WRITE_ACCESSES = 5; + + /* Syntactic match modes */ + + /** + * The search pattern matches exactly the search result, + * that is, the source of the search result equals the search pattern. + */ + int EXACT_MATCH = 0; + /** + * The search pattern is a prefix of the search result. + */ + int PREFIX_MATCH = 1; + /** + * The search pattern contains one or more wild cards ('*') where a + * wild-card can replace 0 or more characters in the search result. + */ + int PATTERN_MATCH = 2; + + + /* Case sensitivity */ + + /** + * The search pattern matches the search result only + * if cases are the same. + */ + boolean CASE_SENSITIVE = true; + /** + * The search pattern ignores cases in the search result. + */ + boolean CASE_INSENSITIVE = false; + + + /* Waiting policies */ + +// /** +// * The search operation starts immediately, even if the underlying indexer +// * has not finished indexing the workspace. Results will more likely +// * not contain all the matches. +// */ +// int FORCE_IMMEDIATE_SEARCH = IJob.ForceImmediate; +// /** +// * The search operation throws an org.eclipse.core.runtime.OperationCanceledException +// * if the underlying indexer has not finished indexing the workspace. +// */ +// int CANCEL_IF_NOT_READY_TO_SEARCH = IJob.CancelIfNotReady; +// /** +// * The search operation waits for the underlying indexer to finish indexing +// * the workspace before starting the search. +// */ +// int WAIT_UNTIL_READY_TO_SEARCH = IJob.WaitUntilReady; + + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/search/ITypeNameRequestor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/search/ITypeNameRequestor.java new file mode 100644 index 0000000..2a092b8 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/search/ITypeNameRequestor.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core.search; + +/** + * A ITypeNameRequestor collects search results from a searchAllTypeNames + * query to a SearchEngine. Clients must implement this interface and pass + * an instance to the searchAllTypeNames(...) method. Only top-level and + * member types are reported. Local types are not reported. + *

    + * This interface may be implemented by clients. + *

    + */ +public interface ITypeNameRequestor { +/** + * Accepts a top-level or a member class. + * + * @param packageName the dot-separated name of the package of the class + * @param simpleTypeName the simple name of the class + * @param enclosingTypeNames if the class is a member type, + * the simple names of the enclosing types from the outer-most to the + * direct parent of the class (for example, if the class is x.y.A$B$C then + * the enclosing types are [A, B]. This is an empty array if the class + * is a top-level type. + * @param path the full path to the resource containing the class. If the resource is a .class file + * or a .java file, this is the full path in the workspace to this resource. If the + * resource is an archive (that is, a .zip or .jar file), the path is composed of 2 paths separated + * by IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR: + * the first path is the full OS path to the archive (if it is an external archive), + * or the workspace relative IPath to the archive (if it is an internal archive), + * the second path is the path to the resource inside the archive. + */ +void acceptClass(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path); +/** + * Accepts a top-level or a member interface. + * + * @param packageName the dot-separated name of the package of the interface + * @param simpleTypeName the simple name of the interface + * @param enclosingTypeNames if the interface is a member type, + * the simple names of the enclosing types from the outer-most to the + * direct parent of the interface (for example, if the interface is x.y.A$B$I then + * the enclosing types are [A, B]. This is an empty array if the interface + * is a top-level type. + * @param path the full path to the resource containing the interface. If the resource is a .class file + * or a .java file, this is the full path in the workspace to this resource. If the + * resource is an archive (that is, a .zip or .jar file), the path is composed of 2 paths separated + * by IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR: + * the first path is the full OS path to the archive (if it is an external archive), + * or the workspace relative IPath to the archive (if it is an internal archive), + * the second path is the path to the resource inside the archive. + * */ +void acceptInterface(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/model/ToolMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/model/ToolMessages.java new file mode 100644 index 0000000..c2b9bf7 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/model/ToolMessages.java @@ -0,0 +1,61 @@ +package net.sourceforge.phpdt.externaltools.internal.model; + +/********************************************************************** +Copyright (c) 2002 IBM Corp. and others. All rights reserved. +This file is made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html +  +Contributors: +**********************************************************************/ + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * Utility class which helps managing messages + */ +public final class ToolMessages { + private static final String RESOURCE_BUNDLE= "net.sourceforge.phpdt.externaltools.internal.model.messages"; //$NON-NLS-1$ + private static ResourceBundle bundle = ResourceBundle.getBundle(RESOURCE_BUNDLE); + + private ToolMessages(){ + // prevent instantiation of class + } + + /** + * Returns the formatted message for the given key in + * the resource bundle. + * + * @param key the message name + * @param args the message arguments + * @return the formatted message + */ + public static String format(String key, Object[] args) { + return MessageFormat.format(getString(key), args); + } + + /** + * Returns the message with the given key in + * the resource bundle. If there isn't any value under + * the given key, the key is returned. + * + * @param key the message name + * @return the message + */ + public static String getString(String key) { + try { + return bundle.getString(key); + } catch (MissingResourceException e) { + return key; + } + } + + /** + * Returns the resource bundle for the plug-in + */ + public static ResourceBundle getResourceBundle() { + return bundle; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/model/messages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/model/messages.properties new file mode 100644 index 0000000..875ed09 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/model/messages.properties @@ -0,0 +1,332 @@ +# ====================================================================== +# Copyright (c) 2002 IBM Corp. and others. All rights reserved. +# This file is made available under the terms of the Common Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/cpl-v10.html +#   +# Contributors: +# ====================================================================== + +# ======================================================================= +# Base External Tool +# ======================================================================= + +ExternalTool.nameMustContainOneChar = The external tool name must contain at least one letter or number. +ExternalTool.nameContainsInvalidChar = The external tool name must contain only letters, numbers, hyphens, and spaces. + +ToolUtil.dirLocVarBetweenText = The variable for the directory location cannot have any other text before or after itself. +ToolUtil.dirLocVarFormatWrong = The variable for the directory location is not in a valid format. +ToolUtil.dirLocVarMissing = The variable named ''{0}'' for the directory location does not exist. +ToolUtil.dirLocVarExpandFailed = The variable named ''{0}'' for the directory location could not be expanded. +ToolUtil.fileLocVarBetweenText = The variable for the file location cannot have any other text before or after itself. +ToolUtil.fileLocVarFormatWrong = The variable for the file location is not in a valid format. +ToolUtil.fileLocVarMissing = The variable named ''{0}'' for the file location does not exist. +ToolUtil.fileLocVarExpandFailed = The variable named ''{0}'' for the file location could not be expanded. +ToolUtil.argumentVarFormatWrong = A variable for the arguments is not in a valid format. +ToolUtil.argumentVarMissing = The variable named ''{0}'' for the arguments does not exist. +ToolUtil.argumentVarExpandFailed = The variable named ''{0}'' for the arguments could not be expanded. + +ExternalToolRegistry.loadToolFailure = Press the Details button for more information. +ExternalToolRegistry.fileNotFoundError = Could not find external tool storage file. +ExternalToolRegistry.ioLoadError = Problems reading external tool storage file. +ExternalToolRegistry.ioSaveError = Problems writing external tool storage file. +ExternalToolRegistry.loadErrorTitle = Problem Loading External Tools. +ExternalToolRegistry.loadErrorMessage = Could not load all external tools. +ExternalToolRegistry.noToolFilename = External tool filename for storage not specified. +ExternalToolRegistry.deleteToolFileFailed = Could not delete external tool file ''{0}''. + +ExternalToolStorage.deleteErrorTitle = Problem Deleting External Tool. +ExternalToolStorage.deleteErrorMessage = Could not delete external tool. Refresh list and try again. +ExternalToolStorage.reloadErrorTitle = Problem Refreshing External Tools +ExternalToolStorage.reloadErrorMessage = Could not load all external tools. +ExternalToolStorage.saveErrorTitle = Problem Saving External Tool. +ExternalToolStorage.saveErrorMessage = Could not save external tool. Please try again. + +NewExternalToolAction.text = &New +NewExternalToolAction.toolTip = New External Tool Wizard + +CopyExternalToolAction.text = &Copy +CopyExternalToolAction.toolTip = Copy External Tool + +PasteExternalToolAction.text = &Paste +PasteExternalToolAction.toolTip = Paste External Tool + +DeleteExternalToolAction.text = &Delete +DeleteExternalToolAction.toolTip = Delete External Tool +DeleteExternalToolAction.confirmToolDeleteTitle = Confirm External Tool Delete +DeleteExternalToolAction.confirmToolDeleteMsg = Are you sure want to delete ''{0}''? + +RenameExternalToolAction.text = Rena&me +RenameExternalToolAction.toolTip = Rename External Tool + +RefreshViewAction.text = Re&fresh +RefreshViewAction.toolTip = Refresh External Tool View + +RunExternalToolAction.text = R&un +RunExternalToolAction.toolTip = Run External Tool + +RunWithExternalToolAction.text = Run &With... +RunWithExternalToolAction.toolTip = Prompt for Arguments and Run External Tool + +EditExternalToolPropertiesAction.text = P&roperties +EditExternalToolPropertiesAction.toolTip = Edit External Tool Properties + +ExternalToolMainGroup.locationLabel = &Location: +ExternalToolMainGroup.locationBrowseLabel = B&rowse... +ExternalToolMainGroup.descriptionLabel = D&escription: +ExternalToolMainGroup.nameLabel = Na&me: +ExternalToolMainGroup.workDirLabel = &Working Directory: +ExternalToolMainGroup.workDirBrowseLabel = Br&owse... +ExternalToolMainGroup.nameRequired = External tool name cannot be empty. +ExternalToolMainGroup.nameAlreadyExist = Another external tool exists with the same name. +ExternalToolMainGroup.locationRequired = External tool location cannot be empty. +ExternalToolMainGroup.invalidLocation = External tool location does not exist or is invalid. +ExternalToolMainGroup.invalidWorkDir = External tool working directory does not exist or is invalid. + +ExternalToolOptionGroup.captureOutputLabel = &Capture output messages from running tool +ExternalToolOptionGroup.showConsoleLabel = &Show console when tool is run +ExternalToolOptionGroup.runBackgroundLabel = &Run tool in background +ExternalToolOptionGroup.openPerspLabel = &Open perspective when tool is run: +ExternalToolOptionGroup.argumentLabel = Ar&guments: +ExternalToolOptionGroup.argumentInstruction = Note: Enclose an argument containing spaces using double-quotes ("). Not\napplicable for variables. +ExternalToolOptionGroup.argumentVariableLabel = &Variables... +ExternalToolOptionGroup.promptArgLabel = &Prompt for arguments before running tool +ExternalToolOptionGroup.showInMenuLabel = S&how in Run > External Tools menu +ExternalToolOptionGroup.saveDirtyEditorsLabel = Save dirty &editors before running tool + +ExternalToolRefreshGroup.refreshLabel = &Refresh resources after running tool +ExternalToolRefreshGroup.recursiveLabel = Recursively &include sub-folders +ExternalToolRefreshGroup.scopeLabel = Choose &Scope Variable: + +ExternalToolNewWizard.shellTitle = New External Tool +ExternalToolNewWizard.optionPageTitle = Options +ExternalToolNewWizard.optionPageDescription = Configure the options when the external tool is run. +ExternalToolNewWizard.refreshPageTitle = Refresh Scope +ExternalToolNewWizard.refreshPageDescription = Specify which resources to refresh after the external tool is run. + +ExternalToolVariable.componentErrorMessage = Problem displaying UI component of selected variable. + +ResourceComponent.selectedResLabel = &Use selected resource +ResourceComponent.specificResLabel = Us&e specific resource: +ResourceComponent.selectionRequired = A specific resource must be selected from the list. + +RunExternalToolAction.openPerspProblem = Failed to open the perspective. +RunExternalToolAction.openPerspTitle = Open Perspective Problem +RunExternalToolAction.runProblem = Could not run the external tool. +RunExternalToolAction.runErrorTitle = Run Tool Problem +RunExternalToolAction.internalError = External tool runner internal error + +DefaultRunnerContext.runningExternalTool = Running external tool... +DefaultRunnerContext.invalidLocation = The file does not exist for the external tool named {0}. +DefaultRunnerContext.invalidDirectory = The working directory does not exist for the external tool named {0}. +DefaultRunnerContext.refreshResources = Refresh resources... +DefaultRunnerContext.noToolRunner = The no valid runner provided for the external tool named {0}. +DefaultRunnerContext.invalidRefreshVarFormat = Invalid refresh scope variable format for the external tool named {0}. +DefaultRunnerContext.noRefreshVarNamed = Could not find refresh scope variable called ''{1}'' for the external tool named {0}. + +ExternalToolMenuDelegate.showView = Show External Tools View +ExternalToolMenuDelegate.runRecent = Run Last Tool +ExternalToolMenuDelegate.configure = Configure... + + +# ======================================================================= +# Program External Tool Type +# ======================================================================= + +ProgramRunner.runningToolLabel = Running external tool: {0} +ProgramRunner.internalErrorMessage = Internal error +ProgramRunner.callingRuntimeExec = Calling runtime exec with:\n +ProgramRunner.program = Program: {0}\n +ProgramRunner.argument = Argument: {0}\n +ProgramRunner.workDir = Working Directory: {0}\n + + +# ======================================================================= +# Ant Build File External Tool Type +# ======================================================================= + +AntFileRunner.callingAntRunner = Calling Ant runner with:\n +AntFileRunner.antFile = Ant build file: {0}\n +AntFileRunner.argument = Argument: {0}\n +AntFileRunner.target = Target: {0}\n + +AntTargetsGroup.availableTargetsLabel = A&vailable targets: +AntTargetsGroup.activeTargetsLabel = A&ctive targets: +AntTargetsGroup.addLabel = > +AntTargetsGroup.removeLabel = < +AntTargetsGroup.addAllLabel = >> +AntTargetsGroup.removeAllLabel = << +AntTargetsGroup.descriptionLabel = &Target description: +AntTargetsGroup.upLabel = U&p +AntTargetsGroup.downLabel = D&own +AntTargetsGroup.getTargetsTitle = Problem retrieving targets +AntTargetsGroup.getTargetsProblem = Could not retrieve targets. +AntTargetsGroup.runDefaultTargetLabel = R&un default target ({0}) +AntTargetsGroup.runDefaultTargetUnknownLabel = R&un default target +AntTargetsGroup.showSubTargetsLabel = S&how sub-targets + +AntExternalToolNewWizard.antTargetsPageTitle = Ant Targets +AntExternalToolNewWizard.antTargetsPageDescription = Specify which Ant targets to execute when the external tool is run. +AntExternalToolNewWizard.promptForArgumentLabel = &Prompt for targets and arguments before running tool + +AntOptionGroupPropertyPage.promptForArgumentLabel = &Prompt for targets and arguments before running tool + + + +# ======================================================================= +# OLD STUFF +# ======================================================================= + +ConfigurationDialog.shellTitle = External Tools Configuration +ConfigurationDialog.dialogTitle = External Tools +ConfigurationDialog.dialogMessage = Configure an external tool to run a program, batch file, or Ant build file. +ConfigurationDialog.toolList = &Tools: +ConfigurationDialog.newButton = &New... +ConfigurationDialog.editButton = &Edit... +ConfigurationDialog.removeButton = &Remove +ConfigurationDialog.upButton = &Up +ConfigurationDialog.downButton = &Down +ConfigurationDialog.details = Det&ails: +ConfigurationDialog.detailMessage = Location: {0}\nArguments: {1}\nDirectory: {2} + +EditDialog.newShellTitle = New External Tool +EditDialog.editShellTitle = Edit External Tool +EditDialog.dialogTitle = External Tool +EditDialog.newDialogMessage = Create an external tool to run a program, batch file, or Ant build file. +EditDialog.editDialogMessage = Edit an external tool to run a program, batch file, or Ant build file. +EditDialog.howToSelectAntTargets = To choose Ant targets, press the ''Browse Variables'' button and select ''Ant targets''. +EditDialog.nameLabel = &Name: +EditDialog.locationLabel = Tool &Location: +EditDialog.argumentLabel = Tool &Arguments: +EditDialog.dirLabel = Working &Directory: +EditDialog.refreshOption = After running, &refresh: +EditDialog.browseWkspButton1 = Browse &Workspace... +EditDialog.browseFileSysButton1 = Browse &File System... +EditDialog.browseVarsButton = Browse &Variables... +EditDialog.directoryBrowseButton = Browse &Options... +EditDialog.refreshOptionButton = Browse O&ptions... +EditDialog.browseWorkspaceTitle = Browse Workspace +EditDialog.selectTool = &Select the external tool to use: +EditDialog.selectResource = &Select the resource to use: +EditDialog.selectContainer = &Select the container to use: +EditDialog.selectDirectory = &Select the working directory to use: +EditDialog.selectTargets = &Select the Ant targets to use: +EditDialog.selectFolder = &Select the folder to use: +EditDialog.browseVarTitle = Browse Variables +EditDialog.browseDirTitle = Browse Working Directory Options +EditDialog.selectVar = &Select a variable to use: +EditDialog.selectDir = &Select a working directory option: +EditDialog.dirBrowseWorkspace = Browse workspace +EditDialog.dirBrowseFileSystem = Browse file system +EditDialog.varWorkspaceLocLabel = Workspace location +EditDialog.varProjectLocLabel = Selected resource's project location +EditDialog.varContainerLocLabel = Selected resource's container location +EditDialog.varResourceLocLabel = Selected resource location +EditDialog.varProjectPathLabel = Selected resource's project full path +EditDialog.varContainerPathLabel = Selected resource's container full path +EditDialog.varResourcePathLabel = Selected resource full path +EditDialog.varProjectNameLabel = Selected resource's project name +EditDialog.varContainerNameLabel = Selected resource's container name +EditDialog.varResourceNameLabel = Selected resource name +EditDialog.varProjectXLocLabel = Specific resource's project location +EditDialog.varContainerXLocLabel = Specific resource's container location +EditDialog.varResourceXLocLabel = Specific resource location +EditDialog.varProjectXPathLabel = Specific resource's project full path +EditDialog.varContainerXPathLabel = Specific resource's container full path +EditDialog.varResourceXPathLabel = Specific resource full path +EditDialog.varProjectXNameLabel = Specific resource's project name +EditDialog.varContainerXNameLabel = Specific resource's container name +EditDialog.varResourceXNameLabel = Specific resource name +EditDialog.varBuildTypeNameLabel = Build type +EditDialog.varAntTargetLabel = Ant targets +EditDialog.browseProjectTitle = Browse Projects +EditDialog.selectProject = &Select a project to use: +EditDialog.noToolName = Enter a name for the tool +EditDialog.noToolLocation = Enter a location for the tool +EditDialog.missingToolLocation = Tool location does not exist or is invalid +EditDialog.missingToolDirectory = Tool working directory does not exist or is invalid +EditDialog.refreshScopeNone = Nothing +EditDialog.refreshScopeWorkspace = Workspace +EditDialog.refreshScopeProject = Current project +EditDialog.refreshScopeProjectX = Project named {0} +EditDialog.refreshScopeWorkingSet = Working set named {0} +EditDialog.browseRefreshTitle = Browse Refresh Scopes +EditDialog.selectRefresh = &Select the refresh scope to use: +EditDialog.refreshNothingLabel = Nothing +EditDialog.refreshWorkspaceLabel = Current workspace +EditDialog.refreshProjectLabel = Current project +EditDialog.refreshProjectXLabel = Specific project +EditDialog.refreshWorkingSetLabel = Specific working set +EditDialog.showLogLabel = S&how execution log on console +EditDialog.errorTitle = Edit External Tool Problem +EditDialog.errorReadAntFile = Problems reading Ant build file: {0} +EditDialog.noAntTargets = Could not find any targets in Ant build file: {0} + +ExternalToolsRegistry.saveStateErrorTitle = Problem Saving External Tool +ExternalToolsRegistry.saveStateError = Could not write external tool configurations to disk.\n\nPlease try again. + +BuilderPropertyPage.description = Add external tools to the build order. +BuilderPropertyPage.newButton = &New... +BuilderPropertyPage.editButton = &Edit... +BuilderPropertyPage.removeButton = &Remove +BuilderPropertyPage.upButton = &Up +BuilderPropertyPage.downButton = &Down +BuilderPropertyPage.statusMessage = Internal error +BuilderPropertyPage.errorTitle = External Tool Builder Problem +BuilderPropertyPage.errorMessage = Internal error +BuilderPropertyPage.invalidBuildTool = Invalid External Tool Builder +BuilderPropertyPage.missingBuilder = Missing builder ({0}) + +ExternalToolsAction.configure = &Configure... + +LogConsoleDocument.externalTool = External Tool + +LogConsoleView.copy = &Copy@Ctrl+C +LogConsoleView.expandAll = &Expand All +LogConsoleView.selectAll = Select &All@Ctrl+A +LogConsoleView.clearOutput = Clear Output +LogConsoleView.hideOutputStructureTree = Hide Output Structure Tree +LogConsoleView.showOutputStructureTree = Show Output Structure Tree +LogConsoleView.showTree = &Show Tree +LogConsoleView.showSelectedElementOnly = Show Output of Selected Element Only +LogConsoleView.showCompleteOutput = Show Complete Output +LogConsoleView.findAction.label = Find/Replace + +LogTreeLabelProvider.invalidItemName = Invalid item name + +ToolsPreferencePage.errorColor = &Error: +ToolsPreferencePage.warningColor = &Warning: +ToolsPreferencePage.infoColor = I&nformation: +ToolsPreferencePage.verboseColor = Ve&rbose: +ToolsPreferencePage.debugColor = Deb&ug: +ToolsPreferencePage.font = Console font setting: +ToolsPreferencePage.description = Console text color settings. + +BuildCanceledException.canceled = Canceled + +AntUtil.antFileNotFound = Could not open Ant build file. +AntUtil.parserConfigError = Internal parser configuration error. +AntUtil.ioError = Could not read content of Ant build file. +AntUtil.formatError = Could not parse content of Ant build file. +AntUtil.invalidAntBuildFile = Invalid content format of Ant build file. + +AntAction.runErrorTitle = Run Ant Problem +AntAction.errorReadAntFile = Problems reading Ant build file: {0} +AntAction.noAntTargets = Could not find any targets in Ant build file: {0} + +AntLaunchWizard.shellTitle = Run Ant +AntLaunchWizard.dialogTitle = Run +AntLaunchWizard.dialogDescription = Run an Ant build file +AntLaunchWizard.runningAnt = Running Ant +AntLaunchWizard.runAntProblem = A problem occurred executing the Ant file. See the log console for details. +AntLaunchWizard.runErrorTitle = Run Ant Problem +AntLaunchWizard.internalAntError = Ant runner internal error + +AntLaunchWizardPage.targetLabel = Available &targets: +AntLaunchWizardPage.argsLabel = &Arguments: +AntLaunchWizardPage.showLogLabel = S&how execution log in console + +AntTargetLabelProvider.defaultTarget = Default + +ExternalToolsDialog.External_Tools_1=External Tools +ExternalToolsDialog.Create,_manage,_and_run_external_tools_2=Create, manage, and run external tools diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/codeassist/ISearchRequestor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/codeassist/ISearchRequestor.java new file mode 100644 index 0000000..e430c5b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/codeassist/ISearchRequestor.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.codeassist; + +/** + * This is the internal requestor passed to the searchable name environment + * so as to process the multiple search results as they are discovered. + * + * It is used to allow the code assist engine to add some more information + * to the raw name environment results before answering them to the UI. + */ +public interface ISearchRequestor { + + /** + * One result of the search consists of a new class. + * + * 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.M". + * The default package is represented by an empty array. + */ + public void acceptClass(char[] packageName, char[] typeName, int modifiers); + + /** + * One result of the search consists of a new interface. + * + * 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 acceptInterface(char[] packageName, char[] typeName, int modifiers); + + /** + * 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); + + /** + * 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.M". + * The default package is represented by an empty array. + */ + public void acceptType(char[] packageName, char[] typeName); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/codeassist/ISearchableNameEnvironment.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/codeassist/ISearchableNameEnvironment.java new file mode 100644 index 0000000..57cfbd5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/codeassist/ISearchableNameEnvironment.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.codeassist; + +import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment; + +/** + * This interface defines the API that may be used to implement any + * search-based tool (such as a CodeAssist, a Finder, ...). + * It is mainly used to hide from the search tool the implementation + * of the underlying environment and its constructions. + */ +public interface ISearchableNameEnvironment extends INameEnvironment { + + /** + * Find the packages that start with the given prefix. + * A valid prefix is a qualified name separated by periods + * (ex. java.util). + * The packages found are passed to: + * ISearchRequestor.acceptPackage(char[][] packageName) + */ + void findPackages(char[] prefix, ISearchRequestor requestor); + + /** + * Find the top-level types (classes and interfaces) that are defined + * in the current environment and whose name starts with the + * given prefix. The prefix is a qualified name separated by periods + * or a simple name (ex. java.util.V or V). + * + * The types found are passed to one of the following methods (if additional + * information is known about the types): + * ISearchRequestor.acceptType(char[][] packageName, char[] typeName) + * ISearchRequestor.acceptClass(char[][] packageName, char[] typeName, int modifiers) + * ISearchRequestor.acceptInterface(char[][] packageName, char[] typeName, int modifiers) + * + * This method can not be used to find member types... member + * types are found relative to their enclosing type. + */ + void findTypes(char[] prefix, ISearchRequestor requestor); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/AbstractSyntaxTreeVisitorAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/AbstractSyntaxTreeVisitorAdapter.java new file mode 100644 index 0000000..3185e97 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/AbstractSyntaxTreeVisitorAdapter.java @@ -0,0 +1,569 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler; + +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope; +import net.sourceforge.phpdt.internal.compiler.lookup.CompilationUnitScope; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpeclipse.internal.compiler.ast.AND_AND_Expression; +import net.sourceforge.phpeclipse.internal.compiler.ast.AllocationExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.AnonymousLocalTypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.Argument; +import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayAllocationExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayInitializer; +import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayQualifiedTypeReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayTypeReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.AssertStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.Assignment; +import net.sourceforge.phpeclipse.internal.compiler.ast.BinaryExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.Block; +import net.sourceforge.phpeclipse.internal.compiler.ast.Break; +import net.sourceforge.phpeclipse.internal.compiler.ast.Case; +import net.sourceforge.phpeclipse.internal.compiler.ast.CastExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.CharLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.ClassLiteralAccess; +import net.sourceforge.phpeclipse.internal.compiler.ast.Clinit; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompoundAssignment; +import net.sourceforge.phpeclipse.internal.compiler.ast.ConditionalExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.Continue; +import net.sourceforge.phpeclipse.internal.compiler.ast.DefaultCase; +import net.sourceforge.phpeclipse.internal.compiler.ast.DoStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.DoubleLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.EmptyStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.EqualExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.ExplicitConstructorCall; +import net.sourceforge.phpeclipse.internal.compiler.ast.ExtendedStringLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.FalseLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.FloatLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.ForStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.IfStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.Initializer; +import net.sourceforge.phpeclipse.internal.compiler.ast.InstanceOfExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.IntLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.LabeledStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.LocalDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.LocalTypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.LongLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.MemberTypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.MessageSend; +import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.NullLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.OR_OR_Expression; +import net.sourceforge.phpeclipse.internal.compiler.ast.PostfixExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.PrefixExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedAllocationExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedNameReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedSuperReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedThisReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedTypeReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.ReturnStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.SingleNameReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.SuperReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.SwitchStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.SynchronizedStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.ThisReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.ThrowStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.TrueLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.TryStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.UnaryExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.WhileStatement; + + +/** + * An adapter class for interating through the parse tree. + */ + +public class AbstractSyntaxTreeVisitorAdapter implements IAbstractSyntaxTreeVisitor { + + public void acceptProblem(IProblem problem) {} + public void endVisit( + AllocationExpression allocationExpression, + BlockScope scope) { + } + public void endVisit(AND_AND_Expression and_and_Expression, BlockScope scope) { + } + public void endVisit( + AnonymousLocalTypeDeclaration anonymousTypeDeclaration, + BlockScope scope) { + } + public void endVisit(Argument argument, BlockScope scope) { + } + public void endVisit( + ArrayAllocationExpression arrayAllocationExpression, + BlockScope scope) { + } + public void endVisit(ArrayInitializer arrayInitializer, BlockScope scope) { + } + public void endVisit( + ArrayQualifiedTypeReference arrayQualifiedTypeReference, + BlockScope scope) { + } + public void endVisit( + ArrayQualifiedTypeReference arrayQualifiedTypeReference, + ClassScope scope) { + } + public void endVisit(ArrayReference arrayReference, BlockScope scope) { + } + public void endVisit(ArrayTypeReference arrayTypeReference, BlockScope scope) { + } + public void endVisit(ArrayTypeReference arrayTypeReference, ClassScope scope) { + } + public void endVisit(Assignment assignment, BlockScope scope) { + } + public void endVisit(AssertStatement assertStatement, BlockScope scope) { + } + public void endVisit(BinaryExpression binaryExpression, BlockScope scope) { + } + public void endVisit(Block block, BlockScope scope) { + } + public void endVisit(Break breakStatement, BlockScope scope) { + } + public void endVisit(Case caseStatement, BlockScope scope) { + } + public void endVisit(CastExpression castExpression, BlockScope scope) { + } + public void endVisit(CharLiteral charLiteral, BlockScope scope) { + } + public void endVisit(ClassLiteralAccess classLiteral, BlockScope scope) { + } + public void endVisit(Clinit clinit, ClassScope scope) { + } + public void endVisit( + CompilationUnitDeclaration compilationUnitDeclaration, + CompilationUnitScope scope) { + } + public void endVisit(CompoundAssignment compoundAssignment, BlockScope scope) { + } + public void endVisit( + ConditionalExpression conditionalExpression, + BlockScope scope) { + } + public void endVisit( + ConstructorDeclaration constructorDeclaration, + ClassScope scope) { + } + public void endVisit(Continue continueStatement, BlockScope scope) { + } + public void endVisit(DefaultCase defaultCaseStatement, BlockScope scope) { + } + public void endVisit(DoStatement doStatement, BlockScope scope) { + } + public void endVisit(DoubleLiteral doubleLiteral, BlockScope scope) { + } + public void endVisit(EqualExpression equalExpression, BlockScope scope) { + } + public void endVisit( + ExplicitConstructorCall explicitConstructor, + BlockScope scope) { + } + public void endVisit( + ExtendedStringLiteral extendedStringLiteral, + BlockScope scope) { + } + public void endVisit(FalseLiteral falseLiteral, BlockScope scope) { + } + public void endVisit(FieldDeclaration fieldDeclaration, MethodScope scope) { + } + public void endVisit(FieldReference fieldReference, BlockScope scope) { + } + public void endVisit(FloatLiteral floatLiteral, BlockScope scope) { + } + public void endVisit(EmptyStatement emptyStatement, BlockScope scope) { + } + public void endVisit(ForStatement forStatement, BlockScope scope) { + } + public void endVisit(IfStatement ifStatement, BlockScope scope) { + } + public void endVisit(ImportReference importRef, CompilationUnitScope scope) { + } + public void endVisit(Initializer initializer, MethodScope scope) { + } + public void endVisit( + InstanceOfExpression instanceOfExpression, + BlockScope scope) { + } + public void endVisit(IntLiteral intLiteral, BlockScope scope) { + } + public void endVisit(LabeledStatement labeledStatement, BlockScope scope) { + } + public void endVisit(LocalDeclaration localDeclaration, BlockScope scope) { + } + public void endVisit(LongLiteral longLiteral, BlockScope scope) { + } + public void endVisit( + MemberTypeDeclaration memberTypeDeclaration, + ClassScope scope) { + } + public void endVisit(MessageSend messageSend, BlockScope scope) { + } + public void endVisit(MethodDeclaration methodDeclaration, ClassScope scope) { + } + public void endVisit(NullLiteral nullLiteral, BlockScope scope) { + } + public void endVisit(OR_OR_Expression or_or_Expression, BlockScope scope) { + } + public void endVisit(PostfixExpression postfixExpression, BlockScope scope) { + } + public void endVisit(PrefixExpression prefixExpression, BlockScope scope) { + } + public void endVisit( + QualifiedAllocationExpression qualifiedAllocationExpression, + BlockScope scope) { + } + public void endVisit( + QualifiedNameReference qualifiedNameReference, + BlockScope scope) { + } + public void endVisit( + QualifiedSuperReference qualifiedSuperReference, + BlockScope scope) { + } + public void endVisit( + QualifiedThisReference qualifiedThisReference, + BlockScope scope) { + } + public void endVisit( + QualifiedTypeReference qualifiedTypeReference, + BlockScope scope) { + } + public void endVisit( + QualifiedTypeReference qualifiedTypeReference, + ClassScope scope) { + } + public void endVisit(ReturnStatement returnStatement, BlockScope scope) { + } + public void endVisit( + SingleNameReference singleNameReference, + BlockScope scope) { + } + public void endVisit( + SingleTypeReference singleTypeReference, + BlockScope scope) { + } + public void endVisit( + SingleTypeReference singleTypeReference, + ClassScope scope) { + } + public void endVisit(StringLiteral stringLiteral, BlockScope scope) { + } + public void endVisit(SuperReference superReference, BlockScope scope) { + } + public void endVisit(SwitchStatement switchStatement, BlockScope scope) { + } + public void endVisit( + SynchronizedStatement synchronizedStatement, + BlockScope scope) { + } + public void endVisit(ThisReference thisReference, BlockScope scope) { + } + public void endVisit(ThrowStatement throwStatement, BlockScope scope) { + } + public void endVisit(TrueLiteral trueLiteral, BlockScope scope) { + } + public void endVisit(TryStatement tryStatement, BlockScope scope) { + } + public void endVisit( + TypeDeclaration typeDeclaration, + CompilationUnitScope scope) { + } + public void endVisit(UnaryExpression unaryExpression, BlockScope scope) { + } + public void endVisit(WhileStatement whileStatement, BlockScope scope) { + } + public boolean visit( + AllocationExpression allocationExpression, + BlockScope scope) { + return true; + } + public boolean visit(AND_AND_Expression and_and_Expression, BlockScope scope) { + return true; + } + public boolean visit( + AnonymousLocalTypeDeclaration anonymousTypeDeclaration, + BlockScope scope) { + return true; + } + public boolean visit(Argument argument, BlockScope scope) { + return true; + } + public boolean visit( + ArrayAllocationExpression arrayAllocationExpression, + BlockScope scope) { + return true; + } + public boolean visit(ArrayInitializer arrayInitializer, BlockScope scope) { + return true; + } + public boolean visit( + ArrayQualifiedTypeReference arrayQualifiedTypeReference, + BlockScope scope) { + return true; + } + public boolean visit( + ArrayQualifiedTypeReference arrayQualifiedTypeReference, + ClassScope scope) { + return true; + } + public boolean visit(ArrayReference arrayReference, BlockScope scope) { + return true; + } + public boolean visit(ArrayTypeReference arrayTypeReference, BlockScope scope) { + return true; + } + public boolean visit(ArrayTypeReference arrayTypeReference, ClassScope scope) { + return true; + } + public boolean visit(Assignment assignment, BlockScope scope) { + return true; + } + public boolean visit(AssertStatement assertStatement, BlockScope scope) { + return true; + } + public boolean visit(BinaryExpression binaryExpression, BlockScope scope) { + return true; + } + public boolean visit(Block block, BlockScope scope) { + return true; + } + public boolean visit(Break breakStatement, BlockScope scope) { + return true; + } + public boolean visit(Case caseStatement, BlockScope scope) { + return true; + } + public boolean visit(CastExpression castExpression, BlockScope scope) { + return true; + } + public boolean visit(CharLiteral charLiteral, BlockScope scope) { + return true; + } + public boolean visit(ClassLiteralAccess classLiteral, BlockScope scope) { + return true; + } + public boolean visit(Clinit clinit, ClassScope scope) { + return true; + } + public boolean visit( + CompilationUnitDeclaration compilationUnitDeclaration, + CompilationUnitScope scope) { + return true; + } + public boolean visit(CompoundAssignment compoundAssignment, BlockScope scope) { + return true; + } + public boolean visit( + ConditionalExpression conditionalExpression, + BlockScope scope) { + return true; + } + public boolean visit( + ConstructorDeclaration constructorDeclaration, + ClassScope scope) { + return true; + } + public boolean visit(Continue continueStatement, BlockScope scope) { + return true; + } + public boolean visit(DefaultCase defaultCaseStatement, BlockScope scope) { + return true; + } + public boolean visit(DoStatement doStatement, BlockScope scope) { + return true; + } + public boolean visit(DoubleLiteral doubleLiteral, BlockScope scope) { + return true; + } + public boolean visit(EqualExpression equalExpression, BlockScope scope) { + return true; + } + public boolean visit(EmptyStatement emptyStatement, BlockScope scope) { + return true; + } + public boolean visit( + ExplicitConstructorCall explicitConstructor, + BlockScope scope) { + return true; + } + public boolean visit( + ExtendedStringLiteral extendedStringLiteral, + BlockScope scope) { + return true; + } + public boolean visit(FalseLiteral falseLiteral, BlockScope scope) { + return true; + } + public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) { + return true; + } + public boolean visit(FieldReference fieldReference, BlockScope scope) { + return true; + } + public boolean visit(FloatLiteral floatLiteral, BlockScope scope) { + return true; + } + public boolean visit(ForStatement forStatement, BlockScope scope) { + return true; + } + public boolean visit(IfStatement ifStatement, BlockScope scope) { + return true; + } + public boolean visit(ImportReference importRef, CompilationUnitScope scope) { + return true; + } + public boolean visit(Initializer initializer, MethodScope scope) { + return true; + } + public boolean visit( + InstanceOfExpression instanceOfExpression, + BlockScope scope) { + return true; + } + public boolean visit(IntLiteral intLiteral, BlockScope scope) { + return true; + } + public boolean visit(LabeledStatement labeledStatement, BlockScope scope) { + return true; + } + public boolean visit(LocalDeclaration localDeclaration, BlockScope scope) { + return true; + } + public boolean visit(LongLiteral longLiteral, BlockScope scope) { + return true; + } + public boolean visit( + MemberTypeDeclaration memberTypeDeclaration, + ClassScope scope) { + return true; + } + public boolean visit(MessageSend messageSend, BlockScope scope) { + return true; + } + public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) { + return true; + } + public boolean visit(NullLiteral nullLiteral, BlockScope scope) { + return true; + } + public boolean visit(OR_OR_Expression or_or_Expression, BlockScope scope) { + return true; + } + public boolean visit(PostfixExpression postfixExpression, BlockScope scope) { + return true; + } + public boolean visit(PrefixExpression prefixExpression, BlockScope scope) { + return true; + } + public boolean visit( + QualifiedAllocationExpression qualifiedAllocationExpression, + BlockScope scope) { + return true; + } + public boolean visit( + QualifiedNameReference qualifiedNameReference, + BlockScope scope) { + return true; + } + public boolean visit( + QualifiedSuperReference qualifiedSuperReference, + BlockScope scope) { + return true; + } + public boolean visit( + QualifiedThisReference qualifiedThisReference, + BlockScope scope) { + return true; + } + public boolean visit( + QualifiedTypeReference qualifiedTypeReference, + BlockScope scope) { + return true; + } + public boolean visit( + QualifiedTypeReference qualifiedTypeReference, + ClassScope scope) { + return true; + } + public boolean visit(ReturnStatement returnStatement, BlockScope scope) { + return true; + } + public boolean visit( + SingleNameReference singleNameReference, + BlockScope scope) { + return true; + } + public boolean visit( + SingleTypeReference singleTypeReference, + BlockScope scope) { + return true; + } + public boolean visit( + SingleTypeReference singleTypeReference, + ClassScope scope) { + return true; + } + public boolean visit(StringLiteral stringLiteral, BlockScope scope) { + return true; + } + public boolean visit(SuperReference superReference, BlockScope scope) { + return true; + } + public boolean visit(SwitchStatement switchStatement, BlockScope scope) { + return true; + } + public boolean visit( + SynchronizedStatement synchronizedStatement, + BlockScope scope) { + return true; + } + public boolean visit(ThisReference thisReference, BlockScope scope) { + return true; + } + public boolean visit(ThrowStatement throwStatement, BlockScope scope) { + return true; + } + public boolean visit(TrueLiteral trueLiteral, BlockScope scope) { + return true; + } + public boolean visit(TryStatement tryStatement, BlockScope scope) { + return true; + } + public boolean visit( + TypeDeclaration typeDeclaration, + CompilationUnitScope scope) { + return true; + } + public boolean visit(UnaryExpression unaryExpression, BlockScope scope) { + return true; + } + public boolean visit(WhileStatement whileStatement, BlockScope scope) { + return true; + } + public boolean visit( + LocalTypeDeclaration localTypeDeclaration, + BlockScope scope) { + return true; + } + public void endVisit( + LocalTypeDeclaration localTypeDeclaration, + BlockScope scope) { + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/CompilationResult.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/CompilationResult.java new file mode 100644 index 0000000..90d5434 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/CompilationResult.java @@ -0,0 +1,430 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler; + +/** + * A compilation result consists of all information returned by the compiler for + * a single compiled compilation source unit. This includes: + *
      + *
    • the compilation unit that was compiled + *
    • for each type produced by compiling the compilation unit, its binary and optionally its principal structure + *
    • any problems (errors or warnings) produced + *
    • dependency info + *
    + * + * The principle structure and binary may be null if the compiler could not produce them. + * If neither could be produced, there is no corresponding entry for the type. + * + * The dependency info includes type references such as supertypes, field types, method + * parameter and return types, local variable types, types of intermediate expressions, etc. + * It also includes the namespaces (packages) in which names were looked up. + * It does not include finer grained dependencies such as information about + * specific fields and methods which were referenced, but does contain their + * declaring types and any other types used to locate such fields or methods. + */ + + + +//import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Map; + +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; +import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; + +public class CompilationResult { + + public IProblem problems[]; + public IProblem tasks[]; + public int problemCount; + public int taskCount; + public ICompilationUnit compilationUnit; + private Map problemsMap; + private Map firstErrorsMap; + private int maxProblemPerUnit; + public char[][][] qualifiedReferences; + public char[][] simpleNameReferences; + + public int lineSeparatorPositions[]; +// public Hashtable compiledTypes = new Hashtable(11); + public int unitIndex, totalUnitsKnown; + public boolean hasBeenAccepted = false; + public char[] fileName; + + public CompilationResult( + char[] fileName, + int unitIndex, + int totalUnitsKnown, + int maxProblemPerUnit){ + + this.fileName = fileName; + this.unitIndex = unitIndex; + this.totalUnitsKnown = totalUnitsKnown; + this.maxProblemPerUnit = maxProblemPerUnit; + } + + public CompilationResult( + ICompilationUnit compilationUnit, + int unitIndex, + int totalUnitsKnown, + int maxProblemPerUnit){ + + this.fileName = compilationUnit.getFileName(); + this.compilationUnit = compilationUnit; + this.unitIndex = unitIndex; + this.totalUnitsKnown = totalUnitsKnown; + this.maxProblemPerUnit = maxProblemPerUnit; + } + + private int computePriority(IProblem problem){ + + final int P_STATIC = 1000; + final int P_OUTSIDE_METHOD = 4000; + final int P_FIRST_ERROR = 2000; + final int P_ERROR = 10000; + + int priority = 1000 - problem.getSourceLineNumber(); // early problems first + if (priority < 0) priority = 0; + if (problem.isError()){ + priority += P_ERROR; + } + ReferenceContext context = problemsMap == null ? null : (ReferenceContext) problemsMap.get(problem); + if (context != null){ +// if (context instanceof AbstractMethodDeclaration){ +// AbstractMethodDeclaration method = (AbstractMethodDeclaration) context; +// if (method.isStatic()) { +// priority += P_STATIC; +// } +// } else { + priority += P_OUTSIDE_METHOD; +// } + } else { + priority += P_OUTSIDE_METHOD; + } + if (firstErrorsMap.containsKey(problem)){ + priority += P_FIRST_ERROR; + } + return priority; + } + + + public IProblem[] getAllProblems() { + IProblem[] problems = this.getProblems(); + int problemCount = problems != null ? problems.length : 0; + IProblem[] tasks = this.getTasks(); + int taskCount = tasks != null ? tasks.length : 0; + if (taskCount == 0) { + return problems; + } + if (problemCount == 0) { + return tasks; + } + + int totalNumberOfProblem = problemCount + taskCount; + IProblem[] allProblems = new IProblem[totalNumberOfProblem]; + int allProblemIndex = 0; + int taskIndex = 0; + int problemIndex = 0; + while (taskIndex + problemIndex < totalNumberOfProblem) { + IProblem nextTask = null; + IProblem nextProblem = null; + if (taskIndex < taskCount) { + nextTask = tasks[taskIndex]; + } + if (problemIndex < problemCount) { + nextProblem = problems[problemIndex]; + } + // select the next problem + IProblem currentProblem = null; + if (nextProblem != null) { + if (nextTask != null) { + if (nextProblem.getSourceStart() < nextTask.getSourceStart()) { + currentProblem = nextProblem; + problemIndex++; + } else { + currentProblem = nextTask; + taskIndex++; + } + } else { + currentProblem = nextProblem; + problemIndex++; + } + } else { + if (nextTask != null) { + currentProblem = nextTask; + taskIndex++; + } + } + allProblems[allProblemIndex++] = currentProblem; + } + return allProblems; + } + +// public ClassFile[] getClassFiles() { +// Enumeration enum = compiledTypes.elements(); +// ClassFile[] classFiles = new ClassFile[compiledTypes.size()]; +// int index = 0; +// while (enum.hasMoreElements()){ +// classFiles[index++] = (ClassFile)enum.nextElement(); +// } +// return classFiles; +// } + + /** + * Answer the initial compilation unit corresponding to the present compilation result + */ + public ICompilationUnit getCompilationUnit(){ + return compilationUnit; + } + + /** + * Answer the initial file name + */ + public char[] getFileName(){ + return fileName; + } + + /** + * Answer the errors encountered during compilation. + */ + public IProblem[] getErrors() { + + IProblem[] problems = getProblems(); + int errorCount = 0; + for (int i = 0; i < this.problemCount; i++) { + if (problems[i].isError()) errorCount++; + } + if (errorCount == this.problemCount) return problems; + IProblem[] errors = new IProblem[errorCount]; + int index = 0; + for (int i = 0; i < this.problemCount; i++) { + if (problems[i].isError()) errors[index++] = problems[i]; + } + return errors; + } + + /** + * Answer the problems (errors and warnings) encountered during compilation. + * + * This is not a compiler internal API - it has side-effects ! + * It is intended to be used only once all problems have been detected, + * and makes sure the problems slot as the exact size of the number of + * problems. + */ + public IProblem[] getProblems() { + + // Re-adjust the size of the problems if necessary. + if (problems != null) { + + if (this.problemCount != problems.length) { + System.arraycopy(problems, 0, (problems = new IProblem[problemCount]), 0, problemCount); + } + + if (this.maxProblemPerUnit > 0 && this.problemCount > this.maxProblemPerUnit){ + quickPrioritize(problems, 0, problemCount - 1); + this.problemCount = this.maxProblemPerUnit; + System.arraycopy(problems, 0, (problems = new IProblem[problemCount]), 0, problemCount); + } + + // Sort problems per source positions. + quickSort(problems, 0, problems.length-1); + } + return problems; + } + + /** + * Answer the tasks (TO-DO, ...) encountered during compilation. + * + * This is not a compiler internal API - it has side-effects ! + * It is intended to be used only once all problems have been detected, + * and makes sure the problems slot as the exact size of the number of + * problems. + */ + public IProblem[] getTasks() { + + // Re-adjust the size of the tasks if necessary. + if (this.tasks != null) { + + if (this.taskCount != this.tasks.length) { + System.arraycopy(this.tasks, 0, (this.tasks = new IProblem[this.taskCount]), 0, this.taskCount); + } + quickSort(tasks, 0, tasks.length-1); + } + return this.tasks; + } + + public boolean hasErrors() { + + if (problems != null) + for (int i = 0; i < problemCount; i++) { + if (problems[i].isError()) + return true; + } + return false; + } + + public boolean hasProblems() { + + return problemCount != 0; + } + + public boolean hasSyntaxError(){ + + if (problems != null) + for (int i = 0; i < problemCount; i++) { + IProblem problem = problems[i]; + if ((problem.getID() & IProblem.Syntax) != 0 && problem.isError()) + return true; + } + return false; + } + + public boolean hasTasks() { + return this.taskCount != 0; + } + + public boolean hasWarnings() { + + if (problems != null) + for (int i = 0; i < problemCount; i++) { + if (problems[i].isWarning()) + return true; + } + return false; + } + + private static void quickSort(IProblem[] list, int left, int right) { + + if (left >= right) return; + + // sort the problems by their source start position... starting with 0 + int original_left = left; + int original_right = right; + int mid = list[(left + right) / 2].getSourceStart(); + do { + while (list[left].getSourceStart() < mid) + left++; + while (mid < list[right].getSourceStart()) + right--; + if (left <= right) { + IProblem tmp = list[left]; + list[left] = list[right]; + list[right] = tmp; + left++; + right--; + } + } while (left <= right); + if (original_left < right) + quickSort(list, original_left, right); + if (left < original_right) + quickSort(list, left, original_right); + } + + private void quickPrioritize(IProblem[] list, int left, int right) { + + if (left >= right) return; + + // sort the problems by their priority... starting with the highest priority + int original_left = left; + int original_right = right; + int mid = computePriority(list[(left + right) / 2]); + do { + while (computePriority(list[right]) < mid) + right--; + while (mid < computePriority(list[left])) + left++; + if (left <= right) { + IProblem tmp = list[left]; + list[left] = list[right]; + list[right] = tmp; + left++; + right--; + } + } while (left <= right); + if (original_left < right) + quickPrioritize(list, original_left, right); + if (left < original_right) + quickPrioritize(list, left, original_right); + } + + /** + * For now, remember the compiled type using its compound name. + */ +// public void record(char[] typeName, ClassFile classFile) { +// +// compiledTypes.put(typeName, classFile); +// } + + public void record(IProblem newProblem, ReferenceContext referenceContext) { + + if (newProblem.getID() == IProblem.Task) { + recordTask(newProblem); + return; + } + if (problemCount == 0) { + problems = new IProblem[5]; + } else if (problemCount == problems.length) { + System.arraycopy(problems, 0, (problems = new IProblem[problemCount * 2]), 0, problemCount); + } + problems[problemCount++] = newProblem; + if (referenceContext != null){ + if (problemsMap == null) problemsMap = new Hashtable(5); + if (firstErrorsMap == null) firstErrorsMap = new Hashtable(5); + if (newProblem.isError() && !referenceContext.hasErrors()) firstErrorsMap.put(newProblem, newProblem); + problemsMap.put(newProblem, referenceContext); + } + } + + private void recordTask(IProblem newProblem) { + if (this.taskCount == 0) { + this.tasks = new IProblem[5]; + } else if (this.taskCount == this.tasks.length) { + System.arraycopy(this.tasks, 0, (this.tasks = new IProblem[this.taskCount * 2]), 0, this.taskCount); + } + this.tasks[this.taskCount++] = newProblem; + } + + public CompilationResult tagAsAccepted(){ + + this.hasBeenAccepted = true; + this.problemsMap = null; // flush + return this; + } + + public String toString(){ + + StringBuffer buffer = new StringBuffer(); + if (this.fileName != null){ + buffer.append("Filename : ").append(this.fileName).append('\n'); //$NON-NLS-1$ + } +// if (this.compiledTypes != null){ +// buffer.append("COMPILED type(s) \n"); //$NON-NLS-1$ +// Enumeration typeNames = this.compiledTypes.keys(); +// while (typeNames.hasMoreElements()) { +// char[] typeName = (char[]) typeNames.nextElement(); +// buffer.append("\t - ").append(typeName).append('\n'); //$NON-NLS-1$ +// +// } +// } else { +// buffer.append("No COMPILED type\n"); //$NON-NLS-1$ +// } + if (problems != null){ + buffer.append(this.problemCount).append(" PROBLEM(s) detected \n"); //$NON-NLS-1$//$NON-NLS-2$ + for (int i = 0; i < this.problemCount; i++){ + buffer.append("\t - ").append(this.problems[i]).append('\n'); //$NON-NLS-1$ + } + } else { + buffer.append("No PROBLEM\n"); //$NON-NLS-1$ + } + return buffer.toString(); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/Compiler.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/Compiler.java new file mode 100644 index 0000000..6583d9e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/Compiler.java @@ -0,0 +1,628 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Map; + +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.env.IBinaryType; +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; +import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment; +import net.sourceforge.phpdt.internal.compiler.env.ISourceType; +import net.sourceforge.phpdt.internal.compiler.impl.ITypeRequestor; +import net.sourceforge.phpdt.internal.compiler.lookup.LookupEnvironment; +import net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding; +import net.sourceforge.phpdt.internal.compiler.parser.UnitParser; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilationUnit; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; + +public class Compiler implements ITypeRequestor, ProblemSeverities { + public UnitParser parser; + public ICompilerRequestor requestor; +// public CompilerOptions options; + public ProblemReporter problemReporter; + + // management of unit to be processed + //public CompilationUnitResult currentCompilationUnitResult; + public CompilationUnitDeclaration[] unitsToProcess; + public int totalUnits; // (totalUnits-1) gives the last unit in unitToProcess + + // name lookup + public LookupEnvironment lookupEnvironment; + + // ONCE STABILIZED, THESE SHOULD RETURN TO A FINAL FIELD + public static boolean DEBUG = false; + public int parseThreshold = -1; + // number of initial units parsed at once (-1: none) + + /* + * Static requestor reserved to listening compilation results in debug mode, + * so as for example to monitor compiler activity independantly from a particular + * builder implementation. It is reset at the end of compilation, and should not + * persist any information after having been reset. + */ +// public static IDebugRequestor DebugRequestor = null; + + /** + * Answer a new compiler using the given name environment and compiler options. + * The environment and options will be in effect for the lifetime of the compiler. + * When the compiler is run, compilation results are sent to the given requestor. + * + * @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment + * Environment used by the compiler in order to resolve type and package + * names. The name environment implements the actual connection of the compiler + * to the outside world (e.g. in batch mode the name environment is performing + * pure file accesses, reuse previous build state or connection to repositories). + * Note: the name environment is responsible for implementing the actual classpath + * rules. + * + * @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy + * Configurable part for problem handling, allowing the compiler client to + * specify the rules for handling problems (stop on first error or accumulate + * them all) and at the same time perform some actions such as opening a dialog + * in UI when compiling interactively. + * @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies + * + * @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor + * Component which will receive and persist all compilation results and is intended + * to consume them as they are produced. Typically, in a batch compiler, it is + * responsible for writing out the actual .class files to the file system. + * @see org.eclipse.jdt.internal.compiler.CompilationResult + * + * @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory + * Factory used inside the compiler to create problem descriptors. It allows the + * compiler client to supply its own representation of compilation problems in + * order to avoid object conversions. Note that the factory is not supposed + * to accumulate the created problems, the compiler will gather them all and hand + * them back as part of the compilation unit result. + */ + public Compiler( + INameEnvironment environment, + IErrorHandlingPolicy policy, +// Map settings, + final ICompilerRequestor requestor, + IProblemFactory problemFactory) { + + // create a problem handler given a handling policy +// this.options = new CompilerOptions(settings); + + // wrap requestor in DebugRequestor if one is specified +// if(DebugRequestor == null) { + this.requestor = requestor; +// } else { +// this.requestor = new ICompilerRequestor(){ +// public void acceptResult(CompilationResult result){ +// if (DebugRequestor.isActive()){ +// DebugRequestor.acceptDebugResult(result); +// } +// requestor.acceptResult(result); +// } +// }; +// } + this.problemReporter = + new ProblemReporter(policy, problemFactory);//this.options, problemFactory); + this.lookupEnvironment = + new LookupEnvironment(this, problemReporter, environment); //options, problemReporter, environment); + this.parser = + new UnitParser( + problemReporter); +// this.options.parseLiteralExpressionsAsConstants, +// options.sourceLevel >= CompilerOptions.JDK1_4); + } + + /** + * Answer a new compiler using the given name environment and compiler options. + * The environment and options will be in effect for the lifetime of the compiler. + * When the compiler is run, compilation results are sent to the given requestor. + * + * @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment + * Environment used by the compiler in order to resolve type and package + * names. The name environment implements the actual connection of the compiler + * to the outside world (e.g. in batch mode the name environment is performing + * pure file accesses, reuse previous build state or connection to repositories). + * Note: the name environment is responsible for implementing the actual classpath + * rules. + * + * @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy + * Configurable part for problem handling, allowing the compiler client to + * specify the rules for handling problems (stop on first error or accumulate + * them all) and at the same time perform some actions such as opening a dialog + * in UI when compiling interactively. + * @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies + * + * @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor + * Component which will receive and persist all compilation results and is intended + * to consume them as they are produced. Typically, in a batch compiler, it is + * responsible for writing out the actual .class files to the file system. + * @see org.eclipse.jdt.internal.compiler.CompilationResult + * + * @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory + * Factory used inside the compiler to create problem descriptors. It allows the + * compiler client to supply its own representation of compilation problems in + * order to avoid object conversions. Note that the factory is not supposed + * to accumulate the created problems, the compiler will gather them all and hand + * them back as part of the compilation unit result. + * @param parseLiteralExpressionsAsConstants boolean + * This parameter is used to optimize the literals or leave them as they are in the source. + * If you put true, "Hello" + " world" will be converted to "Hello world". + */ + public Compiler( + INameEnvironment environment, + IErrorHandlingPolicy policy, +// Map settings, + final ICompilerRequestor requestor, + IProblemFactory problemFactory, + boolean parseLiteralExpressionsAsConstants) { + + // create a problem handler given a handling policy +// this.options = new CompilerOptions(settings); + + // wrap requestor in DebugRequestor if one is specified +// if(DebugRequestor == null) { + this.requestor = requestor; +// } else { +// this.requestor = new ICompilerRequestor(){ +// public void acceptResult(CompilationResult result){ +// if (DebugRequestor.isActive()){ +// DebugRequestor.acceptDebugResult(result); +// } +// requestor.acceptResult(result); +// } +// }; +// } + this.problemReporter = + new ProblemReporter(policy, problemFactory);//, this.options, problemFactory); + this.lookupEnvironment = + new LookupEnvironment(this, problemReporter, environment);//options, problemReporter, environment); + this.parser = + new UnitParser( + problemReporter); +// parseLiteralExpressionsAsConstants, + // this.options.sourceLevel >= CompilerOptions.JDK1_4); + } + + /** + * Add an additional binary type + */ + public void accept(IBinaryType binaryType, PackageBinding packageBinding) { + lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding); + } + + /** + * Add an additional compilation unit into the loop + * -> build compilation unit declarations, their bindings and record their results. + */ + public void accept(ICompilationUnit sourceUnit) { + // Switch the current policy and compilation result for this unit to the requested one. + CompilationResult unitResult = + new CompilationResult(sourceUnit, totalUnits, totalUnits, 10); //this.options.maxProblemsPerUnit); + try { + // diet parsing for large collection of unit + CompilationUnitDeclaration parsedUnit; + if (totalUnits < parseThreshold) { + parsedUnit = parser.parse(sourceUnit, unitResult); + } else { + parsedUnit = parser.dietParse(sourceUnit, unitResult); + } + +// if (options.verbose) { +// String count = String.valueOf(totalUnits + 1); +// System.out.println( +// Util.bind( +// "compilation.request" , //$NON-NLS-1$ +// new String[] { +// count, +// count, +// new String(sourceUnit.getFileName())})); +// } + + // initial type binding creation + lookupEnvironment.buildTypeBindings(parsedUnit); + this.addCompilationUnit(sourceUnit, parsedUnit); + + // binding resolution + lookupEnvironment.completeTypeBindings(parsedUnit); + } catch (AbortCompilationUnit e) { + // at this point, currentCompilationUnitResult may not be sourceUnit, but some other + // one requested further along to resolve sourceUnit. + if (unitResult.compilationUnit == sourceUnit) { // only report once + requestor.acceptResult(unitResult.tagAsAccepted()); + } else { + throw e; // want to abort enclosing request to compile + } + } + } + + /** + * Add additional source types + */ + public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding) { + problemReporter.abortDueToInternalError( + Util.bind( + "abort.againstSourceModel " , //$NON-NLS-1$ + String.valueOf(sourceTypes[0].getName()), + String.valueOf(sourceTypes[0].getFileName()))); + } + + protected void addCompilationUnit( + ICompilationUnit sourceUnit, + CompilationUnitDeclaration parsedUnit) { + + // append the unit to the list of ones to process later on + int size = unitsToProcess.length; + if (totalUnits == size) + // when growing reposition units starting at position 0 + System.arraycopy( + unitsToProcess, + 0, + (unitsToProcess = new CompilationUnitDeclaration[size * 2]), + 0, + totalUnits); + unitsToProcess[totalUnits++] = parsedUnit; + } + + /** + * Add the initial set of compilation units into the loop + * -> build compilation unit declarations, their bindings and record their results. + */ + protected void beginToCompile(ICompilationUnit[] sourceUnits) { + int maxUnits = sourceUnits.length; + totalUnits = 0; + unitsToProcess = new CompilationUnitDeclaration[maxUnits]; + + // Switch the current policy and compilation result for this unit to the requested one. + for (int i = 0; i < maxUnits; i++) { + CompilationUnitDeclaration parsedUnit; + CompilationResult unitResult = + new CompilationResult(sourceUnits[i], i, maxUnits, 10);//, this.options.maxProblemsPerUnit); + try { + // diet parsing for large collection of units + if (totalUnits < parseThreshold) { + parsedUnit = parser.parse(sourceUnits[i], unitResult); + } else { + parsedUnit = parser.dietParse(sourceUnits[i], unitResult); + } +// if (options.verbose) { +// System.out.println( +// Util.bind( +// "compilation.request" , //$NON-NLS-1$ +// new String[] { +// String.valueOf(i + 1), +// String.valueOf(maxUnits), +// new String(sourceUnits[i].getFileName())})); +// } + // initial type binding creation + lookupEnvironment.buildTypeBindings(parsedUnit); + this.addCompilationUnit(sourceUnits[i], parsedUnit); + //} catch (AbortCompilationUnit e) { + // requestor.acceptResult(unitResult.tagAsAccepted()); + } finally { + sourceUnits[i] = null; // no longer hold onto the unit + } + } + // binding resolution + lookupEnvironment.completeTypeBindings(); + } + + /** + * General API + * -> compile each of supplied files + * -> recompile any required types for which we have an incomplete principle structure + */ + public void compile(ICompilationUnit[] sourceUnits) { + CompilationUnitDeclaration unit = null; + int i = 0; + try { + // build and record parsed units + + beginToCompile(sourceUnits); + + // process all units (some more could be injected in the loop by the lookup environment) + for (; i < totalUnits; i++) { + unit = unitsToProcess[i]; + try { +// if (options.verbose) +// System.out.println( +// Util.bind( +// "compilation.process" , //$NON-NLS-1$ +// new String[] { +// String.valueOf(i + 1), +// String.valueOf(totalUnits), +// new String(unitsToProcess[i].getFileName())})); + process(unit, i); + } finally { + // cleanup compilation unit result + unit.cleanUp(); +// if (options.verbose) +// System.out.println(Util.bind("compilation.done", //$NON-NLS-1$ +// new String[] { +// String.valueOf(i + 1), +// String.valueOf(totalUnits), +// new String(unitsToProcess[i].getFileName())})); + } + unitsToProcess[i] = null; // release reference to processed unit declaration + requestor.acceptResult(unit.compilationResult.tagAsAccepted()); + } + } catch (AbortCompilation e) { + this.handleInternalException(e, unit); + } catch (Error e) { + this.handleInternalException(e, unit, null); + throw e; // rethrow + } catch (RuntimeException e) { + this.handleInternalException(e, unit, null); + throw e; // rethrow + } finally { + this.reset(); + } +// if (options.verbose) { +// if (totalUnits > 1) { +// System.out.println( +// Util.bind("compilation.units" , String.valueOf(totalUnits))); //$NON-NLS-1$ +// } else { +// System.out.println( +// Util.bind("compilation.unit" , String.valueOf(totalUnits))); //$NON-NLS-1$ +// } +// } + } + + protected void getMethodBodies(CompilationUnitDeclaration unit, int place) { + //fill the methods bodies in order for the code to be generated + + if (unit.ignoreMethodBodies) { + unit.ignoreFurtherInvestigation = true; + return; + // if initial diet parse did not work, no need to dig into method bodies. + } + + if (place < parseThreshold) + return; //work already done ... + + //real parse of the method.... + parser.scanner.setSource( + unit.compilationResult.compilationUnit.getContents()); + if (unit.types != null) { + for (int i = unit.types.size(); --i >= 0;) + if (unit.types.get(i) instanceof TypeDeclaration) { + ((TypeDeclaration)unit.types.get(i)).parseMethod(parser, unit); + } + } + } + + /* + * Compiler crash recovery in case of unexpected runtime exceptions + */ + protected void handleInternalException( + Throwable internalException, + CompilationUnitDeclaration unit, + CompilationResult result) { + + /* dump a stack trace to the console */ + internalException.printStackTrace(); + + /* find a compilation result */ + if ((unit != null)) // basing result upon the current unit if available + result = unit.compilationResult; // current unit being processed ? + if ((result == null) && (unitsToProcess != null) && (totalUnits > 0)) + result = unitsToProcess[totalUnits - 1].compilationResult; + // last unit in beginToCompile ? + + if (result != null) { + /* create and record a compilation problem */ + StringWriter stringWriter = new StringWriter(); + PrintWriter writer = new PrintWriter(stringWriter); + internalException.printStackTrace(writer); + StringBuffer buffer = stringWriter.getBuffer(); + + String[] pbArguments = new String[] { + Util.bind("compilation.internalError" ) //$NON-NLS-1$ + + "\n" //$NON-NLS-1$ + + buffer.toString()}; + + result + .record( + problemReporter + .createProblem( + result.getFileName(), + IProblem.Unclassified, + pbArguments, + pbArguments, + Error, // severity + 0, // source start + 0, // source end + 0, // line number + unit, + result), + unit); + + /* hand back the compilation result */ + if (!result.hasBeenAccepted) { + requestor.acceptResult(result.tagAsAccepted()); + } + } + } + + /* + * Compiler recovery in case of internal AbortCompilation event + */ + protected void handleInternalException( + AbortCompilation abortException, + CompilationUnitDeclaration unit) { + + /* special treatment for SilentAbort: silently cancelling the compilation process */ + if (abortException.isSilent) { + if (abortException.silentException == null) { + return; + } else { + throw abortException.silentException; + } + } + + /* uncomment following line to see where the abort came from */ + // abortException.printStackTrace(); + + // Exception may tell which compilation result it is related, and which problem caused it + CompilationResult result = abortException.compilationResult; + if ((result == null) && (unit != null)) + result = unit.compilationResult; // current unit being processed ? + if ((result == null) && (unitsToProcess != null) && (totalUnits > 0)) + result = unitsToProcess[totalUnits - 1].compilationResult; + // last unit in beginToCompile ? + if (result != null && !result.hasBeenAccepted) { + /* distant problem which could not be reported back there */ + if (abortException.problemId != 0) { + result + .record( + problemReporter + .createProblem( + result.getFileName(), + abortException.problemId, + abortException.problemArguments, + abortException.messageArguments, + Error, // severity + 0, // source start + 0, // source end + 0, // line number + unit, + result), + unit); + } else { + /* distant internal exception which could not be reported back there */ + if (abortException.exception != null) { + this.handleInternalException(abortException.exception, null, result); + return; + } + } + /* hand back the compilation result */ + if (!result.hasBeenAccepted) { + requestor.acceptResult(result.tagAsAccepted()); + } + } else { + /* + if (abortException.problemId != 0){ + IProblem problem = + problemReporter.createProblem( + "???".toCharArray(), + abortException.problemId, + abortException.problemArguments, + Error, // severity + 0, // source start + 0, // source end + 0); // line number + System.out.println(problem.getMessage()); + } + */ + abortException.printStackTrace(); + } + } + + /** + * Process a compilation unit already parsed and build. + */ + public void process(CompilationUnitDeclaration unit, int i) { + + getMethodBodies(unit, i); + + // fault in fields & methods + if (unit.scope != null) + unit.scope.faultInTypes(); + + // verify inherited methods + if (unit.scope != null) + unit.scope.verifyMethods(lookupEnvironment.methodVerifier()); + + // type checking + unit.resolve(); + + // flow analysis + unit.analyseCode(); + + // code generation +// unit.generateCode(); + + // reference info +// if (options.produceReferenceInfo && unit.scope != null) +// unit.scope.storeDependencyInfo(); + + // refresh the total number of units known at this stage + unit.compilationResult.totalUnitsKnown = totalUnits; + } + public void reset() { + lookupEnvironment.reset(); + parser.scanner.source = null; + unitsToProcess = null; +// if (DebugRequestor != null) DebugRequestor.reset(); + } + + /** + * Internal API used to resolve a given compilation unit. Can run a subset of the compilation process + */ + public CompilationUnitDeclaration resolve( + ICompilationUnit sourceUnit, + boolean verifyMethods, + boolean analyzeCode) { +// boolean generateCode) { + + CompilationUnitDeclaration unit = null; + try { + // build and record parsed units + parseThreshold = 0; // will request a full parse + beginToCompile(new ICompilationUnit[] { sourceUnit }); + // process all units (some more could be injected in the loop by the lookup environment) + unit = unitsToProcess[0]; + getMethodBodies(unit, 0); + if (unit.scope != null) { +// // fault in fields & methods +// unit.scope.faultInTypes(); + +// if (unit.scope != null && verifyMethods) { +// // http://dev.eclipse.org/bugs/show_bug.cgi?id=23117 +// // verify inherited methods +// unit.scope.verifyMethods(lookupEnvironment.methodVerifier()); +// } +// // type checking +// unit.resolve(); + + // flow analysis +// if (analyzeCode) unit.analyseCode(); + + // code generation +// if (generateCode) unit.generateCode(); + } + unitsToProcess[0] = null; // release reference to processed unit declaration + requestor.acceptResult(unit.compilationResult.tagAsAccepted()); + return unit; + } catch (AbortCompilation e) { + this.handleInternalException(e, unit); + return unit == null ? unitsToProcess[0] : unit; + } catch (Error e) { + this.handleInternalException(e, unit, null); + throw e; // rethrow + } catch (RuntimeException e) { + this.handleInternalException(e, unit, null); + throw e; // rethrow + } finally { + // No reset is performed there anymore since, + // within the CodeAssist (or related tools), + // the compiler may be called *after* a call + // to this resolve(...) method. And such a call + // needs to have a compiler with a non-empty + // environment. + // this.reset(); + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/DefaultErrorHandlingPolicies.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/DefaultErrorHandlingPolicies.java new file mode 100644 index 0000000..19152b4 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/DefaultErrorHandlingPolicies.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler; + +public class DefaultErrorHandlingPolicies { + +/* + * Accumulate all problems, then exit without proceeding. + * + * Typically, the #proceedWithProblems(Problem[]) should + * show the problems. + * + */ +public static IErrorHandlingPolicy exitAfterAllProblems() { + return new IErrorHandlingPolicy() { + public boolean stopOnFirstError() { + return false; + } + public boolean proceedOnErrors(){ + return false; + } + }; +} +/* + * Exit without proceeding on the first problem wich appears + * to be an error. + * + */ +public static IErrorHandlingPolicy exitOnFirstError() { + return new IErrorHandlingPolicy() { + public boolean stopOnFirstError() { + return true; + } + public boolean proceedOnErrors(){ + return false; + } + }; +} +/* + * Proceed on the first error met. + * + */ +public static IErrorHandlingPolicy proceedOnFirstError() { + return new IErrorHandlingPolicy() { + public boolean stopOnFirstError() { + return true; + } + public boolean proceedOnErrors(){ + return true; + } + }; +} +/* + * Accumulate all problems, then proceed with them. + * + */ +public static IErrorHandlingPolicy proceedWithAllProblems() { + return new IErrorHandlingPolicy() { + public boolean stopOnFirstError() { + return false; + } + public boolean proceedOnErrors(){ + return true; + } + }; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/DocumentElementParser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/DocumentElementParser.java new file mode 100644 index 0000000..f2cb849 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/DocumentElementParser.java @@ -0,0 +1,1319 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; +import net.sourceforge.phpdt.internal.compiler.parser.UnitParser; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; + +import org.eclipse.core.runtime.CoreException; + + +/* + * A document element parser extracts structural information + * from a piece of source, providing detailed source positions info. + * + * also see @IDocumentElementRequestor + * + * The structural investigation includes: + * - the package statement + * - import statements + * - top-level types: package member, member types (member types of member types...) + * - fields + * - methods + * + * Any (parsing) problem encountered is also provided. + */ +public class DocumentElementParser extends UnitParser { + IDocumentElementRequestor requestor; + private int localIntPtr; + private int lastFieldEndPosition; + private int lastFieldBodyEndPosition; + private int typeStartPosition; + private long selectorSourcePositions; + private int typeDims; + private int extendsDim; + private int declarationSourceStart; + + /* int[] stack for storing javadoc positions */ + int[][] intArrayStack; + int intArrayPtr; + +// CompilerOptions options; + +public DocumentElementParser( + final IDocumentElementRequestor requestor, + IProblemFactory problemFactory) { +// CompilerOptions options) { + super(new ProblemReporter( + DefaultErrorHandlingPolicies.exitAfterAllProblems(), +// options, + problemFactory) { + public void record(IProblem problem, CompilationResult unitResult) { + requestor.acceptProblem(problem); + } + }); +// false, +// options.sourceLevel >= CompilerOptions.JDK1_4); + this.requestor = requestor; + intArrayStack = new int[30][]; +// this.options = options; +} + +/** + * + * INTERNAL USE-ONLY + */ +//protected void adjustInterfaceModifiers() { +// intStack[intPtr - 2] |= AccInterface; +//} +/* + * Will clear the comment stack when looking + * for a potential JavaDoc which might contain @deprecated. + * + * Additionally, before investigating for @deprecated, retrieve the positions + * of the JavaDoc comments so as to notify requestor with them. + */ +//public void checkAnnotation() { +// +// /* persisting javadoc positions */ +// pushOnIntArrayStack(this.getJavaDocPositions()); +// boolean deprecated = false; +// int lastAnnotationIndex = -1; +// int commentPtr = scanner.commentPtr; +// +// //since jdk1.2 look only in the last java doc comment... +// nextComment : for (lastAnnotationIndex = scanner.commentPtr; lastAnnotationIndex >= 0; lastAnnotationIndex--){ +// //look for @deprecated into the first javadoc comment preceeding the declaration +// int commentSourceStart = scanner.commentStarts[lastAnnotationIndex]; +// // javadoc only (non javadoc comment have negative end positions.) +// if (modifiersSourceStart != -1 && modifiersSourceStart < commentSourceStart) { +// continue nextComment; +// } +// if (scanner.commentStops[lastAnnotationIndex] < 0) { +// continue nextComment; +// } +// int commentSourceEnd = scanner.commentStops[lastAnnotationIndex] - 1; //stop is one over +// char[] comment = scanner.source; +// +// deprecated = +// checkDeprecation( +// commentSourceStart, +// commentSourceEnd, +// comment); +// break nextComment; +// } +// if (deprecated) { +// checkAndSetModifiers(AccDeprecated); +// } +// // modify the modifier source start to point at the first comment +// if (commentPtr >= 0) { +// declarationSourceStart = scanner.commentStarts[0]; +// } +//} +/** + * + * INTERNAL USE-ONLY + */ +//protected void consumeClassBodyDeclaration() { +// // ClassBodyDeclaration ::= Diet Block +// //push an Initializer +// //optimize the push/pop +// +// super.consumeClassBodyDeclaration(); +// Initializer initializer = (Initializer) astStack[astPtr]; +// requestor.acceptInitializer( +// initializer.declarationSourceStart, +// initializer.declarationSourceEnd, +// intArrayStack[intArrayPtr--], +// 0, +// modifiersSourceStart, +// initializer.block.sourceStart, +// initializer.block.sourceEnd); +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeClassDeclaration() { +// super.consumeClassDeclaration(); +// // we know that we have a TypeDeclaration on the top of the astStack +// if (isLocalDeclaration()) { +// // we ignore the local variable declarations +// return; +// } +// requestor.exitClass(endStatementPosition, // '}' is the end of the body +// ((TypeDeclaration) astStack[astPtr]).declarationSourceEnd); +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeClassHeader() { +// //ClassHeader ::= $empty +// super.consumeClassHeader(); +// if (isLocalDeclaration()) { +// // we ignore the local variable declarations +// intArrayPtr--; +// return; +// } +// TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr]; +// TypeReference[] superInterfaces = typeDecl.superInterfaces; +// char[][] interfaceNames = null; +// int[] interfaceNameStarts = null; +// int[] interfaceNameEnds = null; +// if (superInterfaces != null) { +// int superInterfacesLength = superInterfaces.length; +// interfaceNames = new char[superInterfacesLength][]; +// interfaceNameStarts = new int[superInterfacesLength]; +// interfaceNameEnds = new int[superInterfacesLength]; +// for (int i = 0; i < superInterfacesLength; i++) { +// TypeReference superInterface = superInterfaces[i]; +// interfaceNames[i] = CharOperation.concatWith(superInterface.getTypeName(), '.'); +// interfaceNameStarts[i] = superInterface.sourceStart; +// interfaceNameEnds[i] = superInterface.sourceEnd; +// } +// } +// // flush the comments related to the class header +// scanner.commentPtr = -1; +// TypeReference superclass = typeDecl.superclass; +// if (superclass == null) { +// requestor.enterClass( +// typeDecl.declarationSourceStart, +// intArrayStack[intArrayPtr--], +// typeDecl.modifiers, +// typeDecl.modifiersSourceStart, +// typeStartPosition, +// typeDecl.name, +// typeDecl.sourceStart, +// typeDecl.sourceEnd, +// null, +// -1, +// -1, +// interfaceNames, +// interfaceNameStarts, +// interfaceNameEnds, +// scanner.currentPosition - 1); +// } else { +// requestor.enterClass( +// typeDecl.declarationSourceStart, +// intArrayStack[intArrayPtr--], +// typeDecl.modifiers, +// typeDecl.modifiersSourceStart, +// typeStartPosition, +// typeDecl.name, +// typeDecl.sourceStart, +// typeDecl.sourceEnd, +// CharOperation.concatWith(superclass.getTypeName(), '.'), +// superclass.sourceStart, +// superclass.sourceEnd, +// interfaceNames, +// interfaceNameStarts, +// interfaceNameEnds, +// scanner.currentPosition - 1); +// +// } +//} +//protected void consumeClassHeaderName() { +// // ClassHeaderName ::= Modifiersopt 'class' 'Identifier' +// TypeDeclaration typeDecl; +// if (nestedMethod[nestedType] == 0) { +// if (nestedType != 0) { +// typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult); +// } else { +// typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult); +// } +// } else { +// // Record that the block has a declaration for local types +// typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult); +// markEnclosingMemberWithLocalType(); +// blockReal(); +// } +// +// //highlight the name of the type +// long pos = identifierPositionStack[identifierPtr]; +// typeDecl.sourceEnd = (int) pos; +// typeDecl.sourceStart = (int) (pos >>> 32); +// typeDecl.name = identifierStack[identifierPtr--]; +// identifierLengthPtr--; +// +// //compute the declaration source too +// // 'class' and 'interface' push an int position +// typeStartPosition = typeDecl.declarationSourceStart = intStack[intPtr--]; +// intPtr--; +// int declarationSourceStart = intStack[intPtr--]; +// typeDecl.modifiersSourceStart = intStack[intPtr--]; +// typeDecl.modifiers = intStack[intPtr--]; +// if (typeDecl.declarationSourceStart > declarationSourceStart) { +// typeDecl.declarationSourceStart = declarationSourceStart; +// } +// typeDecl.bodyStart = typeDecl.sourceEnd + 1; +// pushOnAstStack(typeDecl); +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeCompilationUnit() { +// // CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt +// requestor.exitCompilationUnit(scanner.source.length - 1); +//} +/** + * + * INTERNAL USE-ONLY + */ +//protected void consumeConstructorDeclaration() { +// // ConstructorDeclaration ::= ConstructorHeader ConstructorBody +// super.consumeConstructorDeclaration(); +// if (isLocalDeclaration()) { +// // we ignore the local variable declarations +// return; +// } +// ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr]; +// requestor.exitConstructor(endStatementPosition, cd.declarationSourceEnd); +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeConstructorHeader() { +// // ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt +// super.consumeConstructorHeader(); +// if (isLocalDeclaration()) { +// // we ignore the local variable declarations +// intArrayPtr--; +// return; +// } +// ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr]; +// Argument[] arguments = cd.arguments; +// char[][] argumentTypes = null; +// char[][] argumentNames = null; +// int[] argumentTypeStarts = null; +// int[] argumentTypeEnds = null; +// int[] argumentNameStarts = null; +// int[] argumentNameEnds = null; +// if (arguments != null) { +// int argumentLength = arguments.length; +// argumentTypes = new char[argumentLength][]; +// argumentNames = new char[argumentLength][]; +// argumentNameStarts = new int[argumentLength]; +// argumentNameEnds = new int[argumentLength]; +// argumentTypeStarts = new int[argumentLength]; +// argumentTypeEnds = new int[argumentLength]; +// for (int i = 0; i < argumentLength; i++) { +// Argument argument = arguments[i]; +// TypeReference argumentType = argument.type; +// argumentTypes[i] = returnTypeName(argumentType); +// argumentNames[i] = argument.name; +// argumentNameStarts[i] = argument.sourceStart; +// argumentNameEnds[i] = argument.sourceEnd; +// argumentTypeStarts[i] = argumentType.sourceStart; +// argumentTypeEnds[i] = argumentType.sourceEnd; +// } +// } +// TypeReference[] thrownExceptions = cd.thrownExceptions; +// char[][] exceptionTypes = null; +// int[] exceptionTypeStarts = null; +// int[] exceptionTypeEnds = null; +// if (thrownExceptions != null) { +// int thrownExceptionLength = thrownExceptions.length; +// exceptionTypes = new char[thrownExceptionLength][]; +// exceptionTypeStarts = new int[thrownExceptionLength]; +// exceptionTypeEnds = new int[thrownExceptionLength]; +// for (int i = 0; i < thrownExceptionLength; i++) { +// TypeReference exception = thrownExceptions[i]; +// exceptionTypes[i] = CharOperation.concatWith(exception.getTypeName(), '.'); +// exceptionTypeStarts[i] = exception.sourceStart; +// exceptionTypeEnds[i] = exception.sourceEnd; +// } +// } +// requestor +// .enterConstructor( +// cd.declarationSourceStart, +// intArrayStack[intArrayPtr--], +// cd.modifiers, +// cd.modifiersSourceStart, +// cd.selector, +// cd.sourceStart, +// (int) (selectorSourcePositions & 0xFFFFFFFFL), +// // retrieve the source end of the name +// argumentTypes, +// argumentTypeStarts, +// argumentTypeEnds, +// argumentNames, +// argumentNameStarts, +// argumentNameEnds, +// rParenPos, +// // right parenthesis +// exceptionTypes, +// exceptionTypeStarts, +// exceptionTypeEnds, +// scanner.currentPosition - 1); +//} +//protected void consumeConstructorHeaderName() { +// // ConstructorHeaderName ::= Modifiersopt 'Identifier' '(' +// ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult); +// +// //name -- this is not really revelant but we do ..... +// cd.selector = identifierStack[identifierPtr]; +// selectorSourcePositions = identifierPositionStack[identifierPtr--]; +// identifierLengthPtr--; +// +// //modifiers +// cd.declarationSourceStart = intStack[intPtr--]; +// cd.modifiersSourceStart = intStack[intPtr--]; +// cd.modifiers = intStack[intPtr--]; +// +// //highlight starts at the selector starts +// cd.sourceStart = (int) (selectorSourcePositions >>> 32); +// pushOnAstStack(cd); +// +// cd.sourceEnd = lParenPos; +// cd.bodyStart = lParenPos + 1; +//} +//protected void consumeDefaultModifiers() { +// checkAnnotation(); // might update modifiers with AccDeprecated +// pushOnIntStack(modifiers); // modifiers +// pushOnIntStack(-1); +// pushOnIntStack( +// declarationSourceStart >= 0 ? declarationSourceStart : scanner.startPosition); +// resetModifiers(); +//} +//protected void consumeDiet() { +// // Diet ::= $empty +// super.consumeDiet(); +// /* persisting javadoc positions +// * Will be consume in consumeClassBodyDeclaration +// */ +// pushOnIntArrayStack(this.getJavaDocPositions()); +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeEnterCompilationUnit() { +// // EnterCompilationUnit ::= $empty +// requestor.enterCompilationUnit(); +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeEnterVariable() { +// // EnterVariable ::= $empty +// boolean isLocalDeclaration = isLocalDeclaration(); +// if (!isLocalDeclaration && (variablesCounter[nestedType] != 0)) { +// requestor.exitField(lastFieldBodyEndPosition, lastFieldEndPosition); +// } +// char[] name = identifierStack[identifierPtr]; +// long namePosition = identifierPositionStack[identifierPtr--]; +// int extendedTypeDimension = intStack[intPtr--]; +// +// AbstractVariableDeclaration declaration; +// if (nestedMethod[nestedType] != 0) { +// // create the local variable declarations +// declaration = +// new LocalDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition); +// } else { +// // create the field declaration +// declaration = +// new FieldDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition); +// } +// identifierLengthPtr--; +// TypeReference type; +// int variableIndex = variablesCounter[nestedType]; +// int typeDim = 0; +// if (variableIndex == 0) { +// // first variable of the declaration (FieldDeclaration or LocalDeclaration) +// if (nestedMethod[nestedType] != 0) { +// // local declaration +// declaration.declarationSourceStart = intStack[intPtr--]; +// declaration.modifiersSourceStart = intStack[intPtr--]; +// declaration.modifiers = intStack[intPtr--]; +// type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension +// pushOnAstStack(type); +// } else { +// // field declaration +// type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension +// pushOnAstStack(type); +// declaration.declarationSourceStart = intStack[intPtr--]; +// declaration.modifiersSourceStart = intStack[intPtr--]; +// declaration.modifiers = intStack[intPtr--]; +// } +// } else { +// type = (TypeReference) astStack[astPtr - variableIndex]; +// typeDim = type.dimensions(); +// AbstractVariableDeclaration previousVariable = +// (AbstractVariableDeclaration) astStack[astPtr]; +// declaration.declarationSourceStart = previousVariable.declarationSourceStart; +// declaration.modifiers = previousVariable.modifiers; +// declaration.modifiersSourceStart = previousVariable.modifiersSourceStart; +// } +// +// localIntPtr = intPtr; +// +// if (extendedTypeDimension == 0) { +// declaration.type = type; +// } else { +// int dimension = typeDim + extendedTypeDimension; +// //on the identifierLengthStack there is the information about the type.... +// int baseType; +// if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) { +// //it was a baseType +// declaration.type = TypeReference.baseTypeReference(-baseType, dimension); +// declaration.type.sourceStart = type.sourceStart; +// declaration.type.sourceEnd = type.sourceEnd; +// } else { +// declaration.type = this.copyDims(type, dimension); +// } +// } +// variablesCounter[nestedType]++; +// nestedMethod[nestedType]++; +// pushOnAstStack(declaration); +// +// int[] javadocPositions = intArrayStack[intArrayPtr]; +// if (!isLocalDeclaration) { +// requestor +// .enterField( +// declaration.declarationSourceStart, +// javadocPositions, +// declaration.modifiers, +// declaration.modifiersSourceStart, +// returnTypeName(declaration.type), +// type.sourceStart, +// type.sourceEnd, +// typeDims, +// name, +// (int) (namePosition >>> 32), +// (int) namePosition, +// extendedTypeDimension, +// extendedTypeDimension == 0 ? -1 : endPosition); +// } +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeExitVariableWithInitialization() { +// // ExitVariableWithInitialization ::= $empty +// // the scanner is located after the comma or the semi-colon. +// // we want to include the comma or the semi-colon +// super.consumeExitVariableWithInitialization(); +// nestedMethod[nestedType]--; +// lastFieldEndPosition = scanner.currentPosition - 1; +// lastFieldBodyEndPosition = ((AbstractVariableDeclaration) astStack[astPtr]).initialization.sourceEnd; +//} +//protected void consumeExitVariableWithoutInitialization() { +// // ExitVariableWithoutInitialization ::= $empty +// // do nothing by default +// super.consumeExitVariableWithoutInitialization(); +// nestedMethod[nestedType]--; +// lastFieldEndPosition = scanner.currentPosition - 1; +// lastFieldBodyEndPosition = scanner.startPosition - 1; +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeFieldDeclaration() { +// // See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code +// // FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';' +// // the super.consumeFieldDeclaration will reinitialize the variableCounter[nestedType] +// int variableIndex = variablesCounter[nestedType]; +// super.consumeFieldDeclaration(); +// intArrayPtr--; +// if (isLocalDeclaration()) +// return; +// if (variableIndex != 0) { +// requestor.exitField(lastFieldBodyEndPosition, lastFieldEndPosition); +// } +//} +//protected void consumeFormalParameter() { +// // FormalParameter ::= Type VariableDeclaratorId ==> false +// // FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true +// /* +// astStack : +// identifierStack : type identifier +// intStack : dim dim +// ==> +// astStack : Argument +// identifierStack : +// intStack : +// */ +// +// identifierLengthPtr--; +// char[] name = identifierStack[identifierPtr]; +// long namePositions = identifierPositionStack[identifierPtr--]; +// TypeReference type = getTypeReference(intStack[intPtr--] + intStack[intPtr--]); +// intPtr -= 3; +// Argument arg = +// new Argument( +// name, +// namePositions, +// type, +// intStack[intPtr + 1]); // modifiers +// pushOnAstStack(arg); +// intArrayPtr--; +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeInterfaceDeclaration() { +// super.consumeInterfaceDeclaration(); +// // we know that we have a TypeDeclaration on the top of the astStack +// if (isLocalDeclaration()) { +// // we ignore the local variable declarations +// return; +// } +// requestor.exitInterface(endStatementPosition, // the '}' is the end of the body +// ((TypeDeclaration) astStack[astPtr]).declarationSourceEnd); +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeInterfaceHeader() { +// //InterfaceHeader ::= $empty +// super.consumeInterfaceHeader(); +// if (isLocalDeclaration()) { +// // we ignore the local variable declarations +// intArrayPtr--; +// return; +// } +// TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr]; +// TypeReference[] superInterfaces = typeDecl.superInterfaces; +// char[][] interfaceNames = null; +// int[] interfaceNameStarts = null; +// int[] interfacenameEnds = null; +// int superInterfacesLength = 0; +// if (superInterfaces != null) { +// superInterfacesLength = superInterfaces.length; +// interfaceNames = new char[superInterfacesLength][]; +// interfaceNameStarts = new int[superInterfacesLength]; +// interfacenameEnds = new int[superInterfacesLength]; +// } +// if (superInterfaces != null) { +// for (int i = 0; i < superInterfacesLength; i++) { +// TypeReference superInterface = superInterfaces[i]; +// interfaceNames[i] = CharOperation.concatWith(superInterface.getTypeName(), '.'); +// interfaceNameStarts[i] = superInterface.sourceStart; +// interfacenameEnds[i] = superInterface.sourceEnd; +// } +// } +// // flush the comments related to the interface header +// scanner.commentPtr = -1; +// requestor.enterInterface( +// typeDecl.declarationSourceStart, +// intArrayStack[intArrayPtr--], +// typeDecl.modifiers, +// typeDecl.modifiersSourceStart, +// typeStartPosition, +// typeDecl.name, +// typeDecl.sourceStart, +// typeDecl.sourceEnd, +// interfaceNames, +// interfaceNameStarts, +// interfacenameEnds, +// scanner.currentPosition - 1); +//} +//protected void consumeInterfaceHeaderName() { +// // InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier' +// TypeDeclaration typeDecl; +// if (nestedMethod[nestedType] == 0) { +// if (nestedType != 0) { +// typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult); +// } else { +// typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult); +// } +// } else { +// // Record that the block has a declaration for local types +// typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult); +// markEnclosingMemberWithLocalType(); +// blockReal(); +// } +// +// //highlight the name of the type +// long pos = identifierPositionStack[identifierPtr]; +// typeDecl.sourceEnd = (int) pos; +// typeDecl.sourceStart = (int) (pos >>> 32); +// typeDecl.name = identifierStack[identifierPtr--]; +// identifierLengthPtr--; +// +// //compute the declaration source too +// // 'class' and 'interface' push an int position +// typeStartPosition = typeDecl.declarationSourceStart = intStack[intPtr--]; +// intPtr--; +// int declarationSourceStart = intStack[intPtr--]; +// typeDecl.modifiersSourceStart = intStack[intPtr--]; +// typeDecl.modifiers = intStack[intPtr--]; +// if (typeDecl.declarationSourceStart > declarationSourceStart) { +// typeDecl.declarationSourceStart = declarationSourceStart; +// } +// typeDecl.bodyStart = typeDecl.sourceEnd + 1; +// pushOnAstStack(typeDecl); +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeLocalVariableDeclaration() { +// // See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code +// // FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';' +// +// super.consumeLocalVariableDeclaration(); +// intArrayPtr--; +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeMethodDeclaration(boolean isNotAbstract) { +// // MethodDeclaration ::= MethodHeader MethodBody +// // AbstractMethodDeclaration ::= MethodHeader ';' +// super.consumeMethodDeclaration(isNotAbstract); +// if (isLocalDeclaration()) { +// // we ignore the local variable declarations +// return; +// } +// MethodDeclaration md = (MethodDeclaration) astStack[astPtr]; +// requestor.exitMethod(endStatementPosition, md.declarationSourceEnd); +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeMethodHeader() { +// // MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims ThrowsClauseopt +// super.consumeMethodHeader(); +// if (isLocalDeclaration()) { +// // we ignore the local variable declarations +// intArrayPtr--; +// return; +// } +// MethodDeclaration md = (MethodDeclaration) astStack[astPtr]; +// +// TypeReference returnType = md.returnType; +// char[] returnTypeName = returnTypeName(returnType); +// Argument[] arguments = md.arguments; +// char[][] argumentTypes = null; +// char[][] argumentNames = null; +// int[] argumentTypeStarts = null; +// int[] argumentTypeEnds = null; +// int[] argumentNameStarts = null; +// int[] argumentNameEnds = null; +// if (arguments != null) { +// int argumentLength = arguments.length; +// argumentTypes = new char[argumentLength][]; +// argumentNames = new char[argumentLength][]; +// argumentNameStarts = new int[argumentLength]; +// argumentNameEnds = new int[argumentLength]; +// argumentTypeStarts = new int[argumentLength]; +// argumentTypeEnds = new int[argumentLength]; +// for (int i = 0; i < argumentLength; i++) { +// Argument argument = arguments[i]; +// TypeReference argumentType = argument.type; +// argumentTypes[i] = returnTypeName(argumentType); +// argumentNames[i] = argument.name; +// argumentNameStarts[i] = argument.sourceStart; +// argumentNameEnds[i] = argument.sourceEnd; +// argumentTypeStarts[i] = argumentType.sourceStart; +// argumentTypeEnds[i] = argumentType.sourceEnd; +// } +// } +// TypeReference[] thrownExceptions = md.thrownExceptions; +// char[][] exceptionTypes = null; +// int[] exceptionTypeStarts = null; +// int[] exceptionTypeEnds = null; +// if (thrownExceptions != null) { +// int thrownExceptionLength = thrownExceptions.length; +// exceptionTypeStarts = new int[thrownExceptionLength]; +// exceptionTypeEnds = new int[thrownExceptionLength]; +// exceptionTypes = new char[thrownExceptionLength][]; +// for (int i = 0; i < thrownExceptionLength; i++) { +// TypeReference exception = thrownExceptions[i]; +// exceptionTypes[i] = CharOperation.concatWith(exception.getTypeName(), '.'); +// exceptionTypeStarts[i] = exception.sourceStart; +// exceptionTypeEnds[i] = exception.sourceEnd; +// } +// } +// requestor +// .enterMethod( +// md.declarationSourceStart, +// intArrayStack[intArrayPtr--], +// md.modifiers, +// md.modifiersSourceStart, +// returnTypeName, +// returnType.sourceStart, +// returnType.sourceEnd, +// typeDims, +// md.selector, +// md.sourceStart, +// (int) (selectorSourcePositions & 0xFFFFFFFFL), +// argumentTypes, +// argumentTypeStarts, +// argumentTypeEnds, +// argumentNames, +// argumentNameStarts, +// argumentNameEnds, +// rParenPos, +// extendsDim, +// extendsDim == 0 ? -1 : endPosition, +// exceptionTypes, +// exceptionTypeStarts, +// exceptionTypeEnds, +// scanner.currentPosition - 1); +//} +//protected void consumeMethodHeaderExtendedDims() { +// // MethodHeaderExtendedDims ::= Dimsopt +// // now we update the returnType of the method +// MethodDeclaration md = (MethodDeclaration) astStack[astPtr]; +// int extendedDims = intStack[intPtr--]; +// extendsDim = extendedDims; +// if (extendedDims != 0) { +// TypeReference returnType = md.returnType; +// md.sourceEnd = endPosition; +// int dims = returnType.dimensions() + extendedDims; +// int baseType; +// if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) { +// //it was a baseType +// int sourceStart = returnType.sourceStart; +// int sourceEnd = returnType.sourceEnd; +// returnType = TypeReference.baseTypeReference(-baseType, dims); +// returnType.sourceStart = sourceStart; +// returnType.sourceEnd = sourceEnd; +// md.returnType = returnType; +// } else { +// md.returnType = this.copyDims(md.returnType, dims); +// } +// if (currentToken == TokenNameLBRACE) { +// md.bodyStart = endPosition + 1; +// } +// } +//} +//protected void consumeMethodHeaderName() { +// // MethodHeaderName ::= Modifiersopt Type 'Identifier' '(' +// MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult); +// +// //name +// md.selector = identifierStack[identifierPtr]; +// selectorSourcePositions = identifierPositionStack[identifierPtr--]; +// identifierLengthPtr--; +// //type +// md.returnType = getTypeReference(typeDims = intStack[intPtr--]); +// //modifiers +// md.declarationSourceStart = intStack[intPtr--]; +// md.modifiersSourceStart = intStack[intPtr--]; +// md.modifiers = intStack[intPtr--]; +// +// //highlight starts at selector start +// md.sourceStart = (int) (selectorSourcePositions >>> 32); +// pushOnAstStack(md); +// md.bodyStart = scanner.currentPosition-1; +//} +//protected void consumeModifiers() { +// checkAnnotation(); // might update modifiers with AccDeprecated +// pushOnIntStack(modifiers); // modifiers +// pushOnIntStack(modifiersSourceStart); +// pushOnIntStack( +// declarationSourceStart >= 0 ? declarationSourceStart : modifiersSourceStart); +// resetModifiers(); +//} +/** + * + * INTERNAL USE-ONLY + */ +//protected void consumePackageDeclarationName() { +// /* persisting javadoc positions */ +// pushOnIntArrayStack(this.getJavaDocPositions()); +// +// super.consumePackageDeclarationName(); +// ImportReference importReference = compilationUnit.currentPackage; +// +// requestor.acceptPackage( +// importReference.declarationSourceStart, +// importReference.declarationSourceEnd, +// intArrayStack[intArrayPtr--], +// CharOperation.concatWith(importReference.getImportName(), '.'), +// importReference.sourceStart); +//} +//protected void consumePushModifiers() { +// checkAnnotation(); // might update modifiers with AccDeprecated +// pushOnIntStack(modifiers); // modifiers +// if (modifiersSourceStart < 0) { +// pushOnIntStack(-1); +// pushOnIntStack( +// declarationSourceStart >= 0 ? declarationSourceStart : scanner.startPosition); +// } else { +// pushOnIntStack(modifiersSourceStart); +// pushOnIntStack( +// declarationSourceStart >= 0 ? declarationSourceStart : modifiersSourceStart); +// } +// resetModifiers(); +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeSingleTypeImportDeclarationName() { +// // SingleTypeImportDeclarationName ::= 'import' Name +// +// /* persisting javadoc positions */ +// pushOnIntArrayStack(this.getJavaDocPositions()); +// +// super.consumeSingleTypeImportDeclarationName(); +// ImportReference importReference = (ImportReference) astStack[astPtr]; +// requestor.acceptImport( +// importReference.declarationSourceStart, +// importReference.declarationSourceEnd, +// intArrayStack[intArrayPtr--], +// CharOperation.concatWith(importReference.getImportName(), '.'), +// importReference.sourceStart, +// false); +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeStaticInitializer() { +// // StaticInitializer ::= StaticOnly Block +// //push an Initializer +// //optimize the push/pop +// super.consumeStaticInitializer(); +// Initializer initializer = (Initializer) astStack[astPtr]; +// requestor.acceptInitializer( +// initializer.declarationSourceStart, +// initializer.declarationSourceEnd, +// intArrayStack[intArrayPtr--], +// AccStatic, +// intStack[intPtr--], +// initializer.block.sourceStart, +// initializer.declarationSourceEnd); +//} +//protected void consumeStaticOnly() { +// // StaticOnly ::= 'static' +// checkAnnotation(); // might update declaration source start +// pushOnIntStack(modifiersSourceStart); +// pushOnIntStack( +// declarationSourceStart >= 0 ? declarationSourceStart : modifiersSourceStart); +// jumpOverMethodBody(); +// nestedMethod[nestedType]++; +// resetModifiers(); +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeTypeImportOnDemandDeclarationName() { +// // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*' +// +// /* persisting javadoc positions */ +// pushOnIntArrayStack(this.getJavaDocPositions()); +// +// super.consumeTypeImportOnDemandDeclarationName(); +// ImportReference importReference = (ImportReference) astStack[astPtr]; +// requestor.acceptImport( +// importReference.declarationSourceStart, +// importReference.declarationSourceEnd, +// intArrayStack[intArrayPtr--], +// CharOperation.concatWith(importReference.getImportName(), '.'), +// importReference.sourceStart, +// true); +//} +public CompilationUnitDeclaration endParse(int act) { + if (scanner.recordLineSeparator) { + requestor.acceptLineSeparatorPositions(scanner.getLineEnds()); + } + return super.endParse(act); +} +/* + * Flush annotations defined prior to a given positions. + * + * Note: annotations are stacked in syntactical order + * + * Either answer given , or the end position of a comment line + * immediately following the (same line) + * + * e.g. + * void foo(){ + * } // end of method foo + */ + +//public int flushAnnotationsDefinedPriorTo(int position) { +// +// return lastFieldEndPosition = super.flushAnnotationsDefinedPriorTo(position); +//} +//protected TypeReference getTypeReference(int dim) { /* build a Reference on a variable that may be qualified or not +//This variable is a type reference and dim will be its dimensions*/ +// +// int length; +// TypeReference ref; +// if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) { +// // single variable reference +// if (dim == 0) { +// ref = +// new SingleTypeReference( +// identifierStack[identifierPtr], +// identifierPositionStack[identifierPtr--]); +// } else { +// ref = +// new ArrayTypeReference( +// identifierStack[identifierPtr], +// dim, +// identifierPositionStack[identifierPtr--]); +// ref.sourceEnd = endPosition; +// } +// } else { +// if (length < 0) { //flag for precompiled type reference on base types +// ref = TypeReference.baseTypeReference(-length, dim); +// ref.sourceStart = intStack[intPtr--]; +// if (dim == 0) { +// ref.sourceEnd = intStack[intPtr--]; +// } else { +// intPtr--; +// ref.sourceEnd = endPosition; +// } +// } else { //Qualified variable reference +// char[][] tokens = new char[length][]; +// identifierPtr -= length; +// long[] positions = new long[length]; +// System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length); +// System.arraycopy( +// identifierPositionStack, +// identifierPtr + 1, +// positions, +// 0, +// length); +// if (dim == 0) { +// ref = new QualifiedTypeReference(tokens, positions); +// } else { +// ref = new ArrayQualifiedTypeReference(tokens, dim, positions); +// ref.sourceEnd = endPosition; +// } +// } +// }; +// return ref; +//} +public void initialize() { + //positionning the parser for a new compilation unit + //avoiding stack reallocation and all that.... + super.initialize(); + intArrayPtr = -1; +} +/** + * + * INTERNAL USE-ONLY + */ +//private boolean isLocalDeclaration() { +// int nestedDepth = nestedType; +// while (nestedDepth >= 0) { +// if (nestedMethod[nestedDepth] != 0) { +// return true; +// } +// nestedDepth--; +// } +// return false; +//} +/* + * Investigate one entire unit. + */ +public void parseCompilationUnit(ICompilationUnit unit) { + char[] regionSource = unit.getContents(); + try { + initialize(); + goForCompilationUnit(); + referenceContext = + compilationUnit = + compilationUnit = + new CompilationUnitDeclaration( + problemReporter(), + new CompilationResult(unit, 0, 0, 10), //this.options.maxProblemsPerUnit), + regionSource.length); + scanner.resetTo(0, regionSource.length); + scanner.setSource(regionSource); + parse(); + } catch (CoreException e) { + e.printStackTrace(); + } catch (AbortCompilation ex) { + } +} +/* + * Investigate one constructor declaration. + */ +//public void parseConstructor(char[] regionSource) { +// try { +// initialize(); +// goForClassBodyDeclarations(); +// referenceContext = +// compilationUnit = +// compilationUnit = +// new CompilationUnitDeclaration( +// problemReporter(), +// new CompilationResult(regionSource, 0, 0, 10), //this.options.maxProblemsPerUnit), +// regionSource.length); +// scanner.resetTo(0, regionSource.length); +// scanner.setSource(regionSource); +// parse(); +// } catch (AbortCompilation ex) { +// } +//} +/* + * Investigate one field declaration statement (might have multiple declarations in it). + */ +//public void parseField(char[] regionSource) { +// try { +// initialize(); +// goForFieldDeclaration(); +// referenceContext = +// compilationUnit = +// compilationUnit = +// new CompilationUnitDeclaration( +// problemReporter(), +// new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit), +// regionSource.length); +// scanner.resetTo(0, regionSource.length); +// scanner.setSource(regionSource); +// parse(); +// } catch (AbortCompilation ex) { +// } +// +//} +///* +// * Investigate one import statement declaration. +// */ +//public void parseImport(char[] regionSource) { +// try { +// initialize(); +// goForImportDeclaration(); +// referenceContext = +// compilationUnit = +// compilationUnit = +// new CompilationUnitDeclaration( +// problemReporter(), +// new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit), +// regionSource.length); +// scanner.resetTo(0, regionSource.length); +// scanner.setSource(regionSource); +// parse(); +// } catch (AbortCompilation ex) { +// } +// +//} +///* +// * Investigate one initializer declaration. +// * regionSource need to content exactly an initializer declaration. +// * e.g: static { i = 4; } +// * { name = "test"; } +// */ +//public void parseInitializer(char[] regionSource) { +// try { +// initialize(); +// goForInitializer(); +// referenceContext = +// compilationUnit = +// compilationUnit = +// new CompilationUnitDeclaration( +// problemReporter(), +// new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit), +// regionSource.length); +// scanner.resetTo(0, regionSource.length); +// scanner.setSource(regionSource); +// parse(); +// } catch (AbortCompilation ex) { +// } +// +//} +///* +// * Investigate one method declaration. +// */ +//public void parseMethod(char[] regionSource) { +// try { +// initialize(); +// goForGenericMethodDeclaration(); +// referenceContext = +// compilationUnit = +// compilationUnit = +// new CompilationUnitDeclaration( +// problemReporter(), +// new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit), +// regionSource.length); +// scanner.resetTo(0, regionSource.length); +// scanner.setSource(regionSource); +// parse(); +// } catch (AbortCompilation ex) { +// } +// +//} +///* +// * Investigate one package statement declaration. +// */ +//public void parsePackage(char[] regionSource) { +// try { +// initialize(); +// goForPackageDeclaration(); +// referenceContext = +// compilationUnit = +// compilationUnit = +// new CompilationUnitDeclaration( +// problemReporter(), +// new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit), +// regionSource.length); +// scanner.resetTo(0, regionSource.length); +// scanner.setSource(regionSource); +// parse(); +// } catch (AbortCompilation ex) { +// } +// +//} +///* +// * Investigate one type declaration, its fields, methods and member types. +// */ +//public void parseType(char[] regionSource) { +// try { +// initialize(); +// goForTypeDeclaration(); +// referenceContext = +// compilationUnit = +// compilationUnit = +// new CompilationUnitDeclaration( +// problemReporter(), +// new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit), +// regionSource.length); +// scanner.resetTo(0, regionSource.length); +// scanner.setSource(regionSource); +// parse(); +// } catch (AbortCompilation ex) { +// } +// +//} +/** + * Returns this parser's problem reporter initialized with its reference context. + * Also it is assumed that a problem is going to be reported, so initializes + * the compilation result's line positions. + */ +public ProblemReporter problemReporter() { + problemReporter.referenceContext = referenceContext; + return problemReporter; +} +protected void pushOnIntArrayStack(int[] positions) { + + try { + intArrayStack[++intArrayPtr] = positions; + } catch (IndexOutOfBoundsException e) { + //intPtr is correct + int oldStackLength = intArrayStack.length; + int oldStack[][] = intArrayStack; + intArrayStack = new int[oldStackLength + StackIncrement][]; + System.arraycopy(oldStack, 0, intArrayStack, 0, oldStackLength); + intArrayStack[intArrayPtr] = positions; + } +} +//protected void resetModifiers() { +// super.resetModifiers(); +// declarationSourceStart = -1; +//} +/* + * Syntax error was detected. Will attempt to perform some recovery action in order + * to resume to the regular parse loop. + */ +protected boolean resumeOnSyntaxError() { + return false; +} +/* + * Answer a char array representation of the type name formatted like: + * - type name + dimensions + * Example: + * "A[][]".toCharArray() + * "java.lang.String".toCharArray() + */ +//private char[] returnTypeName(TypeReference type) { +// int dimension = type.dimensions(); +// if (dimension != 0) { +// char[] dimensionsArray = new char[dimension * 2]; +// for (int i = 0; i < dimension; i++) { +// dimensionsArray[i*2] = '['; +// dimensionsArray[(i*2) + 1] = ']'; +// } +// return CharOperation.concat( +// CharOperation.concatWith(type.getTypeName(), '.'), +// dimensionsArray); +// } +// return CharOperation.concatWith(type.getTypeName(), '.'); +//} +//public String toString() { +// StringBuffer buffer = new StringBuffer(); +// buffer.append("intArrayPtr = " + intArrayPtr + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ +// buffer.append(super.toString()); +// return buffer.toString(); +//} +///** +// * INTERNAL USE ONLY +// */ +//protected TypeReference typeReference( +// int dim, +// int localIdentifierPtr, +// int localIdentifierLengthPtr) { +// /* build a Reference on a variable that may be qualified or not +// * This variable is a type reference and dim will be its dimensions. +// * We don't have any side effect on the stacks' pointers. +// */ +// +// int length; +// TypeReference ref; +// if ((length = identifierLengthStack[localIdentifierLengthPtr]) == 1) { +// // single variable reference +// if (dim == 0) { +// ref = +// new SingleTypeReference( +// identifierStack[localIdentifierPtr], +// identifierPositionStack[localIdentifierPtr--]); +// } else { +// ref = +// new ArrayTypeReference( +// identifierStack[localIdentifierPtr], +// dim, +// identifierPositionStack[localIdentifierPtr--]); +// ref.sourceEnd = endPosition; +// } +// } else { +// if (length < 0) { //flag for precompiled type reference on base types +// ref = TypeReference.baseTypeReference(-length, dim); +// ref.sourceStart = intStack[localIntPtr--]; +// if (dim == 0) { +// ref.sourceEnd = intStack[localIntPtr--]; +// } else { +// localIntPtr--; +// ref.sourceEnd = endPosition; +// } +// } else { //Qualified variable reference +// char[][] tokens = new char[length][]; +// localIdentifierPtr -= length; +// long[] positions = new long[length]; +// System.arraycopy(identifierStack, localIdentifierPtr + 1, tokens, 0, length); +// System.arraycopy( +// identifierPositionStack, +// localIdentifierPtr + 1, +// positions, +// 0, +// length); +// if (dim == 0) +// ref = new QualifiedTypeReference(tokens, positions); +// else +// ref = new ArrayQualifiedTypeReference(tokens, dim, positions); +// } +// }; +// return ref; +//} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/IAbstractSyntaxTreeVisitor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/IAbstractSyntaxTreeVisitor.java new file mode 100644 index 0000000..f08807b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/IAbstractSyntaxTreeVisitor.java @@ -0,0 +1,245 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler; + +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope; +import net.sourceforge.phpdt.internal.compiler.lookup.CompilationUnitScope; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpeclipse.internal.compiler.ast.AND_AND_Expression; +import net.sourceforge.phpeclipse.internal.compiler.ast.AllocationExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.AnonymousLocalTypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.Argument; +import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayAllocationExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayInitializer; +import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayQualifiedTypeReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayTypeReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.AssertStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.Assignment; +import net.sourceforge.phpeclipse.internal.compiler.ast.BinaryExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.Block; +import net.sourceforge.phpeclipse.internal.compiler.ast.Break; +import net.sourceforge.phpeclipse.internal.compiler.ast.Case; +import net.sourceforge.phpeclipse.internal.compiler.ast.CastExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.CharLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.ClassLiteralAccess; +import net.sourceforge.phpeclipse.internal.compiler.ast.Clinit; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompoundAssignment; +import net.sourceforge.phpeclipse.internal.compiler.ast.ConditionalExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.Continue; +import net.sourceforge.phpeclipse.internal.compiler.ast.DefaultCase; +import net.sourceforge.phpeclipse.internal.compiler.ast.DoStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.DoubleLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.EmptyStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.EqualExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.ExplicitConstructorCall; +import net.sourceforge.phpeclipse.internal.compiler.ast.ExtendedStringLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.FalseLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.FloatLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.ForStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.IfStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.Initializer; +import net.sourceforge.phpeclipse.internal.compiler.ast.InstanceOfExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.IntLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.LabeledStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.LocalDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.LocalTypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.LongLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.MemberTypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.MessageSend; +import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.NullLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.OR_OR_Expression; +import net.sourceforge.phpeclipse.internal.compiler.ast.PostfixExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.PrefixExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedAllocationExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedNameReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedSuperReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedThisReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedTypeReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.ReturnStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.SingleNameReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.SuperReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.SwitchStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.SynchronizedStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.ThisReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.ThrowStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.TrueLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.TryStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.UnaryExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.WhileStatement; + +/** + * A visitor interface for interating through the parse tree. + */ +public interface IAbstractSyntaxTreeVisitor { + void acceptProblem(IProblem problem); + void endVisit(AllocationExpression allocationExpression, BlockScope scope); + void endVisit(AND_AND_Expression and_and_Expression, BlockScope scope); + void endVisit(AnonymousLocalTypeDeclaration anonymousTypeDeclaration, BlockScope scope); + void endVisit(Argument argument, BlockScope scope); + void endVisit(ArrayAllocationExpression arrayAllocationExpression, BlockScope scope); + void endVisit(ArrayInitializer arrayInitializer, BlockScope scope); + void endVisit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, BlockScope scope); + void endVisit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, ClassScope scope); + void endVisit(ArrayReference arrayReference, BlockScope scope); + void endVisit(ArrayTypeReference arrayTypeReference, BlockScope scope); + void endVisit(ArrayTypeReference arrayTypeReference, ClassScope scope); + void endVisit(AssertStatement assertStatement, BlockScope scope); + void endVisit(Assignment assignment, BlockScope scope); + void endVisit(BinaryExpression binaryExpression, BlockScope scope); + void endVisit(Block block, BlockScope scope); + void endVisit(Break breakStatement, BlockScope scope); + void endVisit(Case caseStatement, BlockScope scope); + void endVisit(CastExpression castExpression, BlockScope scope); + void endVisit(CharLiteral charLiteral, BlockScope scope); + void endVisit(ClassLiteralAccess classLiteral, BlockScope scope); + void endVisit(Clinit clinit, ClassScope scope); + void endVisit(CompilationUnitDeclaration compilationUnitDeclaration, CompilationUnitScope scope); + void endVisit(CompoundAssignment compoundAssignment, BlockScope scope); + void endVisit(ConditionalExpression conditionalExpression, BlockScope scope); + void endVisit(ConstructorDeclaration constructorDeclaration, ClassScope scope); + void endVisit(Continue continueStatement, BlockScope scope); + void endVisit(DefaultCase defaultCaseStatement, BlockScope scope); + void endVisit(DoStatement doStatement, BlockScope scope); + void endVisit(DoubleLiteral doubleLiteral, BlockScope scope); + void endVisit(EqualExpression equalExpression, BlockScope scope); + void endVisit(EmptyStatement statement, BlockScope scope); + void endVisit(ExplicitConstructorCall explicitConstructor, BlockScope scope); + void endVisit(ExtendedStringLiteral extendedStringLiteral, BlockScope scope); + void endVisit(FalseLiteral falseLiteral, BlockScope scope); + void endVisit(FieldDeclaration fieldDeclaration, MethodScope scope); + void endVisit(FieldReference fieldReference, BlockScope scope); + void endVisit(FloatLiteral floatLiteral, BlockScope scope); + void endVisit(ForStatement forStatement, BlockScope scope); + void endVisit(IfStatement ifStatement, BlockScope scope); + void endVisit(ImportReference importRef, CompilationUnitScope scope); + void endVisit(Initializer initializer, MethodScope scope); + void endVisit(InstanceOfExpression instanceOfExpression, BlockScope scope); + void endVisit(IntLiteral intLiteral, BlockScope scope); + void endVisit(LabeledStatement labeledStatement, BlockScope scope); + void endVisit(LocalDeclaration localDeclaration, BlockScope scope); + void endVisit(LocalTypeDeclaration localTypeDeclaration, BlockScope scope); + void endVisit(LongLiteral longLiteral, BlockScope scope); + void endVisit(MemberTypeDeclaration memberTypeDeclaration, ClassScope scope); + void endVisit(MessageSend messageSend, BlockScope scope); + void endVisit(MethodDeclaration methodDeclaration, ClassScope scope); + void endVisit(NullLiteral nullLiteral, BlockScope scope); + void endVisit(OR_OR_Expression or_or_Expression, BlockScope scope); + void endVisit(PostfixExpression postfixExpression, BlockScope scope); + void endVisit(PrefixExpression prefixExpression, BlockScope scope); + void endVisit(QualifiedAllocationExpression qualifiedAllocationExpression, BlockScope scope); + void endVisit(QualifiedNameReference qualifiedNameReference, BlockScope scope); + void endVisit(QualifiedSuperReference qualifiedSuperReference, BlockScope scope); + void endVisit(QualifiedThisReference qualifiedThisReference, BlockScope scope); + void endVisit(QualifiedTypeReference qualifiedTypeReference, BlockScope scope); + void endVisit(QualifiedTypeReference qualifiedTypeReference, ClassScope scope); + void endVisit(ReturnStatement returnStatement, BlockScope scope); + void endVisit(SingleNameReference singleNameReference, BlockScope scope); + void endVisit(SingleTypeReference singleTypeReference, BlockScope scope); + void endVisit(SingleTypeReference singleTypeReference, ClassScope scope); + void endVisit(StringLiteral stringLiteral, BlockScope scope); + void endVisit(SuperReference superReference, BlockScope scope); + void endVisit(SwitchStatement switchStatement, BlockScope scope); + void endVisit(SynchronizedStatement synchronizedStatement, BlockScope scope); + void endVisit(ThisReference thisReference, BlockScope scope); + void endVisit(ThrowStatement throwStatement, BlockScope scope); + void endVisit(TrueLiteral trueLiteral, BlockScope scope); + void endVisit(TryStatement tryStatement, BlockScope scope); + void endVisit(TypeDeclaration typeDeclaration, CompilationUnitScope scope); + void endVisit(UnaryExpression unaryExpression, BlockScope scope); + void endVisit(WhileStatement whileStatement, BlockScope scope); + boolean visit(AllocationExpression allocationExpression, BlockScope scope); + boolean visit(AND_AND_Expression and_and_Expression, BlockScope scope); + boolean visit(AnonymousLocalTypeDeclaration anonymousTypeDeclaration, BlockScope scope); + boolean visit(Argument argument, BlockScope scope); + boolean visit(ArrayAllocationExpression arrayAllocationExpression, BlockScope scope); + boolean visit(ArrayInitializer arrayInitializer, BlockScope scope); + boolean visit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, BlockScope scope); + boolean visit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, ClassScope scope); + boolean visit(ArrayReference arrayReference, BlockScope scope); + boolean visit(ArrayTypeReference arrayTypeReference, BlockScope scope); + boolean visit(ArrayTypeReference arrayTypeReference, ClassScope scope); + boolean visit(AssertStatement assertStatement, BlockScope scope); + boolean visit(Assignment assignment, BlockScope scope); + boolean visit(BinaryExpression binaryExpression, BlockScope scope); + boolean visit(Block block, BlockScope scope); + boolean visit(Break breakStatement, BlockScope scope); + boolean visit(Case caseStatement, BlockScope scope); + boolean visit(CastExpression castExpression, BlockScope scope); + boolean visit(CharLiteral charLiteral, BlockScope scope); + boolean visit(ClassLiteralAccess classLiteral, BlockScope scope); + boolean visit(Clinit clinit, ClassScope scope); + boolean visit(CompilationUnitDeclaration compilationUnitDeclaration, CompilationUnitScope scope); + boolean visit(CompoundAssignment compoundAssignment, BlockScope scope); + boolean visit(ConditionalExpression conditionalExpression, BlockScope scope); + boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope); + boolean visit(Continue continueStatement, BlockScope scope); + boolean visit(DefaultCase defaultCaseStatement, BlockScope scope); + boolean visit(DoStatement doStatement, BlockScope scope); + boolean visit(DoubleLiteral doubleLiteral, BlockScope scope); + boolean visit(EqualExpression equalExpression, BlockScope scope); + boolean visit(EmptyStatement statement, BlockScope scope); + boolean visit(ExplicitConstructorCall explicitConstructor, BlockScope scope); + boolean visit(ExtendedStringLiteral extendedStringLiteral, BlockScope scope); + boolean visit(FalseLiteral falseLiteral, BlockScope scope); + boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope); + boolean visit(FieldReference fieldReference, BlockScope scope); + boolean visit(FloatLiteral floatLiteral, BlockScope scope); + boolean visit(ForStatement forStatement, BlockScope scope); + boolean visit(IfStatement ifStatement, BlockScope scope); + boolean visit(ImportReference importRef, CompilationUnitScope scope); + boolean visit(Initializer initializer, MethodScope scope); + boolean visit(InstanceOfExpression instanceOfExpression, BlockScope scope); + boolean visit(IntLiteral intLiteral, BlockScope scope); + boolean visit(LabeledStatement labeledStatement, BlockScope scope); + boolean visit(LocalDeclaration localDeclaration, BlockScope scope); + boolean visit(LocalTypeDeclaration localTypeDeclaration, BlockScope scope); + boolean visit(LongLiteral longLiteral, BlockScope scope); + boolean visit(MemberTypeDeclaration memberTypeDeclaration, ClassScope scope); + boolean visit(MessageSend messageSend, BlockScope scope); + boolean visit(MethodDeclaration methodDeclaration, ClassScope scope); + boolean visit(NullLiteral nullLiteral, BlockScope scope); + boolean visit(OR_OR_Expression or_or_Expression, BlockScope scope); + boolean visit(PostfixExpression postfixExpression, BlockScope scope); + boolean visit(PrefixExpression prefixExpression, BlockScope scope); + boolean visit(QualifiedAllocationExpression qualifiedAllocationExpression, BlockScope scope); + boolean visit(QualifiedNameReference qualifiedNameReference, BlockScope scope); + boolean visit(QualifiedSuperReference qualifiedSuperReference, BlockScope scope); + boolean visit(QualifiedThisReference qualifiedThisReference, BlockScope scope); + boolean visit(QualifiedTypeReference qualifiedTypeReference, BlockScope scope); + boolean visit(QualifiedTypeReference qualifiedTypeReference, ClassScope scope); + boolean visit(ReturnStatement returnStatement, BlockScope scope); + boolean visit(SingleNameReference singleNameReference, BlockScope scope); + boolean visit(SingleTypeReference singleTypeReference, BlockScope scope); + boolean visit(SingleTypeReference singleTypeReference, ClassScope scope); + boolean visit(StringLiteral stringLiteral, BlockScope scope); + boolean visit(SuperReference superReference, BlockScope scope); + boolean visit(SwitchStatement switchStatement, BlockScope scope); + boolean visit(SynchronizedStatement synchronizedStatement, BlockScope scope); + boolean visit(ThisReference thisReference, BlockScope scope); + boolean visit(ThrowStatement throwStatement, BlockScope scope); + boolean visit(TrueLiteral trueLiteral, BlockScope scope); + boolean visit(TryStatement tryStatement, BlockScope scope); + boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope); + boolean visit(UnaryExpression unaryExpression, BlockScope scope); + boolean visit(WhileStatement whileStatement, BlockScope scope); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ICompilerRequestor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ICompilerRequestor.java new file mode 100644 index 0000000..b41a9b1 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ICompilerRequestor.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler; + +/** + * A callback interface for receiving compilation results. + */ +public interface ICompilerRequestor { + + /** + * Accept a compilation result. + */ + public void acceptResult(CompilationResult result); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/IDocumentElementRequestor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/IDocumentElementRequestor.java new file mode 100644 index 0000000..3308ae1 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/IDocumentElementRequestor.java @@ -0,0 +1,411 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler; + +import net.sourceforge.phpdt.core.compiler.IProblem; + +/** + * Part of the source element parser responsible for building the output. + * It gets notified of structural information as they are detected, relying + * on the requestor to assemble them together, based on the notifications it got. + * + * The structural investigation includes: + * - package statement + * - import statements + * - top-level types: package member, member types (member types of member types...) + * - fields + * - methods + * + * If reference information is requested, then all source constructs are + * investigated and type, field & method references are provided as well. + * + * Any (parsing) problem encountered is also provided. + * + * All positions are relative to the exact source fed to the parser. + * + * Elements which are complex are notified in two steps: + * - enter : once the element header has been identified + * - exit : once the element has been fully consumed + * + * other simpler elements (package, import) are read all at once: + * - accept + */ + +public interface IDocumentElementRequestor { +/** + * @param declarationStart - a source position corresponding to the start of the package + * declaration + * @param declarationEnd - a source position corresponding to the end of the package + * declaration + * @param javaDocPositions - answer back an array of sourceStart/sourceEnd + * positions of the available JavaDoc comments. The array is a flattened + * structure: 2*n entries with consecutives start and end positions. + * If no JavaDoc is available, then null is answered instead of an empty array. + * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45 + * The array is equals to null if there are no javadoc comments + * @param name - the name of the package + * @param nameStartPosition - a source position corresponding to the first character of the + * name + * @param onDemand - a boolean equals to true if the import is an import on demand + */ +void acceptImport( + int declarationStart, + int declarationEnd, + int[] javaDocPositions, + char[] name, + int nameStartPosition, + boolean onDemand); +/** + * @param declarationStart - a source position corresponding to the start of the package + * declaration + * @param declarationEnd - a source position corresponding to the end of the package + * declaration + * @param javaDocPositions - answer back an array of sourceStart/sourceEnd + * positions of the available JavaDoc comments. The array is a flattened + * structure: 2*n entries with consecutives start and end positions. + * If no JavaDoc is available, then null is answered instead of an empty array. + * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45 + * The array is equals to null if there are no javadoc comments + * @param modifiers - the modifiers for this initializer + * @param modifiersStart - a source position corresponding to the start + * of the textual modifiers, is < 0 if there are no textual modifiers + * @param bodyStart - the position of the '{' + * @param bodyEnd - the position of the '}' + */ +void acceptInitializer( + int declarationStart, + int declarationEnd, + int[] javaDocPositions, + int modifiers, + int modifiersStart, + int bodyStart, + int bodyEnd); +/* + * Table of line separator position. This table is passed once at the end + * of the parse action, so as to allow computation of normalized ranges. + * + * A line separator might corresponds to several characters in the source, + * + */ +void acceptLineSeparatorPositions(int[] positions); +/** + * @param declarationStart - a source position corresponding to the start of the package + * declaration + * @param declarationEnd - a source position corresponding to the end of the package + * declaration + * @param javaDocPositions - answer back an array of sourceStart/sourceEnd + * positions of the available JavaDoc comments. The array is a flattened + * structure: 2*n entries with consecutives start and end positions. + * If no JavaDoc is available, then null is answered instead of an empty array. + * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45 + * The array is equals to null if there are no javadoc comments + * @param name - the name of the package + * @param nameStartPosition - a source position corresponding to the first character of the + * name + */ +void acceptPackage( + int declarationStart, + int declarationEnd, + int[] javaDocPositions, + char[] name, + int nameStartPosition); +/** + * @param problem - Used to report a problem while running the JDOM + */ +void acceptProblem(IProblem problem); +/** + * @param declarationStart - a source position corresponding to the start + * of this class. + * @param javaDocPositions - answer back an array of sourceStart/sourceEnd + * positions of the available JavaDoc comments. The array is a flattened + * structure: 2*n entries with consecutives start and end positions. + * If no JavaDoc is available, then null is answered instead of an empty array. + * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45 + * The array is equals to null if there are no javadoc comments + * @param modifiers - the modifiers for this class + * @param modifiersStart - a source position corresponding to the start + * of the textual modifiers, is < 0 if there are no textual modifiers + * @param classStart - a source position corresponding to the start + * of the keyword 'class' + * @param name - the name of the class + * @param nameStart - a source position corresponding to the start of the name + * @param nameEnd - a source position corresponding to the end of the name + * @param superclass - the name of the superclass + * @param superclassStart - a source position corresponding to the start + * of the superclass name + * @param superclassEnd - a source position corresponding to the end of the + * superclass name + * @param superinterfaces - the name of the superinterfaces + * @param superinterfaceStarts - an array of source positions corresponding + * to the start of their respective superinterface names + * @param superinterfaceEnds - an array of source positions corresponding + * to the end of their respective superinterface names + * @param bodyStart - a source position corresponding to the open bracket + * of the class body + */ +void enterClass( + int declarationStart, + int[] javaDocPositions, + int modifiers, + int modifiersStart, + int classStart, + char[] name, + int nameStart, + int nameEnd, + char[] superclass, + int superclassStart, + int superclassEnd, + char[][] superinterfaces, + int[] superinterfaceStarts, + int[] superinterfaceEnds, + int bodyStart); +void enterCompilationUnit(); +/** + * @param declarationStart - a source position corresponding to the first character + * of this constructor declaration + * @param javaDocPositions - answer back an array of sourceStart/sourceEnd + * positions of the available JavaDoc comments. The array is a flattened + * structure: 2*n entries with consecutives start and end positions. + * If no JavaDoc is available, then null is answered instead of an empty array. + * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45 + * The array is equals to null if there are no javadoc comments + * @param modifiers - the modifiers for this constructor converted to a flag + * @param modifiersStart - a source position corresponding to the first character of the + * textual modifiers + * @param name - the name of this constructor + * @param nameStart - a source position corresponding to the first character of the name + * @param nameEnd - a source position corresponding to the last character of the name + * @param parameterTypes - a list of parameter type names + * @param parameterTypeStarts - a list of source positions corresponding to the + * first character of each parameter type name + * @param parameterTypeEnds - a list of source positions corresponding to the + * last character of each parameter type name + * @param parameterNames - a list of the names of the parameters + * @param parametersEnd - a source position corresponding to the last character of the + * parameter list + * @param exceptionTypes - a list of the exception types + * @param exceptionTypeStarts - a list of source positions corresponding to the first + * character of the respective exception types + * @param exceptionTypeEnds - a list of source positions corresponding to the last + * character of the respective exception types + * @param bodyStart - a source position corresponding to the start of this + * constructor's body + */ +void enterConstructor( + int declarationStart, + int[] javaDocPositions, + int modifiers, + int modifiersStart, + char[] name, + int nameStart, + int nameEnd, + char[][] parameterTypes, + int [] parameterTypeStarts, + int [] parameterTypeEnds, + char[][] parameterNames, + int [] parameterNameStarts, + int [] parameterNameEnds, + int parametersEnd, + char[][] exceptionTypes, + int [] exceptionTypeStarts, + int [] exceptionTypeEnds, + int bodyStart); +/** + * @param declarationStart - a source position corresponding to the first character + * of this field + * @param javaDocPositions - answer back an array of sourceStart/sourceEnd + * positions of the available JavaDoc comments. The array is a flattened + * structure: 2*n entries with consecutives start and end positions. + * If no JavaDoc is available, then null is answered instead of an empty array. + * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45 + * The array is equals to null if there are no javadoc comments + * @param modifiers - the modifiers for this field converted to a flag + * @param modifiersStart - a source position corresponding to the first character of the + * textual modifiers + * @param type - the name of the field type + * @param typeStart - a source position corresponding to the start of the fields type + * @param typeEnd - a source position corresponding to the end of the fields type + * @param typeDimensionCount - the array dimension indicated on the type (for example, 'int[] v') + * @param name - the name of this constructor + * @param nameStart - a source position corresponding to the first character of the name + * @param nameEnd - a source position corresponding to the last character of the name + * @param extendedTypeDimensionCount - the array dimension indicated on the variable, + * (for example, 'int v[]') + * @param extendedTypeDimnesionEnd - a source position corresponding to the end of + * the extened type dimension. This position should be -1 in case there is no extended + * dimension for the type. + */ +void enterField( + int declarationStart, + int[] javaDocPositions, + int modifiers, + int modifiersStart, + char[] type, + int typeStart, + int typeEnd, + int typeDimensionCount, + char[] name, + int nameStart, + int nameEnd, + int extendedTypeDimensionCount, + int extendedTypeDimensionEnd); +/** + * @param declarationStart - a source position corresponding to the start + * of this class. + * @param javaDocPositions - answer back an array of sourceStart/sourceEnd + * positions of the available JavaDoc comments. The array is a flattened + * structure: 2*n entries with consecutives start and end positions. + * If no JavaDoc is available, then null is answered instead of an empty array. + * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45 + * The array is equals to null if there are no javadoc comments + * @param modifiers - the modifiers for this class + * @param modifiersStart - a source position corresponding to the start + * of the textual modifiers, is < 0 if there are no textual modifiers + * @param interfaceStart - a source position corresponding to the start + * of the keyword 'interface' + * @param name - the name of the class + * @param nameStart - a source position corresponding to the start of the name + * @param nameEnd - a source position corresponding to the end of the name + * @param superinterfaces - the name of the superinterfaces + * @param superinterfaceStarts - an array of source positions corresponding + * to the start of their respective superinterface names + * @param superinterfaceEnds - an array of source positions corresponding + * to the end of their respective superinterface names + * @param bodyStart - a source position corresponding to the open bracket + * of the class body + */ +void enterInterface( + int declarationStart, + int[] javaDocPositions, + int modifiers, + int modifiersStart, + int interfaceStart, + char[] name, + int nameStart, + int nameEnd, + char[][] superinterfaces, + int[] superinterfaceStarts, + int[] superinterfaceEnds, + int bodyStart); +/** + * @param declarationStart - a source position corresponding to the first character + * of this constructor declaration + * @param javaDocPositions - answer back an array of sourceStart/sourceEnd + * positions of the available JavaDoc comments. The array is a flattened + * structure: 2*n entries with consecutives start and end positions. + * If no JavaDoc is available, then null is answered instead of an empty array. + * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45 + * The array is equals to null if there are no javadoc comments + * @param modifiers - the modifiers for this constructor converted to a flag + * @param modifiersStart - a source position corresponding to the first character of the + * textual modifiers + * @param returnType - the name of the return type + * @param returnTypeStart - a source position corresponding to the first character + * of the return type + * @param returnTypeEnd - a source position corresponding to the last character + * of the return type + * @param returnTypeDimensionCount - the array dimension count as supplied on the + * return type (for example, 'public int[] foo() {}') + * @param name - the name of this constructor + * @param nameStart - a source position corresponding to the first character of the name + * @param nameEnd - a source position corresponding to the last character of the name + * @param parameterTypes - a list of parameter type names + * @param parameterTypeStarts - a list of source positions corresponding to the + * first character of each parameter type name + * @param parameterTypeEnds - a list of source positions corresponding to the + * last character of each parameter type name + * @param parameterNames - a list of the names of the parameters + * @param parametersEnd - a source position corresponding to the last character of the + * parameter list + * @param extendedReturnTypeDimensionCount - the array dimension count as supplied on the + * end of the parameter list (for example, 'public int foo()[] {}') + * @param extendedReturnTypeDimensionEnd - a source position corresponding to the last character + * of the extended return type dimension. This position should be -1 in case there is no extended + * dimension for the type. + * @param exceptionTypes - a list of the exception types + * @param exceptionTypeStarts - a list of source positions corresponding to the first + * character of the respective exception types + * @param exceptionTypeEnds - a list of source positions corresponding to the last + * character of the respective exception types + * @param bodyStart - a source position corresponding to the start of this + * method's body + */ +void enterMethod( + int declarationStart, + int[] javaDocPositions, + int modifiers, + int modifiersStart, + char[] returnType, + int returnTypeStart, + int returnTypeEnd, + int returnTypeDimensionCount, + char[] name, + int nameStart, + int nameEnd, + char[][] parameterTypes, + int [] parameterTypeStarts, + int [] parameterTypeEnds, + char[][] parameterNames, + int [] parameterNameStarts, + int [] parameterNameEnds, + int parametersEnd, + int extendedReturnTypeDimensionCount, + int extendedReturnTypeDimensionEnd, + char[][] exceptionTypes, + int [] exceptionTypeStarts, + int [] exceptionTypeEnds, + int bodyStart); +/** + * @param bodyEnd - a source position corresponding to the closing bracket of the class + * @param declarationEnd - a source position corresponding to the end of the class + * declaration. This can include whitespace and comments following the closing bracket. + */ +void exitClass( + int bodyEnd, + int declarationEnd); +/** + * @param declarationEnd - a source position corresponding to the end of the compilation unit + */ +void exitCompilationUnit( + int declarationEnd); +/** + * @param bodyEnd - a source position corresponding to the closing bracket of the method + * @param declarationEnd - a source position corresponding to the end of the method + * declaration. This can include whitespace and comments following the closing bracket. + */ +void exitConstructor( + int bodyEnd, + int declarationEnd); +/** + * @param bodyEnd - a source position corresponding to the end of the field. + * @param declarationEnd - a source position corresponding to the end of the field. + * This can include whitespace and comments following the semi-colon. + */ +void exitField( + int bodyEnd, + int declarationEnd); +/** + * @param bodyEnd - a source position corresponding to the closing bracket of the interface + * @param declarationEnd - a source position corresponding to the end of the interface + * declaration. This can include whitespace and comments following the closing bracket. + */ +void exitInterface( + int bodyEnd, + int declarationEnd); +/** + * @param bodyEnd - a source position corresponding to the closing bracket of the method + * @param declarationEnd - a source position corresponding to the end of the method + * declaration. This can include whitespace and comments following the closing bracket. + */ +void exitMethod( + int bodyEnd, + int declarationEnd); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/IErrorHandlingPolicy.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/IErrorHandlingPolicy.java new file mode 100644 index 0000000..48d74b8 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/IErrorHandlingPolicy.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler; + +/* + * Handler policy is responsible to answer the 2 following + * questions: + * 1. should the handler stop on first problem which appears + * to be a real error (that is, not a warning), + * 2. should it proceed once it has gathered all problems + * + * The intent is that one can supply its own policy to implement + * some interactive error handling strategy where some UI would + * display problems and ask user if he wants to proceed or not. + */ + +public interface IErrorHandlingPolicy { + boolean proceedOnErrors(); + boolean stopOnFirstError(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/IProblemFactory.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/IProblemFactory.java new file mode 100644 index 0000000..bc424f7 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/IProblemFactory.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler; + +import java.util.Locale; + +import net.sourceforge.phpdt.core.compiler.IProblem; + + + +/* + * Factory used from inside the compiler to build the actual problems + * which are handed back in the compilation result. + * + * This allows sharing the internal problem representation with the environment. + * + * Note: The factory is responsible for computing and storing a localized error message. + */ + +public interface IProblemFactory { + + IProblem createProblem( + char[] originatingFileName, + int problemId, + String[] problemArguments, + String[] messageArguments, // shorter versions of the problemArguments + int severity, + int startPosition, + int endPosition, + int lineNumber); + + Locale getLocale(); + + String getLocalizedMessage(int problemId, String[] messageArguments); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ISourceElementRequestor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ISourceElementRequestor.java new file mode 100644 index 0000000..dea0622 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ISourceElementRequestor.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler; + +import net.sourceforge.phpdt.core.compiler.IProblem; + +/* + * Part of the source element parser responsible for building the output. + * It gets notified of structural information as they are detected, relying + * on the requestor to assemble them together, based on the notifications it got. + * + * The structural investigation includes: + * - package statement + * - import statements + * - top-level types: package member, member types (member types of member types...) + * - fields + * - methods + * + * If reference information is requested, then all source constructs are + * investigated and type, field & method references are provided as well. + * + * Any (parsing) problem encountered is also provided. + * + * All positions are relative to the exact source fed to the parser. + * + * Elements which are complex are notified in two steps: + * - enter : once the element header has been identified + * - exit : once the element has been fully consumed + * + * other simpler elements (package, import) are read all at once: + * - accept + */ + +public interface ISourceElementRequestor { + void acceptConstructorReference(char[] typeName, int argCount, int sourcePosition); + //void acceptFieldReference(char[] fieldName, int sourcePosition); + /** + * @param declarationStart This is the position of the first character of the + * import keyword. + * @param declarationEnd This is the position of the ';' ending the import statement + * or the end of the comment following the import. + * @param name This is the name of the import like specified in the source including the dots. The '.*' + * is never included in the name. + * @param onDemand set to true if the import is an import on demand (e.g. import java.io.*). False otherwise. + */ + //void acceptImport( + // int declarationStart, + // int declarationEnd, + // char[] name, + // boolean onDemand); + /* + * Table of line separator position. This table is passed once at the end + * of the parse action, so as to allow computation of normalized ranges. + * + * A line separator might corresponds to several characters in the source, + * + */ + void acceptLineSeparatorPositions(int[] positions); + void acceptMethodReference(char[] methodName, int argCount, int sourcePosition); + //void acceptPackage( + // int declarationStart, + // int declarationEnd, + // char[] name); + void acceptProblem(IProblem problem); + void acceptTypeReference(char[][] typeName, int sourceStart, int sourceEnd); + void acceptTypeReference(char[] typeName, int sourcePosition); + void acceptUnknownReference(char[][] name, int sourceStart, int sourceEnd); + void acceptUnknownReference(char[] name, int sourcePosition); + void enterClass( + int declarationStart, + int modifiers, + char[] name, + int nameSourceStart, + int nameSourceEnd, + char[] superclass, + char[][] superinterfaces); + void enterCompilationUnit(); + void enterConstructor( + int declarationStart, + int modifiers, + char[] name, + int nameSourceStart, + int nameSourceEnd, + char[][] parameterTypes, + char[][] parameterNames, + char[][] exceptionTypes); + void enterField(int declarationStart, int modifiers, char[] type, char[] name, int nameSourceStart, int nameSourceEnd); + //void enterInitializer( + // int declarationStart, + // int modifiers); + void enterInterface( + int declarationStart, + int modifiers, + char[] name, + int nameSourceStart, + int nameSourceEnd, + char[][] superinterfaces); + void enterMethod( + int declarationStart, + int modifiers, + char[] returnType, + char[] name, + int nameSourceStart, + int nameSourceEnd, + char[][] parameterTypes, + char[][] parameterNames, + char[][] exceptionTypes); + void exitClass(int declarationEnd); + void exitCompilationUnit(int declarationEnd); + void exitConstructor(int declarationEnd); + /* + * initializationStart denotes the source start of the expression used for initializing + * the field if any (-1 if no initialization). + */ + //void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd); + void exitInitializer(int declarationEnd); + void exitInterface(int declarationEnd); + void exitMethod(int declarationEnd); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/SourceElementParser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/SourceElementParser.java new file mode 100644 index 0000000..b3c72a0 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/SourceElementParser.java @@ -0,0 +1,1293 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler; + +import java.util.ArrayList; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; +import net.sourceforge.phpdt.internal.compiler.env.ISourceType; +import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope; +import net.sourceforge.phpdt.internal.compiler.parser.UnitParser; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; +import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.AnonymousLocalTypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.Argument; +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.ExplicitConstructorCall; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.LocalTypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.MemberTypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.NameReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedAllocationExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeReference; + + + +/** + * A source element parser extracts structural and reference information + * from a piece of source. + * + * also see @ISourceElementRequestor + * + * The structural investigation includes: + * - the package statement + * - import statements + * - top-level types: package member, member types (member types of member types...) + * - fields + * - methods + * + * If reference information is requested, then all source constructs are + * investigated and type, field & method references are provided as well. + * + * Any (parsing) problem encountered is also provided. + */ + +public class SourceElementParser extends UnitParser { + + ISourceElementRequestor requestor; + int fieldCount; + int localIntPtr; + int lastFieldEndPosition; + ISourceType sourceType; + boolean reportReferenceInfo; + char[][] typeNames; + char[][] superTypeNames; + int nestedTypeIndex; + static final char[] JAVA_LANG_OBJECT = "java.lang.Object".toCharArray(); //$NON-NLS-1$ + NameReference[] unknownRefs; + int unknownRefsCounter; + LocalDeclarationVisitor localDeclarationVisitor = null; +// CompilerOptions options; + +/** + * An ast visitor that visits local type declarations. + */ +public class LocalDeclarationVisitor extends AbstractSyntaxTreeVisitorAdapter { +// public boolean visit( +// AnonymousLocalTypeDeclaration anonymousTypeDeclaration, +// BlockScope scope) { +// notifySourceElementRequestor(anonymousTypeDeclaration, sourceType == null); +// return false; // don't visit members as this was done during notifySourceElementRequestor(...) +// } + public boolean visit(LocalTypeDeclaration typeDeclaration, BlockScope scope) { + notifySourceElementRequestor(typeDeclaration, sourceType == null); + return false; // don't visit members as this was done during notifySourceElementRequestor(...) + } + public boolean visit(MemberTypeDeclaration typeDeclaration, ClassScope scope) { + notifySourceElementRequestor(typeDeclaration, sourceType == null); + return false; // don't visit members as this was done during notifySourceElementRequestor(...) + } + +} + +public SourceElementParser( + final ISourceElementRequestor requestor, + IProblemFactory problemFactory) { +// CompilerOptions options) { + // we want to notify all syntax error with the acceptProblem API + // To do so, we define the record method of the ProblemReporter + super( + new ProblemReporter( + DefaultErrorHandlingPolicies.exitAfterAllProblems(), +// options, + problemFactory) { + public void record(IProblem problem, CompilationResult unitResult, ReferenceContext referenceContext) { + unitResult.record(problem, referenceContext); + requestor.acceptProblem(problem); + } + }); +// true); +// options.sourceLevel >= CompilerOptions.JDK1_4); + this.requestor = requestor; + typeNames = new char[4][]; + superTypeNames = new char[4][]; + nestedTypeIndex = 0; +// this.options = options; +} + +/** @deprecated use SourceElementParser(ISourceElementRequestor, IProblemFactory, CompilerOptions) */ +//public SourceElementParser( +// final ISourceElementRequestor requestor, +// IProblemFactory problemFactory) { +// this(requestor, problemFactory, new CompilerOptions()); +//} + +//public SourceElementParser( +// final ISourceElementRequestor requestor, +// IProblemFactory problemFactory, +// CompilerOptions options, +// boolean reportLocalDeclarations) { +// this(requestor, problemFactory, options); +// if (reportLocalDeclarations) { +// this.localDeclarationVisitor = new LocalDeclarationVisitor(); +// } +//} + +//public void checkAnnotation() { +// int firstCommentIndex = scanner.commentPtr; +// +// super.checkAnnotation(); +// +// // modify the modifier source start to point at the first comment +// if (firstCommentIndex >= 0) { +// modifiersSourceStart = scanner.commentStarts[0]; +// } +//} + +//protected void classInstanceCreation(boolean alwaysQualified) { +// +// boolean previousFlag = reportReferenceInfo; +// reportReferenceInfo = false; // not to see the type reference reported in super call to getTypeReference(...) +// super.classInstanceCreation(alwaysQualified); +// reportReferenceInfo = previousFlag; +// if (reportReferenceInfo){ +// AllocationExpression alloc = (AllocationExpression)expressionStack[expressionPtr]; +// TypeReference typeRef = alloc.type; +// requestor.acceptConstructorReference( +// typeRef instanceof SingleTypeReference +// ? ((SingleTypeReference) typeRef).token +// : CharOperation.concatWith(alloc.type.getTypeName(), '.'), +// alloc.arguments == null ? 0 : alloc.arguments.length, +// alloc.sourceStart); +// } +//} +//protected void consumeConstructorHeaderName() { +// // ConstructorHeaderName ::= Modifiersopt 'Identifier' '(' +// +// /* recovering - might be an empty message send */ +// if (currentElement != null){ +// if (lastIgnoredToken == TokenNamenew){ // was an allocation expression +// lastCheckPoint = scanner.startPosition; // force to restart at this exact position +// restartRecovery = true; +// return; +// } +// } +// SourceConstructorDeclaration cd = new SourceConstructorDeclaration(this.compilationUnit.compilationResult); +// +// //name -- this is not really revelant but we do ..... +// cd.selector = identifierStack[identifierPtr]; +// long selectorSourcePositions = identifierPositionStack[identifierPtr--]; +// identifierLengthPtr--; +// +// //modifiers +// cd.declarationSourceStart = intStack[intPtr--]; +// cd.modifiers = intStack[intPtr--]; +// +// //highlight starts at the selector starts +// cd.sourceStart = (int) (selectorSourcePositions >>> 32); +// cd.selectorSourceEnd = (int) selectorSourcePositions; +// pushOnAstStack(cd); +// +// cd.sourceEnd = lParenPos; +// cd.bodyStart = lParenPos+1; +// listLength = 0; // initialize listLength before reading parameters/throws +// +// // recovery +// if (currentElement != null){ +// lastCheckPoint = cd.bodyStart; +// if ((currentElement instanceof RecoveredType && lastIgnoredToken != TokenNameDOT) +// || cd.modifiers != 0){ +// currentElement = currentElement.add(cd, 0); +// lastIgnoredToken = -1; +// } +// } +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeExitVariableWithInitialization() { +// // ExitVariableWithInitialization ::= $empty +// // the scanner is located after the comma or the semi-colon. +// // we want to include the comma or the semi-colon +// super.consumeExitVariableWithInitialization(); +// if (isLocalDeclaration() || ((currentToken != TokenNameCOMMA) && (currentToken != TokenNameSEMICOLON))) +// return; +// ((SourceFieldDeclaration) astStack[astPtr]).fieldEndPosition = scanner.currentPosition - 1; +//} +//protected void consumeExitVariableWithoutInitialization() { +// // ExitVariableWithoutInitialization ::= $empty +// // do nothing by default +// super.consumeExitVariableWithoutInitialization(); +// if (isLocalDeclaration() || ((currentToken != TokenNameCOMMA) && (currentToken != TokenNameSEMICOLON))) +// return; +// ((SourceFieldDeclaration) astStack[astPtr]).fieldEndPosition = scanner.currentPosition - 1; +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeFieldAccess(boolean isSuperAccess) { +// // FieldAccess ::= Primary '.' 'Identifier' +// // FieldAccess ::= 'super' '.' 'Identifier' +// super.consumeFieldAccess(isSuperAccess); +// FieldReference fr = (FieldReference) expressionStack[expressionPtr]; +// if (reportReferenceInfo) { +// requestor.acceptFieldReference(fr.token, fr.sourceStart); +// } +//} +//protected void consumeMethodHeaderName() { +// // MethodHeaderName ::= Modifiersopt Type 'Identifier' '(' +// SourceMethodDeclaration md = new SourceMethodDeclaration(this.compilationUnit.compilationResult); +// +// //name +// md.selector = identifierStack[identifierPtr]; +// long selectorSourcePositions = identifierPositionStack[identifierPtr--]; +// identifierLengthPtr--; +// //type +// md.returnType = getTypeReference(intStack[intPtr--]); +// //modifiers +// md.declarationSourceStart = intStack[intPtr--]; +// md.modifiers = intStack[intPtr--]; +// +// //highlight starts at selector start +// md.sourceStart = (int) (selectorSourcePositions >>> 32); +// md.selectorSourceEnd = (int) selectorSourcePositions; +// pushOnAstStack(md); +// md.sourceEnd = lParenPos; +// md.bodyStart = lParenPos+1; +// listLength = 0; // initialize listLength before reading parameters/throws +// +// // recovery +// if (currentElement != null){ +// if (currentElement instanceof RecoveredType +// //|| md.modifiers != 0 +// || (scanner.getLineNumber(md.returnType.sourceStart) +// == scanner.getLineNumber(md.sourceStart))){ +// lastCheckPoint = md.bodyStart; +// currentElement = currentElement.add(md, 0); +// lastIgnoredToken = -1; +// } else { +// lastCheckPoint = md.sourceStart; +// restartRecovery = true; +// } +// } +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeMethodInvocationName() { +// // MethodInvocation ::= Name '(' ArgumentListopt ')' +// +// // when the name is only an identifier...we have a message send to "this" (implicit) +// super.consumeMethodInvocationName(); +// MessageSend messageSend = (MessageSend) expressionStack[expressionPtr]; +// Expression[] args = messageSend.arguments; +// if (reportReferenceInfo) { +// requestor.acceptMethodReference( +// messageSend.selector, +// args == null ? 0 : args.length, +// (int)(messageSend.nameSourcePosition >>> 32)); +// } +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeMethodInvocationPrimary() { +// super.consumeMethodInvocationPrimary(); +// MessageSend messageSend = (MessageSend) expressionStack[expressionPtr]; +// Expression[] args = messageSend.arguments; +// if (reportReferenceInfo) { +// requestor.acceptMethodReference( +// messageSend.selector, +// args == null ? 0 : args.length, +// (int)(messageSend.nameSourcePosition >>> 32)); +// } +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//protected void consumeMethodInvocationSuper() { +// // MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')' +// super.consumeMethodInvocationSuper(); +// MessageSend messageSend = (MessageSend) expressionStack[expressionPtr]; +// Expression[] args = messageSend.arguments; +// if (reportReferenceInfo) { +// requestor.acceptMethodReference( +// messageSend.selector, +// args == null ? 0 : args.length, +// (int)(messageSend.nameSourcePosition >>> 32)); +// } +//} +//protected void consumeSingleTypeImportDeclarationName() { +// // SingleTypeImportDeclarationName ::= 'import' Name +// /* push an ImportRef build from the last name +// stored in the identifier stack. */ +// +// super.consumeSingleTypeImportDeclarationName(); +// ImportReference impt = (ImportReference)astStack[astPtr]; +// if (reportReferenceInfo) { +// requestor.acceptTypeReference(impt.tokens, impt.sourceStart, impt.sourceEnd); +// } +//} +//protected void consumeTypeImportOnDemandDeclarationName() { +// // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*' +// /* push an ImportRef build from the last name +// stored in the identifier stack. */ +// +// super.consumeTypeImportOnDemandDeclarationName(); +// ImportReference impt = (ImportReference)astStack[astPtr]; +// if (reportReferenceInfo) { +// requestor.acceptUnknownReference(impt.tokens, impt.sourceStart, impt.sourceEnd); +// } +//} +//protected FieldDeclaration createFieldDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) { +// return new SourceFieldDeclaration(null, name, sourceStart, sourceEnd); +//} +//protected CompilationUnitDeclaration endParse(int act) { +// if (sourceType != null) { +// if (sourceType.isInterface()) { +// consumeInterfaceDeclaration(); +// } else { +// consumeClassDeclaration(); +// } +// } +// if (compilationUnit != null) { +// CompilationUnitDeclaration result = super.endParse(act); +// return result; +// } else { +// return null; +// } +//} +/* + * Flush annotations defined prior to a given positions. + * + * Note: annotations are stacked in syntactical order + * + * Either answer given , or the end position of a comment line + * immediately following the (same line) + * + * e.g. + * void foo(){ + * } // end of method foo + */ +// +//public int flushAnnotationsDefinedPriorTo(int position) { +// +// return lastFieldEndPosition = super.flushAnnotationsDefinedPriorTo(position); +//} +//public TypeReference getTypeReference(int dim) { +// /* build a Reference on a variable that may be qualified or not +// * This variable is a type reference and dim will be its dimensions +// */ +// int length; +// if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) { +// // single variable reference +// if (dim == 0) { +// SingleTypeReference ref = +// new SingleTypeReference( +// identifierStack[identifierPtr], +// identifierPositionStack[identifierPtr--]); +// if (reportReferenceInfo) { +// requestor.acceptTypeReference(ref.token, ref.sourceStart); +// } +// return ref; +// } else { +// ArrayTypeReference ref = +// new ArrayTypeReference( +// identifierStack[identifierPtr], +// dim, +// identifierPositionStack[identifierPtr--]); +// ref.sourceEnd = endPosition; +// if (reportReferenceInfo) { +// requestor.acceptTypeReference(ref.token, ref.sourceStart); +// } +// return ref; +// } +// } else { +// if (length < 0) { //flag for precompiled type reference on base types +// TypeReference ref = TypeReference.baseTypeReference(-length, dim); +// ref.sourceStart = intStack[intPtr--]; +// if (dim == 0) { +// ref.sourceEnd = intStack[intPtr--]; +// } else { +// intPtr--; // no need to use this position as it is an array +// ref.sourceEnd = endPosition; +// } +// if (reportReferenceInfo){ +// requestor.acceptTypeReference(ref.getTypeName(), ref.sourceStart, ref.sourceEnd); +// } +// return ref; +// } else { //Qualified variable reference +// char[][] tokens = new char[length][]; +// identifierPtr -= length; +// long[] positions = new long[length]; +// System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length); +// System.arraycopy( +// identifierPositionStack, +// identifierPtr + 1, +// positions, +// 0, +// length); +// if (dim == 0) { +// QualifiedTypeReference ref = new QualifiedTypeReference(tokens, positions); +// if (reportReferenceInfo) { +// requestor.acceptTypeReference(ref.tokens, ref.sourceStart, ref.sourceEnd); +// } +// return ref; +// } else { +// ArrayQualifiedTypeReference ref = +// new ArrayQualifiedTypeReference(tokens, dim, positions); +// ref.sourceEnd = endPosition; +// if (reportReferenceInfo) { +// requestor.acceptTypeReference(ref.tokens, ref.sourceStart, ref.sourceEnd); +// } +// return ref; +// } +// } +// } +//} +//public NameReference getUnspecifiedReference() { +// /* build a (unspecified) NameReference which may be qualified*/ +// +// int length; +// if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) { +// // single variable reference +// SingleNameReference ref = +// new SingleNameReference( +// identifierStack[identifierPtr], +// identifierPositionStack[identifierPtr--]); +// if (reportReferenceInfo) { +// this.addUnknownRef(ref); +// } +// return ref; +// } else { +// //Qualified variable reference +// char[][] tokens = new char[length][]; +// identifierPtr -= length; +// System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length); +// QualifiedNameReference ref = +// new QualifiedNameReference( +// tokens, +// (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart +// (int) identifierPositionStack[identifierPtr + length]); // sourceEnd +// if (reportReferenceInfo) { +// this.addUnknownRef(ref); +// } +// return ref; +// } +//} +//public NameReference getUnspecifiedReferenceOptimized() { +// /* build a (unspecified) NameReference which may be qualified +// The optimization occurs for qualified reference while we are +// certain in this case the last item of the qualified name is +// a field access. This optimization is IMPORTANT while it results +// that when a NameReference is build, the type checker should always +// look for that it is not a type reference */ +// +// int length; +// if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) { +// // single variable reference +// SingleNameReference ref = +// new SingleNameReference( +// identifierStack[identifierPtr], +// identifierPositionStack[identifierPtr--]); +// ref.bits &= ~AstNode.RestrictiveFlagMASK; +// ref.bits |= LOCAL | FIELD; +// if (reportReferenceInfo) { +// this.addUnknownRef(ref); +// } +// return ref; +// } +// +// //Qualified-variable-reference +// //In fact it is variable-reference DOT field-ref , but it would result in a type +// //conflict tha can be only reduce by making a superclass (or inetrface ) between +// //nameReference and FiledReference or putting FieldReference under NameReference +// //or else..........This optimisation is not really relevant so just leave as it is +// +// char[][] tokens = new char[length][]; +// identifierPtr -= length; +// System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length); +// QualifiedNameReference ref = +// new QualifiedNameReference( +// tokens, +// (int) (identifierPositionStack[identifierPtr + 1] >> 32), +// // sourceStart +// (int) identifierPositionStack[identifierPtr + length]); // sourceEnd +// ref.bits &= ~AstNode.RestrictiveFlagMASK; +// ref.bits |= LOCAL | FIELD; +// if (reportReferenceInfo) { +// this.addUnknownRef(ref); +// } +// return ref; +//} +///** +// * +// * INTERNAL USE-ONLY +// */ +//private boolean isLocalDeclaration() { +// int nestedDepth = nestedType; +// while (nestedDepth >= 0) { +// if (nestedMethod[nestedDepth] != 0) { +// return true; +// } +// nestedDepth--; +// } +// return false; +//} +/* + * Update the bodyStart of the corresponding parse node + */ +public void notifySourceElementRequestor(CompilationUnitDeclaration parsedUnit) { + if (parsedUnit == null) { + // when we parse a single type member declaration the compilation unit is null, but we still + // want to be able to notify the requestor on the created ast node + if (astStack[0] instanceof AbstractMethodDeclaration) { + notifySourceElementRequestor((AbstractMethodDeclaration) astStack[0]); + return; + } + return; + } + // range check + boolean isInRange = + scanner.initialPosition <= parsedUnit.sourceStart + && scanner.eofPosition >= parsedUnit.sourceEnd; + +// if (reportReferenceInfo) { +// notifyAllUnknownReferences(); +// } + // collect the top level ast nodes + int length = 0; + AstNode[] nodes = null; + if (sourceType == null){ + if (isInRange) { + requestor.enterCompilationUnit(); + } +// ImportReference currentPackage = parsedUnit.currentPackage; +// ImportReference[] imports = parsedUnit.imports; +// TypeDeclaration[] types = parsedUnit.types; + ArrayList types = parsedUnit.types; + if (types != null) { +// length = +// (currentPackage == null ? 0 : 1) +// + (imports == null ? 0 : imports.length) +// + (types == null ? 0 : types.length); +// nodes = new AstNode[length]; + length = types.size(); + nodes = new AstNode[length]; + int index = 0; +// if (currentPackage != null) { +// nodes[index++] = currentPackage; +// } +// if (imports != null) { +// for (int i = 0, max = imports.length; i < max; i++) { +// nodes[index++] = imports[i]; +// } +// } + + for (int i = 0, max = types.size(); i < max; i++) { + nodes[index++] = (AstNode)types.get(i); + } + } + } else { +// TypeDeclaration[] types = parsedUnit.types; + ArrayList types = parsedUnit.types; + if (types != null) { + length = types.size(); + nodes = new AstNode[length]; + for (int i = 0, max = types.size(); i < max; i++) { + nodes[i] = (AstNode)types.get(i); + } + } + } + + // notify the nodes in the syntactical order + if (nodes != null && length > 0) { + quickSort(nodes, 0, length-1); + for (int i=0;i= methodDeclaration.declarationSourceEnd; + + if (methodDeclaration.isClinit()) { + this.visitIfNeeded(methodDeclaration); + return; + } + + if (methodDeclaration.isDefaultConstructor()) { + if (reportReferenceInfo) { + ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration; + ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall; + if (constructorCall != null) { + switch(constructorCall.accessMode) { + case ExplicitConstructorCall.This : + requestor.acceptConstructorReference( + typeNames[nestedTypeIndex-1], + constructorCall.arguments == null ? 0 : constructorCall.arguments.length, + constructorCall.sourceStart); + break; + case ExplicitConstructorCall.Super : + case ExplicitConstructorCall.ImplicitSuper : + requestor.acceptConstructorReference( + superTypeNames[nestedTypeIndex-1], + constructorCall.arguments == null ? 0 : constructorCall.arguments.length, + constructorCall.sourceStart); + break; + } + } + } + return; + } + char[][] argumentTypes = null; + char[][] argumentNames = null; + Argument[] arguments = methodDeclaration.arguments; + if (arguments != null) { + int argumentLength = arguments.length; + argumentTypes = new char[argumentLength][]; + argumentNames = new char[argumentLength][]; + for (int i = 0; i < argumentLength; i++) { + argumentTypes[i] = returnTypeName(arguments[i].type); + argumentNames[i] = arguments[i].name; + } + } + char[][] thrownExceptionTypes = null; + TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions; + if (thrownExceptions != null) { + int thrownExceptionLength = thrownExceptions.length; + thrownExceptionTypes = new char[thrownExceptionLength][]; + for (int i = 0; i < thrownExceptionLength; i++) { + thrownExceptionTypes[i] = + CharOperation.concatWith(thrownExceptions[i].getTypeName(), '.'); + } + } + // by default no selector end position + int selectorSourceEnd = -1; + if (methodDeclaration.isConstructor()) { +// if (methodDeclaration instanceof SourceConstructorDeclaration) { +// selectorSourceEnd = +// ((SourceConstructorDeclaration) methodDeclaration).selectorSourceEnd; +// } + if (isInRange){ + requestor.enterConstructor( + methodDeclaration.declarationSourceStart, + methodDeclaration.modifiers, + methodDeclaration.selector, + methodDeclaration.sourceStart, + selectorSourceEnd, + argumentTypes, + argumentNames, + thrownExceptionTypes); + } + if (reportReferenceInfo) { + ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration; + ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall; + if (constructorCall != null) { + switch(constructorCall.accessMode) { + case ExplicitConstructorCall.This : + requestor.acceptConstructorReference( + typeNames[nestedTypeIndex-1], + constructorCall.arguments == null ? 0 : constructorCall.arguments.length, + constructorCall.sourceStart); + break; + case ExplicitConstructorCall.Super : + case ExplicitConstructorCall.ImplicitSuper : + requestor.acceptConstructorReference( + superTypeNames[nestedTypeIndex-1], + constructorCall.arguments == null ? 0 : constructorCall.arguments.length, + constructorCall.sourceStart); + break; + } + } + } + this.visitIfNeeded(methodDeclaration); + if (isInRange){ + requestor.exitConstructor(methodDeclaration.declarationSourceEnd); + } + return; + } +// if (methodDeclaration instanceof SourceMethodDeclaration) { +// selectorSourceEnd = +// ((SourceMethodDeclaration) methodDeclaration).selectorSourceEnd; +// } + if (isInRange) { + int modifiers = methodDeclaration.modifiers; +// boolean deprecated = (modifiers & AccDeprecated) != 0; // remember deprecation so as to not lose it below + requestor.enterMethod( + methodDeclaration.declarationSourceStart, + modifiers, // deprecated ? (modifiers & AccJustFlag) | AccDeprecated : modifiers & AccJustFlag, + returnTypeName(((MethodDeclaration) methodDeclaration).returnType), + methodDeclaration.selector, + methodDeclaration.sourceStart, + selectorSourceEnd, + argumentTypes, + argumentNames, + thrownExceptionTypes); + } + this.visitIfNeeded(methodDeclaration); + + if (isInRange){ + requestor.exitMethod(methodDeclaration.declarationSourceEnd); + } +} +///* +//* Update the bodyStart of the corresponding parse node +//*/ +//public void notifySourceElementRequestor(FieldDeclaration fieldDeclaration) { +// +// // range check +// boolean isInRange = +// scanner.initialPosition <= fieldDeclaration.declarationSourceStart +// && scanner.eofPosition >= fieldDeclaration.declarationSourceEnd; +// +// if (fieldDeclaration.isField()) { +// int fieldEndPosition = fieldDeclaration.declarationSourceEnd; +// if (fieldDeclaration instanceof SourceFieldDeclaration) { +// fieldEndPosition = ((SourceFieldDeclaration) fieldDeclaration).fieldEndPosition; +// if (fieldEndPosition == 0) { +// // use the declaration source end by default +// fieldEndPosition = fieldDeclaration.declarationSourceEnd; +// } +// } +// if (isInRange) { +// int modifiers = fieldDeclaration.modifiers; +// boolean deprecated = (modifiers & AccDeprecated) != 0; // remember deprecation so as to not lose it below +// requestor.enterField( +// fieldDeclaration.declarationSourceStart, +// deprecated ? (modifiers & AccJustFlag) | AccDeprecated : modifiers & AccJustFlag, +// returnTypeName(fieldDeclaration.type), +// fieldDeclaration.name, +// fieldDeclaration.sourceStart, +// fieldDeclaration.sourceEnd); +// } +// this.visitIfNeeded(fieldDeclaration); +// if (isInRange){ +// requestor.exitField( +// // filter out initializations that are not a constant (simple check) +// (fieldDeclaration.initialization == null +// || fieldDeclaration.initialization instanceof ArrayInitializer +// || fieldDeclaration.initialization instanceof AllocationExpression +// || fieldDeclaration.initialization instanceof ArrayAllocationExpression +// || fieldDeclaration.initialization instanceof Assignment +// || fieldDeclaration.initialization instanceof ClassLiteralAccess +// || fieldDeclaration.initialization instanceof MessageSend +// || fieldDeclaration.initialization instanceof ArrayReference +// || fieldDeclaration.initialization instanceof ThisReference) ? +// -1 : +// fieldDeclaration.initialization.sourceStart, +// fieldEndPosition, +// fieldDeclaration.declarationSourceEnd); +// } +// +// } else { +// if (isInRange){ +// requestor.enterInitializer( +// fieldDeclaration.declarationSourceStart, +// fieldDeclaration.modifiers); +// } +// this.visitIfNeeded((Initializer)fieldDeclaration); +// if (isInRange){ +// requestor.exitInitializer(fieldDeclaration.declarationSourceEnd); +// } +// } +//} +//public void notifySourceElementRequestor( +// ImportReference importReference, +// boolean isPackage) { +// if (isPackage) { +// requestor.acceptPackage( +// importReference.declarationSourceStart, +// importReference.declarationSourceEnd, +// CharOperation.concatWith(importReference.getImportName(), '.')); +// } else { +// requestor.acceptImport( +// importReference.declarationSourceStart, +// importReference.declarationSourceEnd, +// CharOperation.concatWith(importReference.getImportName(), '.'), +// importReference.onDemand); +// } +//} +public void notifySourceElementRequestor(TypeDeclaration typeDeclaration, boolean notifyTypePresence) { +//// public void notifySourceElementRequestor(AstNode typeDeclaration, boolean notifyTypePresence) { + + // range check + boolean isInRange = + scanner.initialPosition <= typeDeclaration.declarationSourceStart + && scanner.eofPosition >= typeDeclaration.declarationSourceEnd; + + FieldDeclaration[] fields = typeDeclaration.fields; + AbstractMethodDeclaration[] methods = typeDeclaration.methods; + MemberTypeDeclaration[] memberTypes = typeDeclaration.memberTypes; + int fieldCount = fields == null ? 0 : fields.length; + int methodCount = methods == null ? 0 : methods.length; + int memberTypeCount = memberTypes == null ? 0 : memberTypes.length; + int fieldIndex = 0; + int methodIndex = 0; + int memberTypeIndex = 0; + boolean isInterface = typeDeclaration.isInterface(); + + if (notifyTypePresence){ + char[][] interfaceNames = null; + int superInterfacesLength = 0; + TypeReference[] superInterfaces = typeDeclaration.superInterfaces; + if (superInterfaces != null) { + superInterfacesLength = superInterfaces.length; + interfaceNames = new char[superInterfacesLength][]; + } else { + if (typeDeclaration instanceof AnonymousLocalTypeDeclaration) { + // see PR 3442 + QualifiedAllocationExpression alloc = ((AnonymousLocalTypeDeclaration)typeDeclaration).allocation; + if (alloc != null && alloc.type != null) { + superInterfaces = new TypeReference[] { ((AnonymousLocalTypeDeclaration)typeDeclaration).allocation.type}; + superInterfacesLength = 1; + interfaceNames = new char[1][]; + } + } + } + if (superInterfaces != null) { + for (int i = 0; i < superInterfacesLength; i++) { + interfaceNames[i] = + CharOperation.concatWith(superInterfaces[i].getTypeName(), '.'); + } + } + if (isInterface) { + if (isInRange){ + int modifiers = typeDeclaration.modifiers; + boolean deprecated = false; //(modifiers & AccDeprecated) != 0; // remember deprecation so as to not lose it below + requestor.enterInterface( + typeDeclaration.declarationSourceStart, + modifiers, //deprecated ? (modifiers & AccJustFlag) | AccDeprecated : modifiers & AccJustFlag, + typeDeclaration.name, + typeDeclaration.sourceStart, + typeDeclaration.sourceEnd, + interfaceNames); + } + if (nestedTypeIndex == typeNames.length) { + // need a resize + System.arraycopy(typeNames, 0, (typeNames = new char[nestedTypeIndex * 2][]), 0, nestedTypeIndex); + System.arraycopy(superTypeNames, 0, (superTypeNames = new char[nestedTypeIndex * 2][]), 0, nestedTypeIndex); + } + typeNames[nestedTypeIndex] = typeDeclaration.name; + superTypeNames[nestedTypeIndex++] = JAVA_LANG_OBJECT; + } else { + TypeReference superclass = typeDeclaration.superclass; + if (superclass == null) { + if (isInRange){ + requestor.enterClass( + typeDeclaration.declarationSourceStart, + typeDeclaration.modifiers, + typeDeclaration.name, + typeDeclaration.sourceStart, + typeDeclaration.sourceEnd, + null, + interfaceNames); + } + } else { + if (isInRange){ + requestor.enterClass( + typeDeclaration.declarationSourceStart, + typeDeclaration.modifiers, + typeDeclaration.name, + typeDeclaration.sourceStart, + typeDeclaration.sourceEnd, + CharOperation.concatWith(superclass.getTypeName(), '.'), + interfaceNames); + } + } + if (nestedTypeIndex == typeNames.length) { + // need a resize + System.arraycopy(typeNames, 0, (typeNames = new char[nestedTypeIndex * 2][]), 0, nestedTypeIndex); + System.arraycopy(superTypeNames, 0, (superTypeNames = new char[nestedTypeIndex * 2][]), 0, nestedTypeIndex); + } + typeNames[nestedTypeIndex] = typeDeclaration.name; + superTypeNames[nestedTypeIndex++] = superclass == null ? JAVA_LANG_OBJECT : CharOperation.concatWith(superclass.getTypeName(), '.'); + } + } + while ((fieldIndex < fieldCount) + || (memberTypeIndex < memberTypeCount) + || (methodIndex < methodCount)) { + FieldDeclaration nextFieldDeclaration = null; + AbstractMethodDeclaration nextMethodDeclaration = null; + TypeDeclaration nextMemberDeclaration = null; + + int position = Integer.MAX_VALUE; + int nextDeclarationType = -1; + if (fieldIndex < fieldCount) { + nextFieldDeclaration = fields[fieldIndex]; + if (nextFieldDeclaration.declarationSourceStart < position) { + position = nextFieldDeclaration.declarationSourceStart; + nextDeclarationType = 0; // FIELD + } + } + if (methodIndex < methodCount) { + nextMethodDeclaration = methods[methodIndex]; + if (nextMethodDeclaration.declarationSourceStart < position) { + position = nextMethodDeclaration.declarationSourceStart; + nextDeclarationType = 1; // METHOD + } + } + if (memberTypeIndex < memberTypeCount) { + nextMemberDeclaration = memberTypes[memberTypeIndex]; + if (nextMemberDeclaration.declarationSourceStart < position) { + position = nextMemberDeclaration.declarationSourceStart; + nextDeclarationType = 2; // MEMBER + } + } + switch (nextDeclarationType) { + case 0 : + fieldIndex++; +// notifySourceElementRequestor(nextFieldDeclaration); + break; + case 1 : + methodIndex++; + notifySourceElementRequestor(nextMethodDeclaration); + break; + case 2 : + memberTypeIndex++; + notifySourceElementRequestor(nextMemberDeclaration, true); + } + } + if (notifyTypePresence){ + if (isInRange){ + if (isInterface) { + requestor.exitInterface(typeDeclaration.declarationSourceEnd); + } else { + requestor.exitClass(typeDeclaration.declarationSourceEnd); + } + } + nestedTypeIndex--; + } +} +public void parseCompilationUnit ( + ICompilationUnit unit, + int start, + int end ) { +// boolean needReferenceInfo) { + +// reportReferenceInfo = needReferenceInfo; +// boolean old = diet; +// if (needReferenceInfo) { +// unknownRefs = new NameReference[10]; +// unknownRefsCounter = 0; +// } + + try { +// diet = true; + CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, 10); //this.options.maxProblemsPerUnit); + CompilationUnitDeclaration parsedUnit = parse(unit, compilationUnitResult, start, end); +// if (scanner.recordLineSeparator) { +// requestor.acceptLineSeparatorPositions(scanner.getLineEnds()); +// } +// if (this.localDeclarationVisitor != null || needReferenceInfo){ +// diet = false; +// this.getMethodBodies(parsedUnit); +// } +// this.scanner.resetTo(start, end); +// notifySourceElementRequestor(parsedUnit); + } catch (AbortCompilation e) { + } finally { +// diet = old; + } +} +public void parseCompilationUnit( + ICompilationUnit unit, + boolean needReferenceInfo) { +// boolean old = diet; +// if (needReferenceInfo) { +// unknownRefs = new NameReference[10]; +// unknownRefsCounter = 0; +// } + + try { +// diet = true; + reportReferenceInfo = needReferenceInfo; + CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, 10); //this.options.maxProblemsPerUnit); + CompilationUnitDeclaration parsedUnit = parse(unit, compilationUnitResult); + if (scanner.recordLineSeparator) { + requestor.acceptLineSeparatorPositions(scanner.getLineEnds()); + } + int initialStart = this.scanner.initialPosition; + int initialEnd = this.scanner.eofPosition; +// if (this.localDeclarationVisitor != null || needReferenceInfo){ +// diet = false; +// this.getMethodBodies(parsedUnit); +// } + this.scanner.resetTo(initialStart, initialEnd); + notifySourceElementRequestor(parsedUnit); + } catch (AbortCompilation e) { + } finally { +// diet = old; + } +} +//public void parseTypeMemberDeclarations( +// ISourceType sourceType, +// ICompilationUnit sourceUnit, +// int start, +// int end, +// boolean needReferenceInfo) { +// boolean old = diet; +// if (needReferenceInfo) { +// unknownRefs = new NameReference[10]; +// unknownRefsCounter = 0; +// } +// +// try { +// diet = !needReferenceInfo; +// reportReferenceInfo = needReferenceInfo; +// CompilationResult compilationUnitResult = +// new CompilationResult(sourceUnit, 0, 0, this.options.maxProblemsPerUnit); +// CompilationUnitDeclaration unit = +// SourceTypeConverter.buildCompilationUnit( +// new ISourceType[]{sourceType}, +// false, // no need for field and methods +// false, // no need for member types +// false, // no need for field initialization +// problemReporter(), +// compilationUnitResult); +// if ((unit == null) || (unit.types == null) || (unit.types.length != 1)) +// return; +// this.sourceType = sourceType; +// try { +// /* automaton initialization */ +// initialize(); +// goForClassBodyDeclarations(); +// /* scanner initialization */ +// scanner.setSource(sourceUnit.getContents()); +// scanner.resetTo(start, end); +// /* unit creation */ +// referenceContext = compilationUnit = unit; +// /* initialize the astStacl */ +// // the compilationUnitDeclaration should contain exactly one type +// pushOnAstStack(unit.types[0]); +// /* run automaton */ +// parse(); +// notifySourceElementRequestor(unit); +// } finally { +// unit = compilationUnit; +// compilationUnit = null; // reset parser +// } +// } catch (AbortCompilation e) { +// } finally { +// if (scanner.recordLineSeparator) { +// requestor.acceptLineSeparatorPositions(scanner.getLineEnds()); +// } +// diet = old; +// } +//} +// +//public void parseTypeMemberDeclarations( +// char[] contents, +// int start, +// int end) { +// +// boolean old = diet; +// +// try { +// diet = true; +// +// /* automaton initialization */ +// initialize(); +// goForClassBodyDeclarations(); +// /* scanner initialization */ +// scanner.setSource(contents); +// scanner.recordLineSeparator = false; +// scanner.taskTags = null; +// scanner.taskPriorities = null; +// scanner.resetTo(start, end); +// +// /* unit creation */ +// referenceContext = null; +// +// /* initialize the astStacl */ +// // the compilationUnitDeclaration should contain exactly one type +// /* run automaton */ +// parse(); +// notifySourceElementRequestor((CompilationUnitDeclaration)null); +// } catch (AbortCompilation e) { +// } finally { +// diet = old; +// } +//} +/** + * Sort the given ast nodes by their positions. + */ +private static void quickSort(AstNode[] sortedCollection, int left, int right) { + int original_left = left; + int original_right = right; + AstNode mid = sortedCollection[ (left + right) / 2]; + do { + while (sortedCollection[left].sourceStart < mid.sourceStart) { + left++; + } + while (mid.sourceStart < sortedCollection[right].sourceStart) { + right--; + } + if (left <= right) { + AstNode tmp = sortedCollection[left]; + sortedCollection[left] = sortedCollection[right]; + sortedCollection[right] = tmp; + left++; + right--; + } + } while (left <= right); + if (original_left < right) { + quickSort(sortedCollection, original_left, right); + } + if (left < original_right) { + quickSort(sortedCollection, left, original_right); + } +} +/* + * Answer a char array representation of the type name formatted like: + * - type name + dimensions + * Example: + * "A[][]".toCharArray() + * "java.lang.String".toCharArray() + */ +private char[] returnTypeName(TypeReference type) { + if (type == null) + return null; + int dimension = type.dimensions(); + if (dimension != 0) { + char[] dimensionsArray = new char[dimension * 2]; + for (int i = 0; i < dimension; i++) { + dimensionsArray[i * 2] = '['; + dimensionsArray[(i * 2) + 1] = ']'; + } + return CharOperation.concat( + CharOperation.concatWith(type.getTypeName(), '.'), + dimensionsArray); + } + return CharOperation.concatWith(type.getTypeName(), '.'); +} + +public void addUnknownRef(NameReference nameRef) { + if (this.unknownRefs.length == this.unknownRefsCounter) { + // resize + System.arraycopy( + this.unknownRefs, + 0, + (this.unknownRefs = new NameReference[this.unknownRefsCounter * 2]), + 0, + this.unknownRefsCounter); + } + this.unknownRefs[this.unknownRefsCounter++] = nameRef; +} + +private void visitIfNeeded(AbstractMethodDeclaration method) { + if (this.localDeclarationVisitor != null + && (method.bits & AstNode.HasLocalTypeMASK) != 0) { + if (method.statements != null) { + int statementsLength = method.statements.length; + for (int i = 0; i < statementsLength; i++) + method.statements[i].traverse(this.localDeclarationVisitor, method.scope); + } + } +} + +//private void visitIfNeeded(FieldDeclaration field) { +// if (this.localDeclarationVisitor != null +// && (field.bits & AstNode.HasLocalTypeMASK) != 0) { +// if (field.initialization != null) { +// field.initialization.traverse(this.localDeclarationVisitor, null); +// } +// } +//} +// +//private void visitIfNeeded(Initializer initializer) { +// if (this.localDeclarationVisitor != null +// && (initializer.bits & AstNode.HasLocalTypeMASK) != 0) { +// if (initializer.block != null) { +// initializer.block.traverse(this.localDeclarationVisitor, null); +// } +// } +//} +// +//protected void reportSyntaxError(int act, int currentKind, int stateStackTop) { +// if (compilationUnit == null) return; +// super.reportSyntaxError(act, currentKind,stateStackTop); +//} + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AstNode.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AstNode.java index 4d3aec2..e4ccbbb 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AstNode.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AstNode.java @@ -11,6 +11,9 @@ public abstract class AstNode { /** Starting and ending position of the node in the sources. */ public int sourceStart, sourceEnd; + protected AstNode() { + super(); + } /** * Create a node giving starting and ending offset. * @param sourceStart starting offset diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/codegen/CaseLabel.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/codegen/CaseLabel.java new file mode 100644 index 0000000..ff7ce6d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/codegen/CaseLabel.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.codegen; + +public class CaseLabel extends Label { + public int instructionPosition = POS_NOT_SET; + public int backwardsBranch = POS_NOT_SET; +/** + * CaseLabel constructor comment. + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +//public CaseLabel(CodeStream codeStream) { +// super(codeStream); +//} +/* +* Put down a refernece to the array at the location in the codestream. +*/ +//void branch() { +// if (position == POS_NOT_SET) { +// addForwardReference(codeStream.position); +// // Leave 4 bytes free to generate the jump offset afterwards +// codeStream.position += 4; +// codeStream.classFileOffset += 4; +// } else { //Position is set. Write it! +// codeStream.writeSignedWord(position - codeStream.position + 1); +// } +//} +///* +//* Put down a refernece to the array at the location in the codestream. +//*/ +//void branchWide() { +// if (position == POS_NOT_SET) { +// addForwardReference(codeStream.position); +// // Leave 4 bytes free to generate the jump offset afterwards +// codeStream.position += 4; +// } else { //Position is set. Write it! +// codeStream.writeSignedWord(position - codeStream.position + 1); +// } +//} +//public boolean isStandardLabel(){ +// return false; +//} +///* +//* Put down a reference to the array at the location in the codestream. +//*/ +//public void place() { +// position = codeStream.position; +// if (instructionPosition == POS_NOT_SET) +// backwardsBranch = position; +// else { +// int offset = position - instructionPosition; +// for (int i = 0; i < forwardReferenceCount; i++) { +// codeStream.writeSignedWord(forwardReferences[i], offset); +// } +// // add the label int the codeStream labels collection +// codeStream.addLabel(this); +// } +//} +/* +* Put down a refernece to the array at the location in the codestream. +*/ +//void placeInstruction() { +// if (instructionPosition == POS_NOT_SET) { +// instructionPosition = codeStream.position; +// if (backwardsBranch != POS_NOT_SET) { +// int offset = backwardsBranch - instructionPosition; +// for (int i = 0; i < forwardReferenceCount; i++) +// codeStream.writeSignedWord(forwardReferences[i], offset); +// backwardsBranch = POS_NOT_SET; +// } +// } +//} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/codegen/Label.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/codegen/Label.java new file mode 100644 index 0000000..1179c83 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/codegen/Label.java @@ -0,0 +1,253 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.codegen; + +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpdt.internal.compiler.problem.AbortMethod; + +/** + * This type is a port of smalltalks JavaLabel + */ +public class Label { +// public CodeStream codeStream; + final static int POS_NOT_SET = -1; + public int position = POS_NOT_SET; // position=POS_NOT_SET Then it's pos is not set. + public int[] forwardReferences = new int[10]; // Add an overflow check here. + public int forwardReferenceCount = 0; + private boolean isWide = false; +public Label() { +} +/** + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +//public Label(CodeStream codeStream) { +// this.codeStream = codeStream; +//} +/** + * Add a forward refrence for the array. + */ +void addForwardReference(int iPos) { + int length; + if (forwardReferenceCount >= (length = forwardReferences.length)) + System.arraycopy(forwardReferences, 0, (forwardReferences = new int[2*length]), 0, length); + forwardReferences[forwardReferenceCount++] = iPos; +} +/** + * Add a forward refrence for the array. + */ +public void appendForwardReferencesFrom(Label otherLabel) { + int otherCount = otherLabel.forwardReferenceCount; + if (otherCount == 0) return; + int length = forwardReferences.length; + int neededSpace = otherCount + forwardReferenceCount; + if (neededSpace >= length){ + System.arraycopy(forwardReferences, 0, (forwardReferences = new int[neededSpace]), 0, forwardReferenceCount); + } + // append other forward references at the end, so they will get updated as well + System.arraycopy(otherLabel.forwardReferences, 0, forwardReferences, forwardReferenceCount, otherCount); + forwardReferenceCount = neededSpace; +} +/* +* Put down a refernece to the array at the location in the codestream. +*/ +//void branch() { +// if (position == POS_NOT_SET) { +// addForwardReference(codeStream.position); +// // Leave two bytes free to generate the jump afterwards +// codeStream.position += 2; +// codeStream.classFileOffset += 2; +// } else { +// /* +// * Position is set. Write it if it is not a wide branch. +// */ +// int offset = position - codeStream.position + 1; +// if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) { +// throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE); +// } +// codeStream.writeSignedShort((short) offset); +// } +//} +/* +* No support for wide branches yet +*/ +//void branchWide() { +// if (position == POS_NOT_SET) { +// addForwardReference(codeStream.position); +// // Leave 4 bytes free to generate the jump offset afterwards +// isWide = true; +// codeStream.position += 4; +// codeStream.classFileOffset += 4; +// } else { //Position is set. Write it! +// codeStream.writeSignedWord(position - codeStream.position + 1); +// } +//} +/** + * @return boolean + */ +public boolean hasForwardReferences() { + return forwardReferenceCount != 0; +} +/* + * Some placed labels might be branching to a goto bytecode which we can optimize better. + */ +//public void inlineForwardReferencesFromLabelsTargeting(int gotoLocation) { +///* +// Code required to optimized unreachable gotos. +// public boolean isBranchTarget(int location) { +// Label[] labels = codeStream.labels; +// for (int i = codeStream.countLabels - 1; i >= 0; i--){ +// Label label = labels[i]; +// if ((label.position == location) && label.isStandardLabel()){ +// return true; +// } +// } +// return false; +// } +// */ +// +// Label[] labels = codeStream.labels; +// for (int i = codeStream.countLabels - 1; i >= 0; i--){ +// Label label = labels[i]; +// if ((label.position == gotoLocation) && label.isStandardLabel()){ +// this.appendForwardReferencesFrom(label); +// /* +// Code required to optimized unreachable gotos. +// label.position = POS_NOT_SET; +// */ +// } else { +// break; // same target labels should be contiguous +// } +// } +//} +public boolean isStandardLabel(){ + return true; +} +/* +* Place the label. If we have forward references resolve them. +*/ +//public void place() { // Currently lacking wide support. +// if (position == POS_NOT_SET) { +// position = codeStream.position; +// codeStream.addLabel(this); +// int oldPosition = position; +// boolean optimizedBranch = false; +// // TURNED OFF since fail on 1F4IRD9 +// if (forwardReferenceCount != 0) { +// if (optimizedBranch = (forwardReferences[forwardReferenceCount - 1] + 2 == position) && (codeStream.bCodeStream[codeStream.classFileOffset - 3] == CodeStream.OPC_goto)) { +// codeStream.position = (position -= 3); +// codeStream.classFileOffset -= 3; +// forwardReferenceCount--; +// // also update the PCs in the related debug attributes +// /** OLD CODE +// int index = codeStream.pcToSourceMapSize - 1; +// while ((index >= 0) && (codeStream.pcToSourceMap[index][1] == oldPosition)) { +// codeStream.pcToSourceMap[index--][1] = position; +// } +// */ +// // Beginning of new code +// int index = codeStream.pcToSourceMapSize - 2; +// if (codeStream.lastEntryPC == oldPosition) { +// codeStream.lastEntryPC = position; +// } +// if ((index >= 0) && (codeStream.pcToSourceMap[index] == position)) { +// codeStream.pcToSourceMapSize-=2; +// } +// // end of new code +// if (codeStream.generateLocalVariableTableAttributes) { +// LocalVariableBinding locals[] = codeStream.locals; +// for (int i = 0, max = locals.length; i < max; i++) { +// LocalVariableBinding local = locals[i]; +// if ((local != null) && (local.initializationCount > 0)) { +// if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == oldPosition) { +// // we want to prevent interval of size 0 to have a negative size. +// // see PR 1GIRQLA: ITPJCORE:ALL - ClassFormatError for local variable attribute +// local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = position; +// } +// if (local.initializationPCs[(local.initializationCount - 1) << 1] == oldPosition) { +// local.initializationPCs[(local.initializationCount - 1) << 1] = position; +// } +// } +// } +// } +// } +// } +// for (int i = 0; i < forwardReferenceCount; i++) { +// int offset = position - forwardReferences[i] + 1; +// if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) { +// throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE); +// } +// if (this.codeStream.wideMode) { +// if (this.isWide) { +// codeStream.writeSignedWord(forwardReferences[i], offset); +// } else { +// codeStream.writeSignedShort(forwardReferences[i], (short) offset); +// } +// } else { +// codeStream.writeSignedShort(forwardReferences[i], (short) offset); +// } +// } +// // For all labels placed at that position we check if we need to rewrite the jump +// // offset. It is the case each time a label had a forward reference to the current position. +// // Like we change the current position, we have to change the jump offset. See 1F4IRD9 for more details. +// if (optimizedBranch) { +// for (int i = 0; i < codeStream.countLabels; i++) { +// Label label = codeStream.labels[i]; +// if (oldPosition == label.position) { +// label.position = position; +// if (label instanceof CaseLabel) { +// int offset = position - ((CaseLabel) label).instructionPosition; +// for (int j = 0; j < label.forwardReferenceCount; j++) { +// int forwardPosition = label.forwardReferences[j]; +// codeStream.writeSignedWord(forwardPosition, offset); +// } +// } else { +// for (int j = 0; j < label.forwardReferenceCount; j++) { +// int forwardPosition = label.forwardReferences[j]; +// int offset = position - forwardPosition + 1; +// if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) { +// throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE); +// } +// if (this.codeStream.wideMode) { +// if (this.isWide) { +// codeStream.writeSignedWord(forwardPosition, offset); +// } else { +// codeStream.writeSignedShort(forwardPosition, (short) offset); +// } +// } else { +// codeStream.writeSignedShort(forwardPosition, (short) offset); +// } +// } +// } +// } +// } +// } +// } +//} +/** + * Print out the receiver + */ +public String toString() { + StringBuffer buffer = new StringBuffer("(position="); //$NON-NLS-1$ + buffer.append(position); + buffer.append(", forwards = ["); //$NON-NLS-1$ + for (int i = 0; i < forwardReferenceCount - 1; i++) + buffer.append(forwardReferences[i] + ", "); //$NON-NLS-1$ + if (forwardReferenceCount >= 1) + buffer.append(forwardReferences[forwardReferenceCount-1]); + buffer.append("] )"); //$NON-NLS-1$ + return buffer.toString(); +} + +public void resetStateForCodeGeneration() { + this.position = POS_NOT_SET; + this.forwardReferenceCount = 0; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/codegen/ObjectCache.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/codegen/ObjectCache.java new file mode 100644 index 0000000..441d128 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/codegen/ObjectCache.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.codegen; + +public class ObjectCache { + public Object keyTable[]; + public int valueTable[]; + int elementSize; + int threshold; +/** + * Constructs a new, empty hashtable. A default capacity is used. + * Note that the hashtable will automatically grow when it gets full. + */ +public ObjectCache() { + this(13); +} +/** + * Constructs a new, empty hashtable with the specified initial + * capacity. + * @param initialCapacity int + * the initial number of buckets + */ +public ObjectCache(int initialCapacity) { + this.elementSize = 0; + this.threshold = (int) (initialCapacity * 0.66f); + this.keyTable = new Object[initialCapacity]; + this.valueTable = new int[initialCapacity]; +} +/** + * Clears the hash table so that it has no more elements in it. + */ +public void clear() { + for (int i = keyTable.length; --i >= 0;) { + keyTable[i] = null; + valueTable[i] = 0; + } + elementSize = 0; +} +/** Returns true if the collection contains an element for the key. + * + * @param char[] key the key that we are looking for + * @return boolean + */ +public boolean containsKey(Object key) { + int index = hashCode(key); + while (keyTable[index] != null) { + if (keyTable[index] == key) + return true; + index = (index + 1) % keyTable.length; + } + return false; +} +/** Gets the object associated with the specified key in the + * hashtable. + * @param key char[] the specified key + * @return int the element for the key or -1 if the key is not + * defined in the hash table. + */ +public int get(Object key) { + int index = hashCode(key); + while (keyTable[index] != null) { + if (keyTable[index] == key) + return valueTable[index]; + index = (index + 1) % keyTable.length; + } + return -1; +} +/** + * Return the hashcode for the key parameter + * + * @param key org.eclipse.jdt.internal.compiler.lookup.MethodBinding + * @return int + */ +public int hashCode(Object key) { + return (key.hashCode() & 0x7FFFFFFF) % keyTable.length; +} +/** + * Puts the specified element into the hashtable, using the specified + * key. The element may be retrieved by doing a get() with the same key. + * The key and the element cannot be null. + * + * @param key Object the specified key in the hashtable + * @param value int the specified element + * @return int the old value of the key, or -1 if it did not have one. + */ +public int put(Object key, int value) { + int index = hashCode(key); + while (keyTable[index] != null) { + if (keyTable[index] == key) + return valueTable[index] = value; + index = (index + 1) % keyTable.length; + } + keyTable[index] = key; + valueTable[index] = value; + + // assumes the threshold is never equal to the size of the table + if (++elementSize > threshold) + rehash(); + return value; +} +/** + * Rehashes the content of the table into a bigger table. + * This method is called automatically when the hashtable's + * size exceeds the threshold. + */ +private void rehash() { + ObjectCache newHashtable = new ObjectCache(keyTable.length * 2); + for (int i = keyTable.length; --i >= 0;) + if (keyTable[i] != null) + newHashtable.put(keyTable[i], valueTable[i]); + + this.keyTable = newHashtable.keyTable; + this.valueTable = newHashtable.valueTable; + this.threshold = newHashtable.threshold; +} +/** + * Returns the number of elements contained in the hashtable. + * + * @return int The size of the table + */ +public int size() { + return elementSize; +} +/** + * Converts to a rather lengthy String. + * + * @return String the ascii representation of the receiver + */ +public String toString() { + int max = size(); + StringBuffer buf = new StringBuffer(); + buf.append("{"); //$NON-NLS-1$ + for (int i = 0; i < max; ++i) { + if (keyTable[i] != null) { + buf.append(keyTable[i]).append("->").append(valueTable[i]); //$NON-NLS-1$ + } + if (i < max) { + buf.append(", "); //$NON-NLS-1$ + } + } + buf.append("}"); //$NON-NLS-1$ + return buf.toString(); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IBinaryField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IBinaryField.java new file mode 100644 index 0000000..e59888a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IBinaryField.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.env; + +import net.sourceforge.phpdt.internal.compiler.impl.Constant; + +public interface IBinaryField extends IGenericField { +/** + * + * @return org.eclipse.jdt.internal.compiler.Constant + */ +Constant getConstant(); +/** + * Answer the resolved name of the receiver's type in the + * class file format as specified in section 4.3.2 of the Java 2 VM spec. + * + * For example: + * - java.lang.String is Ljava/lang/String; + * - an int is I + * - a 2 dimensional array of strings is [[Ljava/lang/String; + * - an array of floats is [F + */ + +char[] getTypeName(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IBinaryMethod.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IBinaryMethod.java new file mode 100644 index 0000000..316c368 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IBinaryMethod.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.env; + +// clinit methods (synthetics too?) can be returned from IBinaryType>>getMethods() +// BUT do not have to be... the compiler will ignore them when building the binding. +// The synthetic argument of a member type's constructor (ie. the first arg of a non-static +// member type) is also ignored by the compiler, BUT in this case it must be included +// in the constructor's signature. + +public interface IBinaryMethod extends IGenericMethod { + +/** + * Answer the resolved names of the exception types in the + * class file format as specified in section 4.2 of the Java 2 VM spec + * or null if the array is empty. + * + * For example, java.lang.String is java/lang/String. + */ +char[][] getExceptionTypeNames(); + +/** + * Answer the receiver's method descriptor which describes the parameter & + * return types as specified in section 4.3.3 of the Java 2 VM spec. + * + * For example: + * - int foo(String) is (Ljava/lang/String;)I + * - Object[] foo(int) is (I)[Ljava/lang/Object; + */ +char[] getMethodDescriptor(); + +/** + * Answer whether the receiver represents a class initializer method. + */ +boolean isClinit(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IBinaryNestedType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IBinaryNestedType.java new file mode 100644 index 0000000..a9aa1f0 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IBinaryNestedType.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.env; + +public interface IBinaryNestedType { +/** + * Answer the resolved name of the enclosing type in the + * class file format as specified in section 4.2 of the Java 2 VM spec. + * + * For example, java.lang.String is java/lang/String. + */ + +char[] getEnclosingTypeName(); +/** + * Answer an int whose bits are set according the access constants + * defined by the VM spec. + */ + +// We have added AccDeprecated & AccSynthetic. + +int getModifiers(); +/** + * Answer the resolved name of the member type in the + * class file format as specified in section 4.2 of the Java 2 VM spec. + * + * For example, p1.p2.A.M is p1/p2/A$M. + */ + +char[] getName(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IBinaryType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IBinaryType.java new file mode 100644 index 0000000..b9f3d19 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IBinaryType.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.env; + +import net.sourceforge.phpdt.core.compiler.CharOperation; + +public interface IBinaryType extends IGenericType { + + char[][] NoInterface = CharOperation.NO_CHAR_CHAR; + IBinaryNestedType[] NoNestedType = new IBinaryNestedType[0]; + IBinaryField[] NoField = new IBinaryField[0]; + IBinaryMethod[] NoMethod = new IBinaryMethod[0]; +/** + * Answer the resolved name of the enclosing type in the + * class file format as specified in section 4.2 of the Java 2 VM spec + * or null if the receiver is a top level type. + * + * For example, java.lang.String is java/lang/String. + */ + +char[] getEnclosingTypeName(); +/** + * Answer the receiver's fields or null if the array is empty. + */ + +IBinaryField[] getFields(); +/** + * Answer the resolved names of the receiver's interfaces in the + * class file format as specified in section 4.2 of the Java 2 VM spec + * or null if the array is empty. + * + * For example, java.lang.String is java/lang/String. + */ + +char[][] getInterfaceNames(); +/** + * Answer the receiver's nested types or null if the array is empty. + * + * This nested type info is extracted from the inner class attributes. + * Ask the name environment to find a member type using its compound name. + */ + +// NOTE: The compiler examines the nested type info & ignores the local types +// so the local types do not have to be included. + +IBinaryNestedType[] getMemberTypes(); +/** + * Answer the receiver's methods or null if the array is empty. + */ + +IBinaryMethod[] getMethods(); +/** + * Answer the resolved name of the type in the + * class file format as specified in section 4.2 of the Java 2 VM spec. + * + * For example, java.lang.String is java/lang/String. + */ + +char[] getName(); +/** + * Answer the resolved name of the receiver's superclass in the + * class file format as specified in section 4.2 of the Java 2 VM spec + * or null if it does not have one. + * + * For example, java.lang.String is java/lang/String. + */ + +char[] getSuperclassName(); + +/** + * Answer true if the receiver is an anonymous class. + * false otherwise + */ +boolean isAnonymous(); + +/** + * Answer true if the receiver is a local class. + * false otherwise + */ +boolean isLocal(); + +/** + * Answer true if the receiver is a member class. + * false otherwise + */ +boolean isMember(); + +/** + * Answer the source file attribute, or null if none. + * + * For example, "String.java" + */ + +char[] sourceFileName(); + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/ICompilationUnit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/ICompilationUnit.java new file mode 100644 index 0000000..811f518 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/ICompilationUnit.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.env; + +/** + * This interface denotes a compilation unit, providing its name and content. + */ +public interface ICompilationUnit extends IDependent { +/** + * Answer the contents of the compilation unit. + * + * In normal use, the contents are requested twice. + * Once during the initial lite parsing step, then again for the + * more detailed parsing step. + */ +char[] getContents(); +/** + * Answer the name of the top level public type. + * For example, {Hashtable}. + */ +char[] getMainTypeName(); +/** + * Answer the name of the package according to the directory structure + * or null if package consistency checks should be ignored. + * For example, {java, lang}. + */ +char[][] getPackageName(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IConstants.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IConstants.java index fd4092c..a0f7338 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IConstants.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IConstants.java @@ -27,8 +27,8 @@ public interface IConstants { // int AccVolatile = 0x0040; // int AccTransient = 0x0080; // int AccNative = 0x0100; -// int AccInterface = 0x0200; -// int AccAbstract = 0x0400; + int AccInterface = 0x0200; + int AccAbstract = 0x0400; // int AccStrictfp = 0x0800; /* @@ -40,5 +40,5 @@ public interface IConstants { * Extra flags for types and members. */ // int AccSynthetic = 0x20000; -// int AccDeprecated = 0x100000; + int AccDeprecated = 0x100000; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IDependent.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IDependent.java new file mode 100644 index 0000000..8229ea5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IDependent.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.env; + +/** + * This represents the target file of a type dependency. + * + * All implementors of this interface are containers for types or types + * themselves which must be able to identify their source file name + * when file dependencies are collected. + */ +public interface IDependent { +/** + * Answer the file name which defines the type. + * + * The path part (optional) must be separated from the actual + * file proper name by a java.io.File.separator. + * + * The proper file name includes the suffix extension (e.g. ".java") + * + * e.g. "c:/com/ibm/compiler/java/api/Compiler.java" + */ + +char[] getFileName(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IGenericField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IGenericField.java new file mode 100644 index 0000000..ac1f15e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IGenericField.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.env; + +public interface IGenericField { +/** + * Answer an int whose bits are set according the access constants + * defined by the VM spec. + */ + +// We have added AccDeprecated & AccSynthetic. + +int getModifiers(); +/** + * Answer the name of the field. + */ + +char[] getName(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IGenericMethod.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IGenericMethod.java new file mode 100644 index 0000000..5c17762 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IGenericMethod.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.env; + +public interface IGenericMethod { +/** + * Answer an int whose bits are set according the access constants + * defined by the VM spec. + */ +// We have added AccDeprecated & AccSynthetic. +int getModifiers(); + +/** + * Answer the name of the method. + * + * For a constructor, answer & for a clinit method. + */ +char[] getSelector(); + +boolean isConstructor(); + +/** + * Answer the names of the argument + * or null if the argument names are not available. + */ + +char[][] getArgumentNames(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IGenericType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IGenericType.java new file mode 100644 index 0000000..7d1bf79 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IGenericType.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.env; + +public interface IGenericType extends IDependent { +/** + * Answer an int whose bits are set according the access constants + * defined by the VM spec. + */ + +// We have added AccDeprecated & AccSynthetic. + +// NOTE: If the receiver represents a member type, the modifiers are extracted from its inner class attributes. + +int getModifiers(); +/** + * Answer whether the receiver contains the resolved binary form + * or the unresolved source form of the type. + */ + +boolean isBinaryType(); +boolean isClass(); +boolean isInterface(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/INameEnvironment.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/INameEnvironment.java new file mode 100644 index 0000000..63cb9ff --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/INameEnvironment.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.env; + +/** + * The name environment provides a callback API that the compiler + * can use to look up types, compilation units, and packages in the + * current environment. The name environment is passed to the compiler + * on creation. + */ +public interface INameEnvironment { +/** + * Find a type with the given compound name. + * Answer the binary form of the type if it is known to be consistent. + * Otherwise, answer the compilation unit which defines the type + * or null if the type does not exist. + * Types in the default package are specified as {{typeName}}. + * + * It is unknown whether the package containing the type actually exists. + * + * NOTE: This method can be used to find a member type using its + * internal name A$B, but the source file for A is answered if the binary + * file is inconsistent. + */ + +NameEnvironmentAnswer findType(char[][] compoundTypeName); +/** + * Find a type named in the package . + * Answer the binary form of the type if it is known to be consistent. + * Otherwise, answer the compilation unit which defines the type + * or null if the type does not exist. + * The default package is indicated by char[0][]. + * + * It is known that the package containing the type exists. + * + * NOTE: This method can be used to find a member type using its + * internal name A$B, but the source file for A is answered if the binary + * file is inconsistent. + */ + +NameEnvironmentAnswer findType(char[] typeName, char[][] packageName); +/** + * Answer whether packageName is the name of a known subpackage inside + * the package parentPackageName. A top level package is found relative to null. + * The default package is always assumed to exist. + * + * For example: + * isPackage({{java}, {awt}}, {event}); + * isPackage(null, {java}); + */ + +boolean isPackage(char[][] parentPackageName, char[] packageName); + +/** + * This method cleans the environment uo. It is responsible for releasing the memory + * and freeing resources. Passed that point, the name environment is no longer usable. + * + * A name environment can have a long life cycle, therefore it is the responsibility of + * the code which created it to decide when it is a good time to clean it up. + */ +void cleanup(); + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/ISourceField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/ISourceField.java new file mode 100644 index 0000000..2cb6e1d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/ISourceField.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.env; + +public interface ISourceField extends IGenericField { +/** + * Answer the source end position of the field's declaration. + */ +int getDeclarationSourceEnd(); + +/** + * Answer the source start position of the field's declaration. + */ +int getDeclarationSourceStart(); + +/** + * Answer the initialization source for this constant field. + * Answer null if the field is not a constant or if it has no initialization. + */ +char[] getInitializationSource(); + +/** + * Answer the source end position of the field's name. + */ +int getNameSourceEnd(); + +/** + * Answer the source start position of the field's name. + */ +int getNameSourceStart(); + +/** + * Answer the type name of the field. + * + * The name is a simple name or a qualified, dot separated name. + * For example, Hashtable or java.util.Hashtable. + */ +char[] getTypeName(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/ISourceMethod.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/ISourceMethod.java new file mode 100644 index 0000000..ce667c8 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/ISourceMethod.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.env; + +public interface ISourceMethod extends IGenericMethod { + +/** + * Answer the unresolved names of the argument types + * or null if the array is empty. + * + * A name is a simple name or a qualified, dot separated name. + * For example, Hashtable or java.util.Hashtable. + */ + +char[][] getArgumentTypeNames(); +/** + * Answer the source end position of the method's declaration. + */ + +int getDeclarationSourceEnd(); +/** + * Answer the source start position of the method's declaration. + */ + +int getDeclarationSourceStart(); +/** + * Answer the unresolved names of the exception types + * or null if the array is empty. + * + * A name is a simple name or a qualified, dot separated name. + * For example, Hashtable or java.util.Hashtable. + */ + +char[][] getExceptionTypeNames(); +/** + * Answer the source end position of the method's selector. + */ + +int getNameSourceEnd(); +/** + * Answer the source start position of the method's selector. + */ + +int getNameSourceStart(); +/** + * Answer the unresolved name of the return type + * or null if receiver is a constructor or clinit. + * + * The name is a simple name or a qualified, dot separated name. + * For example, Hashtable or java.util.Hashtable. + */ + +char[] getReturnTypeName(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/ISourceType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/ISourceType.java new file mode 100644 index 0000000..59c7534 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/ISourceType.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.env; + +public interface ISourceType extends IGenericType { +/** + * Answer the source end position of the type's declaration. + */ + +int getDeclarationSourceEnd(); +/** + * Answer the source start position of the type's declaration. + */ + +int getDeclarationSourceStart(); +/** + * Answer the enclosing type + * or null if the receiver is a top level type. + */ + +ISourceType getEnclosingType(); +/** + * Answer the receiver's fields or null if the array is empty. + * + * NOTE: Multiple fields with the same name can exist in the result. + */ + +ISourceField[] getFields(); +/** + * Answer the unresolved names of the receiver's imports + * or null if the array is empty. + * + * An import is a qualified, dot separated name. + * For example, java.util.Hashtable or java.lang.*. + */ + +char[][] getImports(); +/** + * Answer the unresolved names of the receiver's interfaces + * or null if the array is empty. + * + * A name is a simple name or a qualified, dot separated name. + * For example, Hashtable or java.util.Hashtable. + */ + +char[][] getInterfaceNames(); +/** + * Answer the receiver's member types + * or null if the array is empty. + */ + +ISourceType[] getMemberTypes(); +/** + * Answer the receiver's methods or null if the array is empty. + * + * NOTE: Multiple methods with the same name & parameter types can exist in the result. + */ + +ISourceMethod[] getMethods(); +/** + * Answer the simple source name of the receiver. + */ + +char[] getName(); +/** + * Answer the source end position of the type's name. + */ + +int getNameSourceEnd(); +/** + * Answer the source start position of the type's name. + */ + +int getNameSourceStart(); +/** + * Answer the qualified name of the receiver's package separated by periods + * or null if its the default package. + * + * For example, {java.util.Hashtable}. + */ + +char[] getPackageName(); +/** + * Answer the qualified name of the receiver. + * + * The name is a qualified, dot separated name. + * For example, java.util.Hashtable. + */ + +char[] getQualifiedName(); +/** + * Answer the unresolved name of the receiver's superclass + * or null if it does not have one. + * + * The name is a simple name or a qualified, dot separated name. + * For example, Hashtable or java.util.Hashtable. + */ + +char[] getSuperclassName(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/NameEnvironmentAnswer.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/NameEnvironmentAnswer.java new file mode 100644 index 0000000..b022209 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/NameEnvironmentAnswer.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.env; + +public class NameEnvironmentAnswer { + + // only one of the three can be set + IBinaryType binaryType; + ICompilationUnit compilationUnit; + ISourceType[] sourceTypes; + + public NameEnvironmentAnswer(IBinaryType binaryType) { + this.binaryType = binaryType; + } + + public NameEnvironmentAnswer(ICompilationUnit compilationUnit) { + this.compilationUnit = compilationUnit; + } + + public NameEnvironmentAnswer(ISourceType[] sourceTypes) { + this.sourceTypes = sourceTypes; + } + + /** + * Answer the resolved binary form for the type or null if the + * receiver represents a compilation unit or source type. + */ + public IBinaryType getBinaryType() { + return binaryType; + } + + /** + * Answer the compilation unit or null if the + * receiver represents a binary or source type. + */ + public ICompilationUnit getCompilationUnit() { + return compilationUnit; + } + + /** + * Answer the unresolved source forms for the type or null if the + * receiver represents a compilation unit or binary type. + * + * Multiple source forms can be answered in case the originating compilation unit did contain + * several type at once. Then the first type is guaranteed to be the requested type. + */ + public ISourceType[] getSourceTypes() { + return sourceTypes; + } + + /** + * Answer whether the receiver contains the resolved binary form of the type. + */ + public boolean isBinaryType() { + return binaryType != null; + } + + /** + * Answer whether the receiver contains the compilation unit which defines the type. + */ + public boolean isCompilationUnit() { + return compilationUnit != null; + } + + /** + * Answer whether the receiver contains the unresolved source form of the type. + */ + public boolean isSourceType() { + return sourceTypes != null; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/ConditionalFlowInfo.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/ConditionalFlowInfo.java new file mode 100644 index 0000000..ceda218 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/ConditionalFlowInfo.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.flow; + +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; + +/** + * Record conditional initialization status during definite assignment analysis + * + */ +public class ConditionalFlowInfo extends FlowInfo { + + public FlowInfo initsWhenTrue; + public FlowInfo initsWhenFalse; + + ConditionalFlowInfo(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){ + + this.initsWhenTrue = initsWhenTrue; + this.initsWhenFalse = initsWhenFalse; + } + + public FlowInfo addInitializationsFrom(FlowInfo otherInits) { + + this.initsWhenTrue.addInitializationsFrom(otherInits); + this.initsWhenFalse.addInitializationsFrom(otherInits); + return this; + } + + public FlowInfo addPotentialInitializationsFrom(FlowInfo otherInits) { + + this.initsWhenTrue.addPotentialInitializationsFrom(otherInits); + this.initsWhenFalse.addPotentialInitializationsFrom(otherInits); + return this; + } + + public FlowInfo asNegatedCondition() { + + FlowInfo extra = initsWhenTrue; + initsWhenTrue = initsWhenFalse; + initsWhenFalse = extra; + return this; + } + + public FlowInfo copy() { + + return new ConditionalFlowInfo(initsWhenTrue.copy(), initsWhenFalse.copy()); + } + + public FlowInfo initsWhenFalse() { + + return initsWhenFalse; + } + + public FlowInfo initsWhenTrue() { + + return initsWhenTrue; + } + + /** + * Check status of definite assignment for a field. + */ + public boolean isDefinitelyAssigned(FieldBinding field) { + + return initsWhenTrue.isDefinitelyAssigned(field) + && initsWhenFalse.isDefinitelyAssigned(field); + } + + /** + * Check status of definite assignment for a local variable. + */ + public boolean isDefinitelyAssigned(LocalVariableBinding local) { + + return initsWhenTrue.isDefinitelyAssigned(local) + && initsWhenFalse.isDefinitelyAssigned(local); + } + + public int reachMode(){ + return unconditionalInits().reachMode(); + } + + public boolean isReachable(){ + + return unconditionalInits().isReachable(); + //should maybe directly be: false + } + + /** + * Check status of potential assignment for a field. + */ + public boolean isPotentiallyAssigned(FieldBinding field) { + + return initsWhenTrue.isPotentiallyAssigned(field) + || initsWhenFalse.isPotentiallyAssigned(field); + } + + /** + * Check status of potential assignment for a local variable. + */ + public boolean isPotentiallyAssigned(LocalVariableBinding local) { + + return initsWhenTrue.isPotentiallyAssigned(local) + || initsWhenFalse.isPotentiallyAssigned(local); + } + + /** + * Record a field got definitely assigned. + */ + public void markAsDefinitelyAssigned(FieldBinding field) { + + initsWhenTrue.markAsDefinitelyAssigned(field); + initsWhenFalse.markAsDefinitelyAssigned(field); + } + + /** + * Record a field got definitely assigned. + */ + public void markAsDefinitelyAssigned(LocalVariableBinding local) { + + initsWhenTrue.markAsDefinitelyAssigned(local); + initsWhenFalse.markAsDefinitelyAssigned(local); + } + + /** + * Clear the initialization info for a field + */ + public void markAsDefinitelyNotAssigned(FieldBinding field) { + + initsWhenTrue.markAsDefinitelyNotAssigned(field); + initsWhenFalse.markAsDefinitelyNotAssigned(field); + } + + /** + * Clear the initialization info for a local variable + */ + public void markAsDefinitelyNotAssigned(LocalVariableBinding local) { + + initsWhenTrue.markAsDefinitelyNotAssigned(local); + initsWhenFalse.markAsDefinitelyNotAssigned(local); + } + + public FlowInfo setReachMode(int reachMode) { + + initsWhenTrue.setReachMode(reachMode); + initsWhenFalse.setReachMode(reachMode); + return this; + } + + /** + * Converts conditional receiver into inconditional one, updated in the following way:
      + *
    • intersection of definitely assigned variables, + *
    • union of potentially assigned variables. + *
    + */ + public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) { + + return unconditionalInits().mergedWith(otherInits); + } + + public String toString() { + + return "FlowInfo"; //$NON-NLS-1$ //$NON-NLS-3$ //$NON-NLS-2$ + } + + public UnconditionalFlowInfo unconditionalInits() { + + return initsWhenTrue.unconditionalInits().copy() + .mergedWith(initsWhenFalse.unconditionalInits()); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/ExceptionHandlingFlowContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/ExceptionHandlingFlowContext.java new file mode 100644 index 0000000..d488c0e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/ExceptionHandlingFlowContext.java @@ -0,0 +1,197 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.flow; + +import java.util.ArrayList; + +import net.sourceforge.phpdt.internal.compiler.codegen.ObjectCache; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.Scope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; +import net.sourceforge.phpeclipse.internal.compiler.ast.TryStatement; + +/** + * Reflects the context of code analysis, keeping track of enclosing + * try statements, exception handlers, etc... + */ +public class ExceptionHandlingFlowContext extends FlowContext { + + public ReferenceBinding[] handledExceptions; + + public final static int BitCacheSize = 32; // 32 bits per int + int[] isReached; + int[] isNeeded; + UnconditionalFlowInfo[] initsOnExceptions; + ObjectCache indexes = new ObjectCache(); + boolean isMethodContext; + + public UnconditionalFlowInfo initsOnReturn; + + // for dealing with anonymous constructor thrown exceptions + public ArrayList extendedExceptions; + + public ExceptionHandlingFlowContext( + FlowContext parent, + AstNode associatedNode, + ReferenceBinding[] handledExceptions, + BlockScope scope, + UnconditionalFlowInfo flowInfo) { + + super(parent, associatedNode); + isMethodContext = scope == scope.methodScope(); + this.handledExceptions = handledExceptions; + int count = handledExceptions.length, cacheSize = (count / BitCacheSize) + 1; + this.isReached = new int[cacheSize]; // none is reached by default + this.isNeeded = new int[cacheSize]; // none is needed by default + this.initsOnExceptions = new UnconditionalFlowInfo[count]; + for (int i = 0; i < count; i++) { + this.indexes.put(handledExceptions[i], i); // key type -> value index + boolean isUnchecked = + (scope.compareUncheckedException(handledExceptions[i]) != NotRelated); + int cacheIndex = i / BitCacheSize, bitMask = 1 << (i % BitCacheSize); + if (isUnchecked) { + isReached[cacheIndex] |= bitMask; + this.initsOnExceptions[i] = flowInfo.copy().unconditionalInits(); + } else { + this.initsOnExceptions[i] = FlowInfo.DEAD_END; + } + } + System.arraycopy(this.isReached, 0, this.isNeeded, 0, cacheSize); + this.initsOnReturn = FlowInfo.DEAD_END; + } + + public void complainIfUnusedExceptionHandlers( + AstNode[] exceptionHandlers, + BlockScope scope, + TryStatement tryStatement) { + // report errors for unreachable exception handlers + for (int i = 0, count = handledExceptions.length; i < count; i++) { + int index = indexes.get(handledExceptions[i]); + int cacheIndex = index / BitCacheSize; + int bitMask = 1 << (index % BitCacheSize); + if ((isReached[cacheIndex] & bitMask) == 0) { + scope.problemReporter().unreachableExceptionHandler( + handledExceptions[index], + exceptionHandlers[index]); + } else { + if ((isNeeded[cacheIndex] & bitMask) == 0) { + scope.problemReporter().maskedExceptionHandler( + handledExceptions[index], + exceptionHandlers[index]); + } + } + } + // will optimized out unnecessary catch block during code gen + tryStatement.preserveExceptionHandler = isNeeded; + } + + public String individualToString() { + + StringBuffer buffer = new StringBuffer("Exception flow context"); //$NON-NLS-1$ + int length = handledExceptions.length; + for (int i = 0; i < length; i++) { + int cacheIndex = i / BitCacheSize; + int bitMask = 1 << (i % BitCacheSize); + buffer.append('[').append(handledExceptions[i].readableName()); + if ((isReached[cacheIndex] & bitMask) != 0) { + if ((isNeeded[cacheIndex] & bitMask) == 0) { + buffer.append("-masked"); //$NON-NLS-1$ + } else { + buffer.append("-reached"); //$NON-NLS-1$ + } + } else { + buffer.append("-not reached"); //$NON-NLS-1$ + } + buffer.append('-').append(initsOnExceptions[i].toString()).append(']'); + } + buffer.append("[initsOnReturn -").append(initsOnReturn.toString()).append(']'); //$NON-NLS-1$ + return buffer.toString(); + } + + public UnconditionalFlowInfo initsOnException(ReferenceBinding exceptionType) { + + int index; + if ((index = indexes.get(exceptionType)) < 0) { + return FlowInfo.DEAD_END; + } + return initsOnExceptions[index]; + } + + public UnconditionalFlowInfo initsOnReturn(){ + return this.initsOnReturn; + } + + public void recordHandlingException( + ReferenceBinding exceptionType, + UnconditionalFlowInfo flowInfo, + TypeBinding raisedException, + AstNode invocationSite, + boolean wasAlreadyDefinitelyCaught) { + + int index = indexes.get(exceptionType); + // if already flagged as being reached (unchecked exception handler) + int cacheIndex = index / BitCacheSize; + int bitMask = 1 << (index % BitCacheSize); + if (!wasAlreadyDefinitelyCaught) { + this.isNeeded[cacheIndex] |= bitMask; + } + this.isReached[cacheIndex] |= bitMask; + + initsOnExceptions[index] = + initsOnExceptions[index] == FlowInfo.DEAD_END + ? flowInfo.copy().unconditionalInits() + : initsOnExceptions[index].mergedWith(flowInfo); + } + + public void recordReturnFrom(FlowInfo flowInfo) { + + if (!flowInfo.isReachable()) return; + if (initsOnReturn == FlowInfo.DEAD_END) { + initsOnReturn = flowInfo.copy().unconditionalInits(); + } else { + initsOnReturn = initsOnReturn.mergedWith(flowInfo.unconditionalInits()); + } + } + + /* + * Compute a merged list of unhandled exception types (keeping only the most generic ones). + * This is necessary to add synthetic thrown exceptions for anonymous type constructors (JLS 8.6). + */ + public void mergeUnhandledException(TypeBinding newException){ + + if (this.extendedExceptions == null){ + this.extendedExceptions = new ArrayList(5); + for (int i = 0; i < this.handledExceptions.length; i++){ + this.extendedExceptions.add(this.handledExceptions[i]); + } + } + + boolean isRedundant = false; + + for(int i = this.extendedExceptions.size()-1; i >= 0; i--){ + switch(Scope.compareTypes(newException, (TypeBinding)this.extendedExceptions.get(i))){ + case MoreGeneric : + this.extendedExceptions.remove(i); + break; + case EqualOrMoreSpecific : + isRedundant = true; + break; + case NotRelated : + break; + } + } + if (!isRedundant){ + this.extendedExceptions.add(newException); + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/FinallyFlowContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/FinallyFlowContext.java new file mode 100644 index 0000000..972d228 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/FinallyFlowContext.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.flow; + +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding; +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; +import net.sourceforge.phpeclipse.internal.compiler.ast.Reference; + +/** + * Reflects the context of code analysis, keeping track of enclosing + * try statements, exception handlers, etc... + */ +public class FinallyFlowContext extends FlowContext { + + Reference finalAssignments[]; + VariableBinding finalVariables[]; + int assignCount; + + public FinallyFlowContext(FlowContext parent, AstNode associatedNode) { + super(parent, associatedNode); + } + + /** + * Given some contextual initialization info (derived from a try block or a catch block), this + * code will check that the subroutine context does not also initialize a final variable potentially set + * redundantly. + */ + public void complainOnRedundantFinalAssignments( + FlowInfo flowInfo, + BlockScope scope) { + for (int i = 0; i < assignCount; i++) { + VariableBinding variable = finalVariables[i]; + if (variable == null) continue; + + boolean complained = false; // remember if have complained on this final assignment + if (variable instanceof FieldBinding) { + // final field + if (flowInfo.isPotentiallyAssigned((FieldBinding)variable)) { + complained = true; + scope.problemReporter().duplicateInitializationOfBlankFinalField((FieldBinding)variable, finalAssignments[i]); + } + } else { + // final local variable + if (flowInfo.isPotentiallyAssigned((LocalVariableBinding) variable)) { + complained = true; + scope.problemReporter().duplicateInitializationOfFinalLocal( + (LocalVariableBinding) variable, + finalAssignments[i]); + } + } + // any reference reported at this level is removed from the parent context + // where it could also be reported again + if (complained) { + FlowContext currentContext = parent; + while (currentContext != null) { + //if (currentContext.isSubRoutine()) { + currentContext.removeFinalAssignmentIfAny(finalAssignments[i]); + //} + currentContext = currentContext.parent; + } + } + } + } + + public String individualToString() { + + StringBuffer buffer = new StringBuffer("Finally flow context"); //$NON-NLS-1$ + buffer.append("[finalAssignments count -").append(assignCount).append(']'); //$NON-NLS-1$ + return buffer.toString(); + } + + public boolean isSubRoutine() { + return true; + } + + boolean recordFinalAssignment( + VariableBinding binding, + Reference finalAssignment) { + if (assignCount == 0) { + finalAssignments = new Reference[5]; + finalVariables = new VariableBinding[5]; + } else { + if (assignCount == finalAssignments.length) + System.arraycopy( + finalAssignments, + 0, + (finalAssignments = new Reference[assignCount * 2]), + 0, + assignCount); + System.arraycopy( + finalVariables, + 0, + (finalVariables = new VariableBinding[assignCount * 2]), + 0, + assignCount); + }; + finalAssignments[assignCount] = finalAssignment; + finalVariables[assignCount++] = binding; + return true; + } + + void removeFinalAssignmentIfAny(Reference reference) { + for (int i = 0; i < assignCount; i++) { + if (finalAssignments[i] == reference) { + finalAssignments[i] = null; + finalVariables[i] = null; + return; + } + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/FlowContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/FlowContext.java new file mode 100644 index 0000000..360ffea --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/FlowContext.java @@ -0,0 +1,490 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.flow; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.Scope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants; +import net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding; +import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; +import net.sourceforge.phpeclipse.internal.compiler.ast.Reference; +import net.sourceforge.phpeclipse.internal.compiler.ast.TryStatement; + +/** + * Reflects the context of code analysis, keeping track of enclosing + * try statements, exception handlers, etc... + */ +public class FlowContext implements TypeConstants { + + public AstNode associatedNode; + public FlowContext parent; + + public final static FlowContext NotContinuableContext = new FlowContext(null, null); + + public FlowContext(FlowContext parent, AstNode associatedNode) { + + this.parent = parent; + this.associatedNode = associatedNode; + } + + public Label breakLabel() { + + return null; + } + + public void checkExceptionHandlers( + TypeBinding[] raisedExceptions, + AstNode location, + FlowInfo flowInfo, + BlockScope scope) { + + // check that all the argument exception types are handled + // JDK Compatible implementation - when an exception type is thrown, + // all related catch blocks are marked as reachable... instead of those only + // until the point where it is safely handled (Smarter - see comment at the end) + int remainingCount; // counting the number of remaining unhandled exceptions + int raisedCount; // total number of exceptions raised + if ((raisedExceptions == null) + || ((raisedCount = raisedExceptions.length) == 0)) + return; + remainingCount = raisedCount; + + // duplicate the array of raised exceptions since it will be updated + // (null replaces any handled exception) + System.arraycopy( + raisedExceptions, + 0, + (raisedExceptions = new TypeBinding[raisedCount]), + 0, + raisedCount); + FlowContext traversedContext = this; + + while (traversedContext != null) { + AstNode sub; + if (((sub = traversedContext.subRoutine()) != null) && sub.cannotReturn()) { + // traversing a non-returning subroutine means that all unhandled + // exceptions will actually never get sent... + return; + } + // filter exceptions that are locally caught from the innermost enclosing + // try statement to the outermost ones. + if (traversedContext instanceof ExceptionHandlingFlowContext) { + ExceptionHandlingFlowContext exceptionContext = + (ExceptionHandlingFlowContext) traversedContext; + ReferenceBinding[] caughtExceptions; + if ((caughtExceptions = exceptionContext.handledExceptions) != NoExceptions) { + int caughtCount = caughtExceptions.length; + boolean[] locallyCaught = new boolean[raisedCount]; // at most + + for (int caughtIndex = 0; caughtIndex < caughtCount; caughtIndex++) { + ReferenceBinding caughtException = caughtExceptions[caughtIndex]; + for (int raisedIndex = 0; raisedIndex < raisedCount; raisedIndex++) { + TypeBinding raisedException; + if ((raisedException = raisedExceptions[raisedIndex]) != null) { + switch (Scope.compareTypes(raisedException, caughtException)) { + case EqualOrMoreSpecific : + exceptionContext.recordHandlingException( + caughtException, + flowInfo.unconditionalInits(), + raisedException, + location, + locallyCaught[raisedIndex]); + // was already definitely caught ? + if (!locallyCaught[raisedIndex]) { + locallyCaught[raisedIndex] = true; + // remember that this exception has been definitely caught + remainingCount--; + } + break; + case MoreGeneric : + exceptionContext.recordHandlingException( + caughtException, + flowInfo.unconditionalInits(), + raisedException, + location, + false); + // was not caught already per construction + } + } + } + } + // remove locally caught exceptions from the remaining ones + for (int i = 0; i < raisedCount; i++) { + if (locallyCaught[i]) { + raisedExceptions[i] = null; // removed from the remaining ones. + } + } + } + // method treatment for unchecked exceptions + if (exceptionContext.isMethodContext) { + for (int i = 0; i < raisedCount; i++) { + TypeBinding raisedException; + if ((raisedException = raisedExceptions[i]) != null) { + if (raisedException.isCompatibleWith(scope.getJavaLangRuntimeException()) + || raisedException.isCompatibleWith(scope.getJavaLangError())) { + remainingCount--; + raisedExceptions[i] = null; + } + } + } + // anonymous constructors are allowed to throw any exceptions (their thrown exceptions + // clause will be fixed up later as per JLS 8.6). + if (exceptionContext.associatedNode instanceof AbstractMethodDeclaration){ + AbstractMethodDeclaration method = (AbstractMethodDeclaration)exceptionContext.associatedNode; + if (method.isConstructor() && method.binding.declaringClass.isAnonymousType()){ + + for (int i = 0; i < raisedCount; i++) { + TypeBinding raisedException; + if ((raisedException = raisedExceptions[i]) != null) { + exceptionContext.mergeUnhandledException(raisedException); + } + } + return; // no need to complain, will fix up constructor exceptions + } + } + break; // not handled anywhere, thus jump to error handling + } + } + if (remainingCount == 0) + return; + + traversedContext.recordReturnFrom(flowInfo.unconditionalInits()); + if (traversedContext.associatedNode instanceof TryStatement){ + flowInfo = flowInfo.copy().addInitializationsFrom(((TryStatement) traversedContext.associatedNode).subRoutineInits); + } + traversedContext = traversedContext.parent; + } + // if reaches this point, then there are some remaining unhandled exception types. + nextReport: for (int i = 0; i < raisedCount; i++) { + TypeBinding exception; + if ((exception = raisedExceptions[i]) != null) { + // only one complaint if same exception declared to be thrown more than once + for (int j = 0; j < i; j++) { + if (raisedExceptions[j] == exception) continue nextReport; // already reported + } + scope.problemReporter().unhandledException(exception, location); + } + } + } + + public void checkExceptionHandlers( + TypeBinding raisedException, + AstNode location, + FlowInfo flowInfo, + BlockScope scope) { + + // LIGHT-VERSION OF THE EQUIVALENT WITH AN ARRAY OF EXCEPTIONS + // check that all the argument exception types are handled + // JDK Compatible implementation - when an exception type is thrown, + // all related catch blocks are marked as reachable... instead of those only + // until the point where it is safely handled (Smarter - see comment at the end) + FlowContext traversedContext = this; + while (traversedContext != null) { + AstNode sub; + if (((sub = traversedContext.subRoutine()) != null) && sub.cannotReturn()) { + // traversing a non-returning subroutine means that all unhandled + // exceptions will actually never get sent... + return; + } + + // filter exceptions that are locally caught from the innermost enclosing + // try statement to the outermost ones. + if (traversedContext instanceof ExceptionHandlingFlowContext) { + ExceptionHandlingFlowContext exceptionContext = + (ExceptionHandlingFlowContext) traversedContext; + ReferenceBinding[] caughtExceptions; + if ((caughtExceptions = exceptionContext.handledExceptions) != NoExceptions) { + boolean definitelyCaught = false; + for (int caughtIndex = 0, caughtCount = caughtExceptions.length; + caughtIndex < caughtCount; + caughtIndex++) { + ReferenceBinding caughtException = caughtExceptions[caughtIndex]; + switch (Scope.compareTypes(raisedException, caughtException)) { + case EqualOrMoreSpecific : + exceptionContext.recordHandlingException( + caughtException, + flowInfo.unconditionalInits(), + raisedException, + location, + definitelyCaught); + // was it already definitely caught ? + definitelyCaught = true; + break; + case MoreGeneric : + exceptionContext.recordHandlingException( + caughtException, + flowInfo.unconditionalInits(), + raisedException, + location, + false); + // was not caught already per construction + } + } + if (definitelyCaught) + return; + } + // method treatment for unchecked exceptions + if (exceptionContext.isMethodContext) { + if (raisedException.isCompatibleWith(scope.getJavaLangRuntimeException()) + || raisedException.isCompatibleWith(scope.getJavaLangError())) + return; + + // anonymous constructors are allowed to throw any exceptions (their thrown exceptions + // clause will be fixed up later as per JLS 8.6). + if (exceptionContext.associatedNode instanceof AbstractMethodDeclaration){ + AbstractMethodDeclaration method = (AbstractMethodDeclaration)exceptionContext.associatedNode; + if (method.isConstructor() && method.binding.declaringClass.isAnonymousType()){ + + exceptionContext.mergeUnhandledException(raisedException); + return; // no need to complain, will fix up constructor exceptions + } + } + break; // not handled anywhere, thus jump to error handling + } + } + + traversedContext.recordReturnFrom(flowInfo.unconditionalInits()); + if (traversedContext.associatedNode instanceof TryStatement){ + flowInfo = flowInfo.copy().addInitializationsFrom(((TryStatement) traversedContext.associatedNode).subRoutineInits); + } + traversedContext = traversedContext.parent; + } + // if reaches this point, then there are some remaining unhandled exception types. + scope.problemReporter().unhandledException(raisedException, location); + } + + public Label continueLabel() { + + return null; + } + + /* + * lookup through break labels + */ + public FlowContext getTargetContextForBreakLabel(char[] labelName) { + + FlowContext current = this, lastNonReturningSubRoutine = null; + while (current != null) { + if (current.isNonReturningContext()) { + lastNonReturningSubRoutine = current; + } + char[] currentLabelName; + if (((currentLabelName = current.labelName()) != null) + && CharOperation.equals(currentLabelName, labelName)) { + if (lastNonReturningSubRoutine == null) { + return current; + } else { + return lastNonReturningSubRoutine; + } + } + current = current.parent; + } + // not found + return null; + } + + /* + * lookup through continue labels + */ + public FlowContext getTargetContextForContinueLabel(char[] labelName) { + + FlowContext current = this; + FlowContext lastContinuable = null; + FlowContext lastNonReturningSubRoutine = null; + + while (current != null) { + if (current.isNonReturningContext()) { + lastNonReturningSubRoutine = current; + } else { + if (current.isContinuable()) { + lastContinuable = current; + } + } + + char[] currentLabelName; + if ((currentLabelName = current.labelName()) != null && CharOperation.equals(currentLabelName, labelName)) { + + // matching label found + if ((lastContinuable != null) + && (current.associatedNode.concreteStatement() == lastContinuable.associatedNode)) { + + if (lastNonReturningSubRoutine == null) { + return lastContinuable; + } else { + return lastNonReturningSubRoutine; + } + } else { + // label is found, but not a continuable location + return NotContinuableContext; + } + } + current = current.parent; + } + // not found + return null; + } + + /* + * lookup a default break through breakable locations + */ + public FlowContext getTargetContextForDefaultBreak() { + + FlowContext current = this, lastNonReturningSubRoutine = null; + while (current != null) { + if (current.isNonReturningContext()) { + lastNonReturningSubRoutine = current; + } + if (current.isBreakable() && current.labelName() == null) { + if (lastNonReturningSubRoutine == null) { + return current; + } else { + return lastNonReturningSubRoutine; + } + } + current = current.parent; + } + // not found + return null; + } + + /* + * lookup a default continue amongst continuable locations + */ + public FlowContext getTargetContextForDefaultContinue() { + + FlowContext current = this, lastNonReturningSubRoutine = null; + while (current != null) { + if (current.isNonReturningContext()) { + lastNonReturningSubRoutine = current; + } + if (current.isContinuable()) { + if (lastNonReturningSubRoutine == null) { + return current; + } else { + return lastNonReturningSubRoutine; + } + } + current = current.parent; + } + // not found + return null; + } + + public String individualToString() { + + return "Flow context"; //$NON-NLS-1$ + } + + public FlowInfo initsOnBreak() { + + return FlowInfo.DEAD_END; + } + + public UnconditionalFlowInfo initsOnReturn() { + + return FlowInfo.DEAD_END; + } + + public boolean isBreakable() { + + return false; + } + + public boolean isContinuable() { + + return false; + } + + public boolean isNonReturningContext() { + + return false; + } + + public boolean isSubRoutine() { + + return false; + } + + public char[] labelName() { + + return null; + } + + public void recordBreakFrom(FlowInfo flowInfo) { + } + + public void recordContinueFrom(FlowInfo flowInfo) { + } + + boolean recordFinalAssignment( + VariableBinding variable, + Reference finalReference) { + + return true; // keep going + } + + public void recordReturnFrom(FlowInfo flowInfo) { + } + + public void recordSettingFinal( + VariableBinding variable, + Reference finalReference) { + + // for initialization inside looping statement that effectively loops + FlowContext context = this; + while (context != null) { + if (!context.recordFinalAssignment(variable, finalReference)) { + break; // no need to keep going + } + context = context.parent; + } + } + + void removeFinalAssignmentIfAny(Reference reference) { + } + + public AstNode subRoutine() { + + return null; + } + + public String toString() { + + StringBuffer buffer = new StringBuffer(); + FlowContext current = this; + int parentsCount = 0; + while ((current = current.parent) != null) { + parentsCount++; + } + FlowContext[] parents = new FlowContext[parentsCount + 1]; + current = this; + int index = parentsCount; + while (index >= 0) { + parents[index--] = current; + current = current.parent; + } + for (int i = 0; i < parentsCount; i++) { + for (int j = 0; j < i; j++) + buffer.append('\t'); + buffer.append(parents[i].individualToString()).append('\n'); + } + buffer.append('*'); + for (int j = 0; j < parentsCount + 1; j++) + buffer.append('\t'); + buffer.append(individualToString()).append('\n'); + return buffer.toString(); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/FlowInfo.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/FlowInfo.java new file mode 100644 index 0000000..8226796 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/FlowInfo.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.flow; + +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpeclipse.internal.compiler.ast.Statement; + +public abstract class FlowInfo { + + public final static int REACHABLE = 0; + public final static int UNREACHABLE = 1; + + public static final UnconditionalFlowInfo DEAD_END; // Represents a dead branch status of initialization + static { + DEAD_END = new UnconditionalFlowInfo(); + DEAD_END.reachMode = UNREACHABLE; + } + abstract public FlowInfo addInitializationsFrom(FlowInfo otherInits); + + abstract public FlowInfo addPotentialInitializationsFrom(FlowInfo otherInits); + + public FlowInfo asNegatedCondition() { + + return this; + } + + public boolean complainIfUnreachable(Statement statement, BlockScope scope, boolean didAlreadyComplain) { + + // Report an error if necessary + return false; + } + + public static FlowInfo conditional(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){ + + // if (initsWhenTrue.equals(initsWhenFalse)) return initsWhenTrue; -- could optimize if #equals is defined + return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse); + } + + abstract public FlowInfo copy(); + + public static UnconditionalFlowInfo initial(int maxFieldCount) { + UnconditionalFlowInfo info = new UnconditionalFlowInfo(); + info.maxFieldCount = maxFieldCount; + return info; + } + + abstract public FlowInfo initsWhenFalse(); + + abstract public FlowInfo initsWhenTrue(); + + /** + * Check status of definite assignment for a field. + */ + abstract public boolean isDefinitelyAssigned(FieldBinding field); + + /** + * Check status of definite assignment for a local. + */ + public abstract boolean isDefinitelyAssigned(LocalVariableBinding local); + + //abstract public int reachMode(); + + /** + * Check status of potential assignment for a field. + */ + abstract public boolean isPotentiallyAssigned(FieldBinding field); + + /** + * Check status of potential assignment for a local variable. + */ + + abstract public boolean isPotentiallyAssigned(LocalVariableBinding field); + + abstract public boolean isReachable(); + + /** + * Record a field got definitely assigned. + */ + abstract public void markAsDefinitelyAssigned(FieldBinding field); + + /** + * Record a local got definitely assigned. + */ + abstract public void markAsDefinitelyAssigned(LocalVariableBinding local); + + /** + * Clear the initialization info for a field + */ + abstract public void markAsDefinitelyNotAssigned(FieldBinding field); + + /** + * Clear the initialization info for a local variable + */ + abstract public void markAsDefinitelyNotAssigned(LocalVariableBinding local); + + abstract public int reachMode(); + + abstract public FlowInfo setReachMode(int reachMode); + + /** + * Returns the receiver updated in the following way:
      + *
    • intersection of definitely assigned variables, + *
    • union of potentially assigned variables. + *
    + */ + abstract public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits); + + public String toString(){ + + if (this == DEAD_END){ + return "FlowInfo.DEAD_END"; //$NON-NLS-1$ + } + return super.toString(); + } + + abstract public UnconditionalFlowInfo unconditionalInits(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/InitializationFlowContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/InitializationFlowContext.java new file mode 100644 index 0000000..83cb333 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/InitializationFlowContext.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.flow; + +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; + +/** + * Reflects the context of code analysis, keeping track of enclosing + * try statements, exception handlers, etc... + */ +public class InitializationFlowContext extends ExceptionHandlingFlowContext { + + public int exceptionCount; + public TypeBinding[] thrownExceptions = new TypeBinding[5]; + public AstNode[] exceptionThrowers = new AstNode[5]; + public FlowInfo[] exceptionThrowerFlowInfos = new FlowInfo[5]; + + public InitializationFlowContext( + FlowContext parent, + AstNode associatedNode, + BlockScope scope) { + super( + parent, + associatedNode, + NoExceptions, // no exception allowed by default + scope, + FlowInfo.DEAD_END); + } + + public void checkInitializerExceptions( + BlockScope currentScope, + FlowContext initializerContext, + FlowInfo flowInfo) { + for (int i = 0; i < exceptionCount; i++) { + initializerContext.checkExceptionHandlers( + thrownExceptions[i], + exceptionThrowers[i], + exceptionThrowerFlowInfos[i], + currentScope); + } + } + + public String individualToString() { + + StringBuffer buffer = new StringBuffer("Initialization flow context"); //$NON-NLS-1$ + for (int i = 0; i < exceptionCount; i++) { + buffer.append('[').append(thrownExceptions[i].readableName()); + buffer.append('-').append(exceptionThrowerFlowInfos[i].toString()).append(']'); + } + return buffer.toString(); + } + + public void recordHandlingException( + ReferenceBinding exceptionType, + UnconditionalFlowInfo flowInfo, + TypeBinding raisedException, + AstNode invocationSite, + boolean wasMasked) { + + // even if unreachable code, need to perform unhandled exception diagnosis + int size = thrownExceptions.length; + if (exceptionCount == size) { + System.arraycopy( + thrownExceptions, + 0, + (thrownExceptions = new TypeBinding[size * 2]), + 0, + size); + System.arraycopy( + exceptionThrowers, + 0, + (exceptionThrowers = new AstNode[size * 2]), + 0, + size); + System.arraycopy( + exceptionThrowerFlowInfos, + 0, + (exceptionThrowerFlowInfos = new FlowInfo[size * 2]), + 0, + size); + } + thrownExceptions[exceptionCount] = raisedException; + exceptionThrowers[exceptionCount] = invocationSite; + exceptionThrowerFlowInfos[exceptionCount++] = flowInfo.copy(); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/InsideSubRoutineFlowContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/InsideSubRoutineFlowContext.java new file mode 100644 index 0000000..13af45c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/InsideSubRoutineFlowContext.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.flow; + +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; + +/** + * Reflects the context of code analysis, keeping track of enclosing + * try statements, exception handlers, etc... + */ +public class InsideSubRoutineFlowContext extends FlowContext { + + public UnconditionalFlowInfo initsOnReturn; + + public InsideSubRoutineFlowContext( + FlowContext parent, + AstNode associatedNode) { + super(parent, associatedNode); + this.initsOnReturn = FlowInfo.DEAD_END; + } + + public String individualToString() { + + StringBuffer buffer = new StringBuffer("Inside SubRoutine flow context"); //$NON-NLS-1$ + buffer.append("[initsOnReturn -").append(initsOnReturn.toString()).append(']'); //$NON-NLS-1$ + return buffer.toString(); + } + + public UnconditionalFlowInfo initsOnReturn(){ + return this.initsOnReturn; + } + + public boolean isNonReturningContext() { + return associatedNode.cannotReturn(); + } + + public AstNode subRoutine() { + return associatedNode; + } + + public void recordReturnFrom(FlowInfo flowInfo) { + + if (!flowInfo.isReachable()) return; + if (initsOnReturn == FlowInfo.DEAD_END) { + initsOnReturn = flowInfo.copy().unconditionalInits(); + } else { + initsOnReturn = initsOnReturn.mergedWith(flowInfo.unconditionalInits()); + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/LabelFlowContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/LabelFlowContext.java new file mode 100644 index 0000000..7192673 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/LabelFlowContext.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.flow; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; + +/** + * Reflects the context of code analysis, keeping track of enclosing + * try statements, exception handlers, etc... + */ +public class LabelFlowContext extends SwitchFlowContext { + + public char[] labelName; + + public LabelFlowContext( + FlowContext parent, + AstNode associatedNode, + char[] labelName, + Label breakLabel, + BlockScope scope) { + + super(parent, associatedNode, breakLabel); + this.labelName = labelName; + checkLabelValidity(scope); + } + + void checkLabelValidity(BlockScope scope) { + + // check if label was already defined above + FlowContext current = parent; + while (current != null) { + char[] currentLabelName; + if (((currentLabelName = current.labelName()) != null) + && CharOperation.equals(currentLabelName, labelName)) { + scope.problemReporter().alreadyDefinedLabel(labelName, associatedNode); + } + current = current.parent; + } + } + + public String individualToString() { + + return "Label flow context [label:" + String.valueOf(labelName) + "]"; //$NON-NLS-2$ //$NON-NLS-1$ + } + + public char[] labelName() { + + return labelName; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/LoopingFlowContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/LoopingFlowContext.java new file mode 100644 index 0000000..56556e8 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/LoopingFlowContext.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.flow; + +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.Scope; +import net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding; +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; +import net.sourceforge.phpeclipse.internal.compiler.ast.Reference; + +/** + * Reflects the context of code analysis, keeping track of enclosing + * try statements, exception handlers, etc... + */ +public class LoopingFlowContext extends SwitchFlowContext { + + public Label continueLabel; + public UnconditionalFlowInfo initsOnContinue = FlowInfo.DEAD_END; + Reference finalAssignments[]; + VariableBinding finalVariables[]; + int assignCount = 0; + Scope associatedScope; + + public LoopingFlowContext( + FlowContext parent, + AstNode associatedNode, + Label breakLabel, + Label continueLabel, + Scope associatedScope) { + super(parent, associatedNode, breakLabel); + this.continueLabel = continueLabel; + this.associatedScope = associatedScope; + } + + public void complainOnFinalAssignmentsInLoop( + BlockScope scope, + FlowInfo flowInfo) { + for (int i = 0; i < assignCount; i++) { + VariableBinding variable = finalVariables[i]; + if (variable == null) continue; + boolean complained = false; // remember if have complained on this final assignment + if (variable instanceof FieldBinding) { + if (flowInfo.isPotentiallyAssigned((FieldBinding) variable)) { + complained = true; + scope.problemReporter().duplicateInitializationOfBlankFinalField( + (FieldBinding) variable, + finalAssignments[i]); + } + } else { + if (flowInfo.isPotentiallyAssigned((LocalVariableBinding) variable)) { + complained = true; + scope.problemReporter().duplicateInitializationOfFinalLocal( + (LocalVariableBinding) variable, + finalAssignments[i]); + } + } + // any reference reported at this level is removed from the parent context where it + // could also be reported again + if (complained) { + FlowContext context = parent; + while (context != null) { + context.removeFinalAssignmentIfAny(finalAssignments[i]); + context = context.parent; + } + } + } + } + + public Label continueLabel() { + return continueLabel; + } + + public String individualToString() { + StringBuffer buffer = new StringBuffer("Looping flow context"); //$NON-NLS-1$ + buffer.append("[initsOnBreak -").append(initsOnBreak.toString()).append(']'); //$NON-NLS-1$ + buffer.append("[initsOnContinue -").append(initsOnContinue.toString()).append(']'); //$NON-NLS-1$ + return buffer.toString(); + } + + public boolean isContinuable() { + return true; + } + + public boolean isContinuedTo() { + return initsOnContinue != FlowInfo.DEAD_END; + } + + public void recordContinueFrom(FlowInfo flowInfo) { + + if (!flowInfo.isReachable()) return; + if (initsOnContinue == FlowInfo.DEAD_END) { + initsOnContinue = flowInfo.copy().unconditionalInits(); + } else { + initsOnContinue = initsOnContinue.mergedWith(flowInfo.unconditionalInits()); + }; + } + + boolean recordFinalAssignment( + VariableBinding binding, + Reference finalAssignment) { + // do not consider variables which are defined inside this loop + if (binding instanceof LocalVariableBinding) { + Scope scope = ((LocalVariableBinding) binding).declaringScope; + while ((scope = scope.parent) != null) { + if (scope == associatedScope) + return false; + } + } + if (assignCount == 0) { + finalAssignments = new Reference[5]; + finalVariables = new VariableBinding[5]; + } else { + if (assignCount == finalAssignments.length) + System.arraycopy( + finalAssignments, + 0, + (finalAssignments = new Reference[assignCount * 2]), + 0, + assignCount); + System.arraycopy( + finalVariables, + 0, + (finalVariables = new VariableBinding[assignCount * 2]), + 0, + assignCount); + }; + finalAssignments[assignCount] = finalAssignment; + finalVariables[assignCount++] = binding; + return true; + } + + void removeFinalAssignmentIfAny(Reference reference) { + for (int i = 0; i < assignCount; i++) { + if (finalAssignments[i] == reference) { + finalAssignments[i] = null; + finalVariables[i] = null; + return; + } + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/SwitchFlowContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/SwitchFlowContext.java new file mode 100644 index 0000000..dc4f1e5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/SwitchFlowContext.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.flow; + +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; + +/** + * Reflects the context of code analysis, keeping track of enclosing + * try statements, exception handlers, etc... + */ +public class SwitchFlowContext extends FlowContext { + public Label breakLabel; + public UnconditionalFlowInfo initsOnBreak = FlowInfo.DEAD_END; + + public SwitchFlowContext( + FlowContext parent, + AstNode associatedNode, + Label breakLabel) { + super(parent, associatedNode); + this.breakLabel = breakLabel; + } + + public Label breakLabel() { + return breakLabel; + } + + public String individualToString() { + StringBuffer buffer = new StringBuffer("Switch flow context"); //$NON-NLS-1$ + buffer.append("[initsOnBreak -").append(initsOnBreak.toString()).append(']'); //$NON-NLS-1$ + return buffer.toString(); + } + + public boolean isBreakable() { + return true; + } + + public void recordBreakFrom(FlowInfo flowInfo) { + + if (initsOnBreak == FlowInfo.DEAD_END) { + initsOnBreak = flowInfo.copy().unconditionalInits(); + } else { + initsOnBreak = initsOnBreak.mergedWith(flowInfo.unconditionalInits()); + }; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/UnconditionalFlowInfo.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/UnconditionalFlowInfo.java new file mode 100644 index 0000000..3740e12 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/UnconditionalFlowInfo.java @@ -0,0 +1,577 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.flow; + +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; +import net.sourceforge.phpeclipse.internal.compiler.ast.Statement; + +/** + * Record initialization status during definite assignment analysis + * + * No caching of pre-allocated instances. + */ +public class UnconditionalFlowInfo extends FlowInfo { + + + public long definiteInits; + public long potentialInits; + public long extraDefiniteInits[]; + public long extraPotentialInits[]; + + public int reachMode = REACHABLE; // by default + + public int maxFieldCount; + + // Constants + public static final int BitCacheSize = 64; // 64 bits in a long. + + UnconditionalFlowInfo() { + } + + // unions of both sets of initialization - used for try/finally + public FlowInfo addInitializationsFrom(FlowInfo inits) { + + if (this == DEAD_END) + return this; + + UnconditionalFlowInfo otherInits = inits.unconditionalInits(); + if (otherInits == DEAD_END) + return this; + + // union of definitely assigned variables, + definiteInits |= otherInits.definiteInits; + // union of potentially set ones + potentialInits |= otherInits.potentialInits; + + // treating extra storage + if (extraDefiniteInits != null) { + if (otherInits.extraDefiniteInits != null) { + // both sides have extra storage + int i = 0, length, otherLength; + if ((length = extraDefiniteInits.length) < (otherLength = otherInits.extraDefiniteInits.length)) { + // current storage is shorter -> grow current (could maybe reuse otherInits extra storage?) + System.arraycopy(extraDefiniteInits, 0, (extraDefiniteInits = new long[otherLength]), 0, length); + System.arraycopy(extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, length); + while (i < length) { + extraDefiniteInits[i] |= otherInits.extraDefiniteInits[i]; + extraPotentialInits[i] |= otherInits.extraPotentialInits[i++]; + } + while (i < otherLength) { + extraPotentialInits[i] = otherInits.extraPotentialInits[i++]; + } + } else { + // current storage is longer + while (i < otherLength) { + extraDefiniteInits[i] |= otherInits.extraDefiniteInits[i]; + extraPotentialInits[i] |= otherInits.extraPotentialInits[i++]; + } + while (i < length) + extraDefiniteInits[i++] = 0; + } + } else { + // no extra storage on otherInits + } + } else + if (otherInits.extraDefiniteInits != null) { + // no storage here, but other has extra storage. + int otherLength; + System.arraycopy(otherInits.extraDefiniteInits, 0, (extraDefiniteInits = new long[otherLength = otherInits.extraDefiniteInits.length]), 0, otherLength); + System.arraycopy(otherInits.extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, otherLength); + } + return this; + } + + // unions of both sets of initialization - used for try/finally + public FlowInfo addPotentialInitializationsFrom(FlowInfo inits) { + + if (this == DEAD_END){ + return this; + } + + UnconditionalFlowInfo otherInits = inits.unconditionalInits(); + if (otherInits == DEAD_END){ + return this; + } + // union of potentially set ones + potentialInits |= otherInits.potentialInits; + + // treating extra storage + if (extraDefiniteInits != null) { + if (otherInits.extraDefiniteInits != null) { + // both sides have extra storage + int i = 0, length, otherLength; + if ((length = extraDefiniteInits.length) < (otherLength = otherInits.extraDefiniteInits.length)) { + // current storage is shorter -> grow current (could maybe reuse otherInits extra storage?) + System.arraycopy(extraDefiniteInits, 0, (extraDefiniteInits = new long[otherLength]), 0, length); + System.arraycopy(extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, length); + while (i < length) { + extraPotentialInits[i] |= otherInits.extraPotentialInits[i++]; + } + while (i < otherLength) { + extraPotentialInits[i] = otherInits.extraPotentialInits[i++]; + } + } else { + // current storage is longer + while (i < otherLength) { + extraPotentialInits[i] |= otherInits.extraPotentialInits[i++]; + } + } + } + } else + if (otherInits.extraDefiniteInits != null) { + // no storage here, but other has extra storage. + int otherLength; + extraDefiniteInits = new long[otherLength = otherInits.extraDefiniteInits.length]; + System.arraycopy(otherInits.extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, otherLength); + } + return this; + } + + // Report an error if necessary + public boolean complainIfUnreachable(Statement statement, BlockScope scope, boolean didAlreadyComplain) { + + if ((this.reachMode & UNREACHABLE) != 0) { + statement.bits &= ~AstNode.IsReachableMASK; + boolean reported = this == DEAD_END; + if (!didAlreadyComplain && reported) { + scope.problemReporter().unreachableCode(statement); + } + return reported; // keep going for fake reachable + } + return false; + } + + /** + * Answers a copy of the current instance + */ + public FlowInfo copy() { + + // do not clone the DeadEnd + if (this == DEAD_END) + return this; + + // look for an unused preallocated object + UnconditionalFlowInfo copy = new UnconditionalFlowInfo(); + + // copy slots + copy.definiteInits = this.definiteInits; + copy.potentialInits = this.potentialInits; + copy.reachMode = this.reachMode; + copy.maxFieldCount = this.maxFieldCount; + + if (this.extraDefiniteInits != null) { + int length; + System.arraycopy(this.extraDefiniteInits, 0, (copy.extraDefiniteInits = new long[ (length = extraDefiniteInits.length)]), 0, length); + System.arraycopy(this.extraPotentialInits, 0, (copy.extraPotentialInits = new long[length]), 0, length); + }; + return copy; + } + + public UnconditionalFlowInfo discardFieldInitializations(){ + + int limit = this.maxFieldCount; + + if (limit < BitCacheSize) { + long mask = (1L << limit)-1; + this.definiteInits &= ~mask; + this.potentialInits &= ~mask; + return this; + } + + this.definiteInits = 0; + this.potentialInits = 0; + + // use extra vector + if (extraDefiniteInits == null) { + return this; // if vector not yet allocated, then not initialized + } + int vectorIndex, length = this.extraDefiniteInits.length; + if ((vectorIndex = (limit / BitCacheSize) - 1) >= length) { + return this; // not enough room yet + } + for (int i = 0; i < vectorIndex; i++) { + this.extraDefiniteInits[i] = 0L; + this.extraPotentialInits[i] = 0L; + } + long mask = (1L << (limit % BitCacheSize))-1; + this.extraDefiniteInits[vectorIndex] &= ~mask; + this.extraPotentialInits[vectorIndex] &= ~mask; + return this; + } + + public UnconditionalFlowInfo discardNonFieldInitializations(){ + + int limit = this.maxFieldCount; + + if (limit < BitCacheSize) { + long mask = (1L << limit)-1; + this.definiteInits &= mask; + this.potentialInits &= mask; + return this; + } + // use extra vector + if (extraDefiniteInits == null) { + return this; // if vector not yet allocated, then not initialized + } + int vectorIndex, length = this.extraDefiniteInits.length; + if ((vectorIndex = (limit / BitCacheSize) - 1) >= length) { + return this; // not enough room yet + } + long mask = (1L << (limit % BitCacheSize))-1; + this.extraDefiniteInits[vectorIndex] &= mask; + this.extraPotentialInits[vectorIndex] &= mask; + for (int i = vectorIndex+1; i < length; i++) { + this.extraDefiniteInits[i] = 0L; + this.extraPotentialInits[i] = 0L; + } + return this; + } + + public FlowInfo initsWhenFalse() { + + return this; + } + + public FlowInfo initsWhenTrue() { + + return this; + } + + /** + * Check status of definite assignment at a given position. + * It deals with the dual representation of the InitializationInfo2: + * bits for the first 64 entries, then an array of booleans. + */ + final private boolean isDefinitelyAssigned(int position) { + + // Dependant of CodeStream.isDefinitelyAssigned(..) + // id is zero-based + if (position < BitCacheSize) { + return (definiteInits & (1L << position)) != 0; // use bits + } + // use extra vector + if (extraDefiniteInits == null) + return false; // if vector not yet allocated, then not initialized + int vectorIndex; + if ((vectorIndex = (position / BitCacheSize) - 1) >= extraDefiniteInits.length) + return false; // if not enough room in vector, then not initialized + return ((extraDefiniteInits[vectorIndex]) & (1L << (position % BitCacheSize))) != 0; + } + + /** + * Check status of definite assignment for a field. + */ + final public boolean isDefinitelyAssigned(FieldBinding field) { + + // Dependant of CodeStream.isDefinitelyAssigned(..) + // We do not want to complain in unreachable code + if ((this.reachMode & UNREACHABLE) != 0) + return true; + return isDefinitelyAssigned(field.id); + } + + /** + * Check status of definite assignment for a local. + */ + final public boolean isDefinitelyAssigned(LocalVariableBinding local) { + + // Dependant of CodeStream.isDefinitelyAssigned(..) + // We do not want to complain in unreachable code + if ((this.reachMode & UNREACHABLE) != 0) + return true; + if (local.isArgument) { + return true; + } + // final constants are inlined, and thus considered as always initialized + if (local.constant != Constant.NotAConstant) { + return true; + } + return isDefinitelyAssigned(local.id + maxFieldCount); + } + + public boolean isReachable() { + + return this.reachMode == REACHABLE; + } + + /** + * Check status of potential assignment at a given position. + * It deals with the dual representation of the InitializationInfo3: + * bits for the first 64 entries, then an array of booleans. + */ + final private boolean isPotentiallyAssigned(int position) { + + // id is zero-based + if (position < BitCacheSize) { + // use bits + return (potentialInits & (1L << position)) != 0; + } + // use extra vector + if (extraPotentialInits == null) + return false; // if vector not yet allocated, then not initialized + int vectorIndex; + if ((vectorIndex = (position / BitCacheSize) - 1) >= extraPotentialInits.length) + return false; // if not enough room in vector, then not initialized + return ((extraPotentialInits[vectorIndex]) & (1L << (position % BitCacheSize))) != 0; + } + + /** + * Check status of definite assignment for a field. + */ + final public boolean isPotentiallyAssigned(FieldBinding field) { + + return isPotentiallyAssigned(field.id); + } + + /** + * Check status of potential assignment for a local. + */ + final public boolean isPotentiallyAssigned(LocalVariableBinding local) { + + if (local.isArgument) { + return true; + } + // final constants are inlined, and thus considered as always initialized + if (local.constant != Constant.NotAConstant) { + return true; + } + return isPotentiallyAssigned(local.id + maxFieldCount); + } + + /** + * Record a definite assignment at a given position. + * It deals with the dual representation of the InitializationInfo2: + * bits for the first 64 entries, then an array of booleans. + */ + final private void markAsDefinitelyAssigned(int position) { + + if (this != DEAD_END) { + + // position is zero-based + if (position < BitCacheSize) { + // use bits + long mask; + definiteInits |= (mask = 1L << position); + potentialInits |= mask; + } else { + // use extra vector + int vectorIndex = (position / BitCacheSize) - 1; + if (extraDefiniteInits == null) { + int length; + extraDefiniteInits = new long[length = vectorIndex + 1]; + extraPotentialInits = new long[length]; + } else { + int oldLength; // might need to grow the arrays + if (vectorIndex >= (oldLength = extraDefiniteInits.length)) { + System.arraycopy(extraDefiniteInits, 0, (extraDefiniteInits = new long[vectorIndex + 1]), 0, oldLength); + System.arraycopy(extraPotentialInits, 0, (extraPotentialInits = new long[vectorIndex + 1]), 0, oldLength); + } + } + long mask; + extraDefiniteInits[vectorIndex] |= (mask = 1L << (position % BitCacheSize)); + extraPotentialInits[vectorIndex] |= mask; + } + } + } + + /** + * Record a field got definitely assigned. + */ + public void markAsDefinitelyAssigned(FieldBinding field) { + if (this != DEAD_END) + markAsDefinitelyAssigned(field.id); + } + + /** + * Record a local got definitely assigned. + */ + public void markAsDefinitelyAssigned(LocalVariableBinding local) { + if (this != DEAD_END) + markAsDefinitelyAssigned(local.id + maxFieldCount); + } + + /** + * Clear initialization information at a given position. + * It deals with the dual representation of the InitializationInfo2: + * bits for the first 64 entries, then an array of booleans. + */ + final private void markAsDefinitelyNotAssigned(int position) { + if (this != DEAD_END) { + + // position is zero-based + if (position < BitCacheSize) { + // use bits + long mask; + definiteInits &= ~(mask = 1L << position); + potentialInits &= ~mask; + } else { + // use extra vector + int vectorIndex = (position / BitCacheSize) - 1; + if (extraDefiniteInits == null) { + return; // nothing to do, it was not yet set + } else { + // might need to grow the arrays + if (vectorIndex >= extraDefiniteInits.length) { + return; // nothing to do, it was not yet set + } + } + long mask; + extraDefiniteInits[vectorIndex] &= ~(mask = 1L << (position % BitCacheSize)); + extraPotentialInits[vectorIndex] &= ~mask; + } + } + } + + /** + * Clear the initialization info for a field + */ + public void markAsDefinitelyNotAssigned(FieldBinding field) { + + if (this != DEAD_END) + markAsDefinitelyNotAssigned(field.id); + } + + /** + * Clear the initialization info for a local variable + */ + + public void markAsDefinitelyNotAssigned(LocalVariableBinding local) { + + if (this != DEAD_END) + markAsDefinitelyNotAssigned(local.id + maxFieldCount); + } + + /** + * Returns the receiver updated in the following way:
      + *
    • intersection of definitely assigned variables, + *
    • union of potentially assigned variables. + *
    + */ + public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) { + + if (this == DEAD_END) return otherInits; + if (otherInits == DEAD_END) return this; + + if ((this.reachMode & UNREACHABLE) != (otherInits.reachMode & UNREACHABLE)){ + if ((this.reachMode & UNREACHABLE) != 0){ + return otherInits; + } else { + return this; + } + } + + // if one branch is not fake reachable, then the merged one is reachable + this.reachMode &= otherInits.reachMode; + + // intersection of definitely assigned variables, + this.definiteInits &= otherInits.definiteInits; + // union of potentially set ones + this.potentialInits |= otherInits.potentialInits; + + // treating extra storage + if (this.extraDefiniteInits != null) { + if (otherInits.extraDefiniteInits != null) { + // both sides have extra storage + int i = 0, length, otherLength; + if ((length = this.extraDefiniteInits.length) < (otherLength = otherInits.extraDefiniteInits.length)) { + // current storage is shorter -> grow current (could maybe reuse otherInits extra storage?) + System.arraycopy(this.extraDefiniteInits, 0, (this.extraDefiniteInits = new long[otherLength]), 0, length); + System.arraycopy(this.extraPotentialInits, 0, (this.extraPotentialInits = new long[otherLength]), 0, length); + while (i < length) { + this.extraDefiniteInits[i] &= otherInits.extraDefiniteInits[i]; + this.extraPotentialInits[i] |= otherInits.extraPotentialInits[i++]; + } + while (i < otherLength) { + this.extraPotentialInits[i] = otherInits.extraPotentialInits[i++]; + } + } else { + // current storage is longer + while (i < otherLength) { + this.extraDefiniteInits[i] &= otherInits.extraDefiniteInits[i]; + this.extraPotentialInits[i] |= otherInits.extraPotentialInits[i++]; + } + while (i < length) + this.extraDefiniteInits[i++] = 0; + } + } else { + // no extra storage on otherInits + int i = 0, length = this.extraDefiniteInits.length; + while (i < length) + this.extraDefiniteInits[i++] = 0; + } + } else + if (otherInits.extraDefiniteInits != null) { + // no storage here, but other has extra storage. + int otherLength; + this.extraDefiniteInits = new long[otherLength = otherInits.extraDefiniteInits.length]; + System.arraycopy(otherInits.extraPotentialInits, 0, (this.extraPotentialInits = new long[otherLength]), 0, otherLength); + } + return this; + } + + /* + * Answer the total number of fields in enclosing types of a given type + */ + static int numberOfEnclosingFields(ReferenceBinding type){ + + int count = 0; + type = type.enclosingType(); + while(type != null) { + count += type.fieldCount(); + type = type.enclosingType(); + } + return count; + } + + public int reachMode(){ + return this.reachMode; + } + + public FlowInfo setReachMode(int reachMode) { + + if (this == DEAD_END) return this; // cannot modify DEAD_END + + // reset optional inits when becoming unreachable + if ((this.reachMode & UNREACHABLE) == 0 && (reachMode & UNREACHABLE) != 0) { + this.potentialInits = 0; + if (this.extraPotentialInits != null){ + for (int i = 0, length = this.extraPotentialInits.length; i < length; i++){ + this.extraPotentialInits[i] = 0; + } + } + } + this.reachMode = reachMode; + + return this; + } + + public String toString(){ + + if (this == DEAD_END){ + return "FlowInfo.DEAD_END"; //$NON-NLS-1$ + } + return "FlowInfo"; //$NON-NLS-1$ + } + + public UnconditionalFlowInfo unconditionalInits() { + + // also see conditional inits, where it requests them to merge + return this; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/BooleanConstant.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/BooleanConstant.java new file mode 100644 index 0000000..6af6c00 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/BooleanConstant.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.impl; + +public class BooleanConstant extends Constant { + boolean value; + + +public BooleanConstant(boolean value) { + this.value = value; +} +public boolean booleanValue() { + return (boolean) value; +} +public String stringValue() { + //spec 15.17.11 + + String s = new Boolean(value).toString() ; + if (s == null) + return "null"; //$NON-NLS-1$ + else + return s; +} +public String toString(){ + + return "(boolean)" + value ; } //$NON-NLS-1$ +public int typeID() { + return T_boolean; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/Constant.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/Constant.java new file mode 100644 index 0000000..c1b8d7e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/Constant.java @@ -0,0 +1,1611 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.impl; + +import net.sourceforge.phpdt.internal.compiler.lookup.TypeIds; +import net.sourceforge.phpdt.internal.compiler.problem.ShouldNotImplement; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpeclipse.internal.compiler.ast.OperatorIds; + +public abstract class Constant implements TypeIds, OperatorIds { + + public static final Constant NotAConstant = new DoubleConstant(Double.NaN); + + public static final IntConstant Zero = new IntConstant(0); + public static final IntConstant Two = new IntConstant(2); + public static final IntConstant One = new IntConstant(1); + + public boolean booleanValue() { + + throw new ShouldNotImplement(Util.bind("constant.cannotCastedInto",typeName(),"boolean")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public byte byteValue() { + + throw new ShouldNotImplement(Util.bind("constant.cannotCastedInto",typeName(),"byte")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public final Constant castTo(int conversionToTargetType){ + //the cast is an int of the form + // (castId<<4)+typeId (in order to follow the + //user written style (cast)expression .... + + if (this == NotAConstant) return NotAConstant; + switch(conversionToTargetType){ + case T_undefined : return this; + // TARGET TYPE <- FROM TYPE + // case (T_undefined<<4)+T_undefined : return NotAConstant; + // case (T_undefined<<4)+T_byte : return NotAConstant; + // case (T_undefined<<4)+T_long : return NotAConstant; + // case (T_undefined<<4)+T_short : return NotAConstant; + // case (T_undefined<<4)+T_void : return NotAConstant; + // case (T_undefined<<4)+T_String : return NotAConstant; + // case (T_undefined<<4)+T_Object : return NotAConstant; + // case (T_undefined<<4)+T_double : return NotAConstant; + // case (T_undefined<<4)+T_float : return NotAConstant; + // case (T_undefined<<4)+T_boolean : return NotAConstant; + // case (T_undefined<<4)+T_char : return NotAConstant; + // case (T_undefined<<4)+T_int : return NotAConstant; + + // case (T_byte<<4)+T_undefined : return NotAConstant; + case (T_byte<<4)+T_byte : return this; + case (T_byte<<4)+T_long : return Constant.fromValue((byte)this.longValue()); + case (T_byte<<4)+T_short : return Constant.fromValue((byte)this.shortValue()); + // case (T_byte<<4)+T_void : return NotAConstant; + // case (T_byte<<4)+T_String : return NotAConstant; + // case (T_byte<<4)+T_Object : return NotAConstant; + case (T_byte<<4)+T_double : return Constant.fromValue((byte)this.doubleValue()); + case (T_byte<<4)+T_float : return Constant.fromValue((byte)this.floatValue()); + // case (T_byte<<4)+T_boolean : return NotAConstant; + case (T_byte<<4)+T_char : return Constant.fromValue((byte)this.charValue()); + case (T_byte<<4)+T_int : return Constant.fromValue((byte)this.intValue()); + + // case (T_long<<4)+T_undefined : return NotAConstant; + case (T_long<<4)+T_byte : return Constant.fromValue((long)this.byteValue()); + case (T_long<<4)+T_long : return this; + case (T_long<<4)+T_short : return Constant.fromValue((long)this.shortValue()); + // case (T_long<<4)+T_void : return NotAConstant; + // case (T_long<<4)+T_String : return NotAConstant; + // case (T_long<<4)+T_Object : return NotAConstant; + case (T_long<<4)+T_double : return Constant.fromValue((long)this.doubleValue()); + case (T_long<<4)+T_float : return Constant.fromValue((long)this.floatValue()); + // case (T_long<<4)+T_boolean : return NotAConstant; + case (T_long<<4)+T_char : return Constant.fromValue((long)this.charValue()); + case (T_long<<4)+T_int : return Constant.fromValue((long)this.intValue()); + + // case (T_short<<4)+T_undefined : return NotAConstant; + case (T_short<<4)+T_byte : return Constant.fromValue((short)this.byteValue()); + case (T_short<<4)+T_long : return Constant.fromValue((short)this.longValue()); + case (T_short<<4)+T_short : return this; + // case (T_short<<4)+T_void : return NotAConstant; + // case (T_short<<4)+T_String : return NotAConstant; + // case (T_short<<4)+T_Object : return NotAConstant; + case (T_short<<4)+T_double : return Constant.fromValue((short)this.doubleValue()); + case (T_short<<4)+T_float : return Constant.fromValue((short)this.floatValue()); + // case (T_short<<4)+T_boolean : return NotAConstant; + case (T_short<<4)+T_char : return Constant.fromValue((short)this.charValue()); + case (T_short<<4)+T_int : return Constant.fromValue((short)this.intValue()); + + // case (T_void<<4)+T_undefined : return NotAConstant; + // case (T_void<<4)+T_byte : return NotAConstant; + // case (T_void<<4)+T_long : return NotAConstant; + // case (T_void<<4)+T_short : return NotAConstant; + // case (T_void<<4)+T_void : return NotAConstant; + // case (T_void<<4)+T_String : return NotAConstant; + // case (T_void<<4)+T_Object : return NotAConstant; + // case (T_void<<4)+T_double : return NotAConstant; + // case (T_void<<4)+T_float : return NotAConstant; + // case (T_void<<4)+T_boolean : return NotAConstant; + // case (T_void<<4)+T_char : return NotAConstant; + // case (T_void<<4)+T_int : return NotAConstant; + + // case (T_String<<4)+T_undefined : return NotAConstant; + // case (T_String<<4)+T_byte : return NotAConstant; + // case (T_String<<4)+T_long : return NotAConstant; + // case (T_String<<4)+T_short : return NotAConstant; + // case (T_String<<4)+T_void : return NotAConstant; + case (T_String<<4)+T_String : return this; + // case (T_String<<4)+T_Object : return NotAConstant; + // case (T_String<<4)+T_double : return NotAConstant; + // case (T_String<<4)+T_float : return NotAConstant; + // case (T_String<<4)+T_boolean : return NotAConstant; + // case (T_String<<4)+T_char : return NotAConstant; + // case (T_String<<4)+T_int : return NotAConstant; + + // case (T_Object<<4)+T_undefined : return NotAConstant; + // case (T_Object<<4)+T_byte : return NotAConstant; + // case (T_Object<<4)+T_long : return NotAConstant; + // case (T_Object<<4)+T_short : return NotAConstant; + // case (T_Object<<4)+T_void : return NotAConstant; + // case (T_Object<<4)+T_String : return NotAConstant; + // case (T_Object<<4)+T_Object : return NotAConstant; + // case (T_Object<<4)+T_double : return NotAConstant; + // case (T_Object<<4)+T_float : return NotAConstant; + // case (T_Object<<4)+T_boolean : return NotAConstant; + // case (T_Object<<4)+T_char : return NotAConstant; + // case (T_Object<<4)+T_int : return NotAConstant; + + // case (T_double<<4)+T_undefined : return NotAConstant; + case (T_double<<4)+T_byte : return Constant.fromValue((double)this.byteValue()); + case (T_double<<4)+T_long : return Constant.fromValue((double)this.longValue()); + case (T_double<<4)+T_short : return Constant.fromValue((double)this.shortValue()); + // case (T_double<<4)+T_void : return NotAConstant; + // case (T_double<<4)+T_String : return NotAConstant; + // case (T_double<<4)+T_Object : return NotAConstant; + case (T_double<<4)+T_double : return this; + case (T_double<<4)+T_float : return Constant.fromValue((double)this.floatValue()); + // case (T_double<<4)+T_boolean : return NotAConstant; + case (T_double<<4)+T_char : return Constant.fromValue((double)this.charValue()); + case (T_double<<4)+T_int : return Constant.fromValue((double)this.intValue()); + + // case (T_float<<4)+T_undefined : return NotAConstant; + case (T_float<<4)+T_byte : return Constant.fromValue((float)this.byteValue()); + case (T_float<<4)+T_long : return Constant.fromValue((float)this.longValue()); + case (T_float<<4)+T_short : return Constant.fromValue((float)this.shortValue()); + // case (T_float<<4)+T_void : return NotAConstant; + // case (T_float<<4)+T_String : return NotAConstant; + // case (T_float<<4)+T_Object : return NotAConstant; + case (T_float<<4)+T_double : return Constant.fromValue((float)this.doubleValue()); + case (T_float<<4)+T_float : return this; + // case (T_float<<4)+T_boolean : return NotAConstant; + case (T_float<<4)+T_char : return Constant.fromValue((float)this.charValue()); + case (T_float<<4)+T_int : return Constant.fromValue((float)this.intValue()); + + // case (T_boolean<<4)+T_undefined : return NotAConstant; + // case (T_boolean<<4)+T_byte : return NotAConstant; + // case (T_boolean<<4)+T_long : return NotAConstant; + // case (T_boolean<<4)+T_short : return NotAConstant; + // case (T_boolean<<4)+T_void : return NotAConstant; + // case (T_boolean<<4)+T_String : return NotAConstant; + // case (T_boolean<<4)+T_Object : return NotAConstant; + // case (T_boolean<<4)+T_double : return NotAConstant; + // case (T_boolean<<4)+T_float : return NotAConstant; + case (T_boolean<<4)+T_boolean : return this; + // case (T_boolean<<4)+T_char : return NotAConstant; + // case (T_boolean<<4)+T_int : return NotAConstant; + + // case (T_char<<4)+T_undefined : return NotAConstant; + case (T_char<<4)+T_byte : return Constant.fromValue((char)this.byteValue()); + case (T_char<<4)+T_long : return Constant.fromValue((char)this.longValue()); + case (T_char<<4)+T_short : return Constant.fromValue((char)this.shortValue()); + // case (T_char<<4)+T_void : return NotAConstant; + // case (T_char<<4)+T_String : return NotAConstant; + // case (T_char<<4)+T_Object : return NotAConstant; + case (T_char<<4)+T_double : return Constant.fromValue((char)this.doubleValue()); + case (T_char<<4)+T_float : return Constant.fromValue((char)this.floatValue()); + // case (T_char<<4)+T_boolean : return NotAConstant; + case (T_char<<4)+T_char : return this; + case (T_char<<4)+T_int : return Constant.fromValue((char)this.intValue()); + + // case (T_int<<4)+T_undefined : return NotAConstant; + case (T_int<<4)+T_byte : return Constant.fromValue((int)this.byteValue()); + case (T_int<<4)+T_long : return Constant.fromValue((int)this.longValue()); + case (T_int<<4)+T_short : return Constant.fromValue((int)this.shortValue()); + // case (T_int<<4)+T_void : return NotAConstant; + // case (T_int<<4)+T_String : return NotAConstant; + // case (T_int<<4)+T_Object : return NotAConstant; + case (T_int<<4)+T_double : return Constant.fromValue((int)this.doubleValue()); + case (T_int<<4)+T_float : return Constant.fromValue((int)this.floatValue()); + // case (T_int<<4)+T_boolean : return NotAConstant; + case (T_int<<4)+T_char : return Constant.fromValue((int)this.charValue()); + case (T_int<<4)+T_int : return this; + + } + + return NotAConstant; + } + + public char charValue() { + + throw new ShouldNotImplement(Util.bind("constant.cannotCastedInto",typeName(),"char")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public static final Constant computeConstantOperation(Constant cst, int id, int operator) { + + switch (operator) { + case NOT : + return Constant.fromValue(!cst.booleanValue()); + case PLUS : return cst; + case MINUS : //the two special -9223372036854775808L and -2147483648 are inlined at parseTime + switch (id){ + case T_float : float f; + if ( (f= cst.floatValue()) == 0.0f) + { //positive and negative 0.... + if (Float.floatToIntBits(f) == 0) + return Constant.fromValue(-0.0f); + else + return Constant.fromValue(0.0f);} + break; //default case + case T_double : double d; + if ( (d= cst.doubleValue()) == 0.0d) + { //positive and negative 0.... + if (Double.doubleToLongBits(d) == 0) + return Constant.fromValue(-0.0d); + else + return Constant.fromValue(0.0d);} + break; //default case + } + return computeConstantOperationMINUS(Zero,T_int,operator,cst,id); + case TWIDDLE: + switch (id){ + case T_char : return Constant.fromValue(~ cst.charValue()); + case T_byte: return Constant.fromValue(~ cst.byteValue()); + case T_short: return Constant.fromValue(~ cst.shortValue()); + case T_int: return Constant.fromValue(~ cst.intValue()); + case T_long: return Constant.fromValue(~ cst.longValue()); + default : return NotAConstant; + } + default : return NotAConstant; + } + } + + public static final Constant computeConstantOperation(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (operator) { + case AND : return computeConstantOperationAND (left,leftId,operator,right,rightId); + case AND_AND : return computeConstantOperationAND_AND (left,leftId,operator,right,rightId); + case DIVIDE : return computeConstantOperationDIVIDE (left,leftId,operator,right,rightId); + case GREATER : return computeConstantOperationGREATER (left,leftId,operator,right,rightId); + case GREATER_EQUAL : return computeConstantOperationGREATER_EQUAL(left,leftId,operator,right,rightId); + case LEFT_SHIFT : return computeConstantOperationLEFT_SHIFT (left,leftId,operator,right,rightId); + case LESS : return computeConstantOperationLESS (left,leftId,operator,right,rightId); + case LESS_EQUAL : return computeConstantOperationLESS_EQUAL (left,leftId,operator,right,rightId); + case MINUS : return computeConstantOperationMINUS (left,leftId,operator,right,rightId); + case MULTIPLY : return computeConstantOperationMULTIPLY (left,leftId,operator,right,rightId); + case OR : return computeConstantOperationOR (left,leftId,operator,right,rightId); + case OR_OR : return computeConstantOperationOR_OR (left,leftId,operator,right,rightId); + case PLUS : return computeConstantOperationPLUS (left,leftId,operator,right,rightId); + case REMAINDER : return computeConstantOperationREMAINDER (left,leftId,operator,right,rightId); + case RIGHT_SHIFT: return computeConstantOperationRIGHT_SHIFT(left,leftId,operator,right,rightId); + case UNSIGNED_RIGHT_SHIFT: return computeConstantOperationUNSIGNED_RIGHT_SHIFT(left,leftId,operator,right,rightId); + case XOR : return computeConstantOperationXOR (left,leftId,operator,right,rightId); + + default : return NotAConstant; + } + } + + public static final Constant computeConstantOperationAND(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_boolean : return Constant.fromValue(left.booleanValue() & right.booleanValue()); + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() & right.charValue()); + case T_byte: return Constant.fromValue(left.charValue() & right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() & right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() & right.intValue()); + case T_long: return Constant.fromValue(left.charValue() & right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() & right.charValue()); + case T_byte: return Constant.fromValue(left.byteValue() & right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() & right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() & right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() & right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() & right.charValue()); + case T_byte: return Constant.fromValue(left.shortValue() & right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() & right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() & right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() & right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() & right.charValue()); + case T_byte: return Constant.fromValue(left.intValue() & right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() & right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() & right.intValue()); + case T_long: return Constant.fromValue(left.intValue() & right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() & right.charValue()); + case T_byte: return Constant.fromValue(left.longValue() & right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() & right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() & right.intValue()); + case T_long: return Constant.fromValue(left.longValue() & right.longValue()); + } + } + + return NotAConstant; + } + + public static final Constant computeConstantOperationAND_AND(Constant left, int leftId, int operator, Constant right, int rightId) { + + return Constant.fromValue(left.booleanValue() && right.booleanValue()); + } + + public static final Constant computeConstantOperationDIVIDE(Constant left, int leftId, int operator, Constant right, int rightId) { + // division by zero must be handled outside this method (error reporting) + + switch (leftId){ + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() / right.charValue()); + case T_float: return Constant.fromValue(left.charValue() / right.floatValue()); + case T_double: return Constant.fromValue(left.charValue() / right.doubleValue()); + case T_byte: return Constant.fromValue(left.charValue() / right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() / right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() / right.intValue()); + case T_long: return Constant.fromValue(left.charValue() / right.longValue()); + } + break; + case T_float : + switch (rightId){ + case T_char : return Constant.fromValue(left.floatValue() / right.charValue()); + case T_float: return Constant.fromValue(left.floatValue() / right.floatValue()); + case T_double: return Constant.fromValue(left.floatValue() / right.doubleValue()); + case T_byte: return Constant.fromValue(left.floatValue() / right.byteValue()); + case T_short: return Constant.fromValue(left.floatValue() / right.shortValue()); + case T_int: return Constant.fromValue(left.floatValue() / right.intValue()); + case T_long: return Constant.fromValue(left.floatValue() / right.longValue()); + } + break; + case T_double : + switch (rightId){ + case T_char : return Constant.fromValue(left.doubleValue() / right.charValue()); + case T_float: return Constant.fromValue(left.doubleValue() / right.floatValue()); + case T_double: return Constant.fromValue(left.doubleValue() / right.doubleValue()); + case T_byte: return Constant.fromValue(left.doubleValue() / right.byteValue()); + case T_short: return Constant.fromValue(left.doubleValue() / right.shortValue()); + case T_int: return Constant.fromValue(left.doubleValue() / right.intValue()); + case T_long: return Constant.fromValue(left.doubleValue() / right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() / right.charValue()); + case T_float: return Constant.fromValue(left.byteValue() / right.floatValue()); + case T_double: return Constant.fromValue(left.byteValue() / right.doubleValue()); + case T_byte: return Constant.fromValue(left.byteValue() / right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() / right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() / right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() / right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() / right.charValue()); + case T_float: return Constant.fromValue(left.shortValue() / right.floatValue()); + case T_double: return Constant.fromValue(left.shortValue() / right.doubleValue()); + case T_byte: return Constant.fromValue(left.shortValue() / right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() / right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() / right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() / right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() / right.charValue()); + case T_float: return Constant.fromValue(left.intValue() / right.floatValue()); + case T_double: return Constant.fromValue(left.intValue() / right.doubleValue()); + case T_byte: return Constant.fromValue(left.intValue() / right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() / right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() / right.intValue()); + case T_long: return Constant.fromValue(left.intValue() / right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() / right.charValue()); + case T_float: return Constant.fromValue(left.longValue() / right.floatValue()); + case T_double: return Constant.fromValue(left.longValue() / right.doubleValue()); + case T_byte: return Constant.fromValue(left.longValue() / right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() / right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() / right.intValue()); + case T_long: return Constant.fromValue(left.longValue() / right.longValue()); + } + + } + + return NotAConstant; + } + + public static final Constant computeConstantOperationEQUAL_EQUAL(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_boolean : + if (rightId == T_boolean) { + return Constant.fromValue(left.booleanValue() == right.booleanValue()); + } + break; + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() == right.charValue()); + case T_float: return Constant.fromValue(left.charValue() == right.floatValue()); + case T_double: return Constant.fromValue(left.charValue() == right.doubleValue()); + case T_byte: return Constant.fromValue(left.charValue() == right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() == right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() == right.intValue()); + case T_long: return Constant.fromValue(left.charValue() == right.longValue());} + break; + case T_float : + switch (rightId){ + case T_char : return Constant.fromValue(left.floatValue() == right.charValue()); + case T_float: return Constant.fromValue(left.floatValue() == right.floatValue()); + case T_double: return Constant.fromValue(left.floatValue() == right.doubleValue()); + case T_byte: return Constant.fromValue(left.floatValue() == right.byteValue()); + case T_short: return Constant.fromValue(left.floatValue() == right.shortValue()); + case T_int: return Constant.fromValue(left.floatValue() == right.intValue()); + case T_long: return Constant.fromValue(left.floatValue() == right.longValue()); + } + break; + case T_double : + switch (rightId){ + case T_char : return Constant.fromValue(left.doubleValue() == right.charValue()); + case T_float: return Constant.fromValue(left.doubleValue() == right.floatValue()); + case T_double: return Constant.fromValue(left.doubleValue() == right.doubleValue()); + case T_byte: return Constant.fromValue(left.doubleValue() == right.byteValue()); + case T_short: return Constant.fromValue(left.doubleValue() == right.shortValue()); + case T_int: return Constant.fromValue(left.doubleValue() == right.intValue()); + case T_long: return Constant.fromValue(left.doubleValue() == right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() == right.charValue()); + case T_float: return Constant.fromValue(left.byteValue() == right.floatValue()); + case T_double: return Constant.fromValue(left.byteValue() == right.doubleValue()); + case T_byte: return Constant.fromValue(left.byteValue() == right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() == right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() == right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() == right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() == right.charValue()); + case T_float: return Constant.fromValue(left.shortValue() == right.floatValue()); + case T_double: return Constant.fromValue(left.shortValue() == right.doubleValue()); + case T_byte: return Constant.fromValue(left.shortValue() == right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() == right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() == right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() == right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() == right.charValue()); + case T_float: return Constant.fromValue(left.intValue() == right.floatValue()); + case T_double: return Constant.fromValue(left.intValue() == right.doubleValue()); + case T_byte: return Constant.fromValue(left.intValue() == right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() == right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() == right.intValue()); + case T_long: return Constant.fromValue(left.intValue() == right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() == right.charValue()); + case T_float: return Constant.fromValue(left.longValue() == right.floatValue()); + case T_double: return Constant.fromValue(left.longValue() == right.doubleValue()); + case T_byte: return Constant.fromValue(left.longValue() == right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() == right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() == right.intValue()); + case T_long: return Constant.fromValue(left.longValue() == right.longValue()); + } + break; + case T_String : + if (rightId == T_String) { + //String are interned in th compiler==>thus if two string constant + //get to be compared, it is an equal on the vale which is done + return Constant.fromValue(((StringConstant)left).compileTimeEqual((StringConstant)right)); + } + break; + case T_null : + if (rightId == T_String) { + return Constant.fromValue(false); + } else { + if (rightId == T_null) { + return Constant.fromValue(true); + } + } + } + + return Constant.fromValue(false); + } + + public static final Constant computeConstantOperationGREATER(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() > right.charValue()); + case T_float: return Constant.fromValue(left.charValue() > right.floatValue()); + case T_double: return Constant.fromValue(left.charValue() > right.doubleValue()); + case T_byte: return Constant.fromValue(left.charValue() > right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() > right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() > right.intValue()); + case T_long: return Constant.fromValue(left.charValue() > right.longValue()); + } + break; + case T_float : + switch (rightId){ + case T_char : return Constant.fromValue(left.floatValue() > right.charValue()); + case T_float: return Constant.fromValue(left.floatValue() > right.floatValue()); + case T_double: return Constant.fromValue(left.floatValue() > right.doubleValue()); + case T_byte: return Constant.fromValue(left.floatValue() > right.byteValue()); + case T_short: return Constant.fromValue(left.floatValue() > right.shortValue()); + case T_int: return Constant.fromValue(left.floatValue() > right.intValue()); + case T_long: return Constant.fromValue(left.floatValue() > right.longValue()); + } + break; + case T_double : + switch (rightId){ + case T_char : return Constant.fromValue(left.doubleValue() > right.charValue()); + case T_float: return Constant.fromValue(left.doubleValue() > right.floatValue()); + case T_double: return Constant.fromValue(left.doubleValue() > right.doubleValue()); + case T_byte: return Constant.fromValue(left.doubleValue() > right.byteValue()); + case T_short: return Constant.fromValue(left.doubleValue() > right.shortValue()); + case T_int: return Constant.fromValue(left.doubleValue() > right.intValue()); + case T_long: return Constant.fromValue(left.doubleValue() > right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() > right.charValue()); + case T_float: return Constant.fromValue(left.byteValue() > right.floatValue()); + case T_double: return Constant.fromValue(left.byteValue() > right.doubleValue()); + case T_byte: return Constant.fromValue(left.byteValue() > right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() > right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() > right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() > right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() > right.charValue()); + case T_float: return Constant.fromValue(left.shortValue() > right.floatValue()); + case T_double: return Constant.fromValue(left.shortValue() > right.doubleValue()); + case T_byte: return Constant.fromValue(left.shortValue() > right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() > right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() > right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() > right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() > right.charValue()); + case T_float: return Constant.fromValue(left.intValue() > right.floatValue()); + case T_double: return Constant.fromValue(left.intValue() > right.doubleValue()); + case T_byte: return Constant.fromValue(left.intValue() > right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() > right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() > right.intValue()); + case T_long: return Constant.fromValue(left.intValue() > right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() > right.charValue()); + case T_float: return Constant.fromValue(left.longValue() > right.floatValue()); + case T_double: return Constant.fromValue(left.longValue() > right.doubleValue()); + case T_byte: return Constant.fromValue(left.longValue() > right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() > right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() > right.intValue()); + case T_long: return Constant.fromValue(left.longValue() > right.longValue()); + } + + } + + return NotAConstant; + } + + public static final Constant computeConstantOperationGREATER_EQUAL(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() >= right.charValue()); + case T_float: return Constant.fromValue(left.charValue() >= right.floatValue()); + case T_double: return Constant.fromValue(left.charValue() >= right.doubleValue()); + case T_byte: return Constant.fromValue(left.charValue() >= right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() >= right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() >= right.intValue()); + case T_long: return Constant.fromValue(left.charValue() >= right.longValue()); + } + break; + case T_float : + switch (rightId){ + case T_char : return Constant.fromValue(left.floatValue() >= right.charValue()); + case T_float: return Constant.fromValue(left.floatValue() >= right.floatValue()); + case T_double: return Constant.fromValue(left.floatValue() >= right.doubleValue()); + case T_byte: return Constant.fromValue(left.floatValue() >= right.byteValue()); + case T_short: return Constant.fromValue(left.floatValue() >= right.shortValue()); + case T_int: return Constant.fromValue(left.floatValue() >= right.intValue()); + case T_long: return Constant.fromValue(left.floatValue() >= right.longValue()); + } + break; + case T_double : + switch (rightId){ + case T_char : return Constant.fromValue(left.doubleValue() >= right.charValue()); + case T_float: return Constant.fromValue(left.doubleValue() >= right.floatValue()); + case T_double: return Constant.fromValue(left.doubleValue() >= right.doubleValue()); + case T_byte: return Constant.fromValue(left.doubleValue() >= right.byteValue()); + case T_short: return Constant.fromValue(left.doubleValue() >= right.shortValue()); + case T_int: return Constant.fromValue(left.doubleValue() >= right.intValue()); + case T_long: return Constant.fromValue(left.doubleValue() >= right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() >= right.charValue()); + case T_float: return Constant.fromValue(left.byteValue() >= right.floatValue()); + case T_double: return Constant.fromValue(left.byteValue() >= right.doubleValue()); + case T_byte: return Constant.fromValue(left.byteValue() >= right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() >= right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() >= right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() >= right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() >= right.charValue()); + case T_float: return Constant.fromValue(left.shortValue() >= right.floatValue()); + case T_double: return Constant.fromValue(left.shortValue() >= right.doubleValue()); + case T_byte: return Constant.fromValue(left.shortValue() >= right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() >= right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() >= right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() >= right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() >= right.charValue()); + case T_float: return Constant.fromValue(left.intValue() >= right.floatValue()); + case T_double: return Constant.fromValue(left.intValue() >= right.doubleValue()); + case T_byte: return Constant.fromValue(left.intValue() >= right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() >= right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() >= right.intValue()); + case T_long: return Constant.fromValue(left.intValue() >= right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() >= right.charValue()); + case T_float: return Constant.fromValue(left.longValue() >= right.floatValue()); + case T_double: return Constant.fromValue(left.longValue() >= right.doubleValue()); + case T_byte: return Constant.fromValue(left.longValue() >= right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() >= right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() >= right.intValue()); + case T_long: return Constant.fromValue(left.longValue() >= right.longValue()); + } + + } + + return NotAConstant; + } + + public static final Constant computeConstantOperationLEFT_SHIFT(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() << right.charValue()); + case T_byte: return Constant.fromValue(left.charValue() << right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() << right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() << right.intValue()); + case T_long: return Constant.fromValue(left.charValue() << right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() << right.charValue()); + case T_byte: return Constant.fromValue(left.byteValue() << right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() << right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() << right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() << right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() << right.charValue()); + case T_byte: return Constant.fromValue(left.shortValue() << right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() << right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() << right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() << right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() << right.charValue()); + case T_byte: return Constant.fromValue(left.intValue() << right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() << right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() << right.intValue()); + case T_long: return Constant.fromValue(left.intValue() << right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() << right.charValue()); + case T_byte: return Constant.fromValue(left.longValue() << right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() << right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() << right.intValue()); + case T_long: return Constant.fromValue(left.longValue() << right.longValue()); + } + + } + + return NotAConstant; + } + + public static final Constant computeConstantOperationLESS(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() < right.charValue()); + case T_float: return Constant.fromValue(left.charValue() < right.floatValue()); + case T_double: return Constant.fromValue(left.charValue() < right.doubleValue()); + case T_byte: return Constant.fromValue(left.charValue() < right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() < right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() < right.intValue()); + case T_long: return Constant.fromValue(left.charValue() < right.longValue()); + } + break; + case T_float : + switch (rightId){ + case T_char : return Constant.fromValue(left.floatValue() < right.charValue()); + case T_float: return Constant.fromValue(left.floatValue() < right.floatValue()); + case T_double: return Constant.fromValue(left.floatValue() < right.doubleValue()); + case T_byte: return Constant.fromValue(left.floatValue() < right.byteValue()); + case T_short: return Constant.fromValue(left.floatValue() < right.shortValue()); + case T_int: return Constant.fromValue(left.floatValue() < right.intValue()); + case T_long: return Constant.fromValue(left.floatValue() < right.longValue()); + } + break; + case T_double : + switch (rightId){ + case T_char : return Constant.fromValue(left.doubleValue() < right.charValue()); + case T_float: return Constant.fromValue(left.doubleValue() < right.floatValue()); + case T_double: return Constant.fromValue(left.doubleValue() < right.doubleValue()); + case T_byte: return Constant.fromValue(left.doubleValue() < right.byteValue()); + case T_short: return Constant.fromValue(left.doubleValue() < right.shortValue()); + case T_int: return Constant.fromValue(left.doubleValue() < right.intValue()); + case T_long: return Constant.fromValue(left.doubleValue() < right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() < right.charValue()); + case T_float: return Constant.fromValue(left.byteValue() < right.floatValue()); + case T_double: return Constant.fromValue(left.byteValue() < right.doubleValue()); + case T_byte: return Constant.fromValue(left.byteValue() < right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() < right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() < right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() < right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() < right.charValue()); + case T_float: return Constant.fromValue(left.shortValue() < right.floatValue()); + case T_double: return Constant.fromValue(left.shortValue() < right.doubleValue()); + case T_byte: return Constant.fromValue(left.shortValue() < right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() < right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() < right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() < right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() < right.charValue()); + case T_float: return Constant.fromValue(left.intValue() < right.floatValue()); + case T_double: return Constant.fromValue(left.intValue() < right.doubleValue()); + case T_byte: return Constant.fromValue(left.intValue() < right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() < right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() < right.intValue()); + case T_long: return Constant.fromValue(left.intValue() < right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() < right.charValue()); + case T_float: return Constant.fromValue(left.longValue() < right.floatValue()); + case T_double: return Constant.fromValue(left.longValue() < right.doubleValue()); + case T_byte: return Constant.fromValue(left.longValue() < right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() < right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() < right.intValue()); + case T_long: return Constant.fromValue(left.longValue() < right.longValue()); + } + + } + + return NotAConstant; + } + + public static final Constant computeConstantOperationLESS_EQUAL(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() <= right.charValue()); + case T_float: return Constant.fromValue(left.charValue() <= right.floatValue()); + case T_double: return Constant.fromValue(left.charValue() <= right.doubleValue()); + case T_byte: return Constant.fromValue(left.charValue() <= right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() <= right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() <= right.intValue()); + case T_long: return Constant.fromValue(left.charValue() <= right.longValue()); + } + break; + case T_float : + switch (rightId){ + case T_char : return Constant.fromValue(left.floatValue() <= right.charValue()); + case T_float: return Constant.fromValue(left.floatValue() <= right.floatValue()); + case T_double: return Constant.fromValue(left.floatValue() <= right.doubleValue()); + case T_byte: return Constant.fromValue(left.floatValue() <= right.byteValue()); + case T_short: return Constant.fromValue(left.floatValue() <= right.shortValue()); + case T_int: return Constant.fromValue(left.floatValue() <= right.intValue()); + case T_long: return Constant.fromValue(left.floatValue() <= right.longValue()); + } + break; + case T_double : + switch (rightId){ + case T_char : return Constant.fromValue(left.doubleValue() <= right.charValue()); + case T_float: return Constant.fromValue(left.doubleValue() <= right.floatValue()); + case T_double: return Constant.fromValue(left.doubleValue() <= right.doubleValue()); + case T_byte: return Constant.fromValue(left.doubleValue() <= right.byteValue()); + case T_short: return Constant.fromValue(left.doubleValue() <= right.shortValue()); + case T_int: return Constant.fromValue(left.doubleValue() <= right.intValue()); + case T_long: return Constant.fromValue(left.doubleValue() <= right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() <= right.charValue()); + case T_float: return Constant.fromValue(left.byteValue() <= right.floatValue()); + case T_double: return Constant.fromValue(left.byteValue() <= right.doubleValue()); + case T_byte: return Constant.fromValue(left.byteValue() <= right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() <= right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() <= right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() <= right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() <= right.charValue()); + case T_float: return Constant.fromValue(left.shortValue() <= right.floatValue()); + case T_double: return Constant.fromValue(left.shortValue() <= right.doubleValue()); + case T_byte: return Constant.fromValue(left.shortValue() <= right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() <= right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() <= right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() <= right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() <= right.charValue()); + case T_float: return Constant.fromValue(left.intValue() <= right.floatValue()); + case T_double: return Constant.fromValue(left.intValue() <= right.doubleValue()); + case T_byte: return Constant.fromValue(left.intValue() <= right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() <= right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() <= right.intValue()); + case T_long: return Constant.fromValue(left.intValue() <= right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() <= right.charValue()); + case T_float: return Constant.fromValue(left.longValue() <= right.floatValue()); + case T_double: return Constant.fromValue(left.longValue() <= right.doubleValue()); + case T_byte: return Constant.fromValue(left.longValue() <= right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() <= right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() <= right.intValue()); + case T_long: return Constant.fromValue(left.longValue() <= right.longValue()); + } + } + + return NotAConstant; + } + + public static final Constant computeConstantOperationMINUS(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() - right.charValue()); + case T_float: return Constant.fromValue(left.charValue() - right.floatValue()); + case T_double: return Constant.fromValue(left.charValue() - right.doubleValue()); + case T_byte: return Constant.fromValue(left.charValue() - right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() - right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() - right.intValue()); + case T_long: return Constant.fromValue(left.charValue() - right.longValue()); + } + break; + case T_float : + switch (rightId){ + case T_char : return Constant.fromValue(left.floatValue() - right.charValue()); + case T_float: return Constant.fromValue(left.floatValue() - right.floatValue()); + case T_double: return Constant.fromValue(left.floatValue() - right.doubleValue()); + case T_byte: return Constant.fromValue(left.floatValue() - right.byteValue()); + case T_short: return Constant.fromValue(left.floatValue() - right.shortValue()); + case T_int: return Constant.fromValue(left.floatValue() - right.intValue()); + case T_long: return Constant.fromValue(left.floatValue() - right.longValue()); + } + break; + case T_double : + switch (rightId){ + case T_char : return Constant.fromValue(left.doubleValue() - right.charValue()); + case T_float: return Constant.fromValue(left.doubleValue() - right.floatValue()); + case T_double: return Constant.fromValue(left.doubleValue() - right.doubleValue()); + case T_byte: return Constant.fromValue(left.doubleValue() - right.byteValue()); + case T_short: return Constant.fromValue(left.doubleValue() - right.shortValue()); + case T_int: return Constant.fromValue(left.doubleValue() - right.intValue()); + case T_long: return Constant.fromValue(left.doubleValue() - right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() - right.charValue()); + case T_float: return Constant.fromValue(left.byteValue() - right.floatValue()); + case T_double: return Constant.fromValue(left.byteValue() - right.doubleValue()); + case T_byte: return Constant.fromValue(left.byteValue() - right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() - right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() - right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() - right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() - right.charValue()); + case T_float: return Constant.fromValue(left.shortValue() - right.floatValue()); + case T_double: return Constant.fromValue(left.shortValue() - right.doubleValue()); + case T_byte: return Constant.fromValue(left.shortValue() - right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() - right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() - right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() - right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() - right.charValue()); + case T_float: return Constant.fromValue(left.intValue() - right.floatValue()); + case T_double: return Constant.fromValue(left.intValue() - right.doubleValue()); + case T_byte: return Constant.fromValue(left.intValue() - right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() - right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() - right.intValue()); + case T_long: return Constant.fromValue(left.intValue() - right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() - right.charValue()); + case T_float: return Constant.fromValue(left.longValue() - right.floatValue()); + case T_double: return Constant.fromValue(left.longValue() - right.doubleValue()); + case T_byte: return Constant.fromValue(left.longValue() - right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() - right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() - right.intValue()); + case T_long: return Constant.fromValue(left.longValue() - right.longValue()); + } + + } + + return NotAConstant; + } + + public static final Constant computeConstantOperationMULTIPLY(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() * right.charValue()); + case T_float: return Constant.fromValue(left.charValue() * right.floatValue()); + case T_double: return Constant.fromValue(left.charValue() * right.doubleValue()); + case T_byte: return Constant.fromValue(left.charValue() * right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() * right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() * right.intValue()); + case T_long: return Constant.fromValue(left.charValue() * right.longValue()); + } + break; + case T_float : + switch (rightId){ + case T_char : return Constant.fromValue(left.floatValue() * right.charValue()); + case T_float: return Constant.fromValue(left.floatValue() * right.floatValue()); + case T_double: return Constant.fromValue(left.floatValue() * right.doubleValue()); + case T_byte: return Constant.fromValue(left.floatValue() * right.byteValue()); + case T_short: return Constant.fromValue(left.floatValue() * right.shortValue()); + case T_int: return Constant.fromValue(left.floatValue() * right.intValue()); + case T_long: return Constant.fromValue(left.floatValue() * right.longValue()); + } + break; + case T_double : + switch (rightId){ + case T_char : return Constant.fromValue(left.doubleValue() * right.charValue()); + case T_float: return Constant.fromValue(left.doubleValue() * right.floatValue()); + case T_double: return Constant.fromValue(left.doubleValue() * right.doubleValue()); + case T_byte: return Constant.fromValue(left.doubleValue() * right.byteValue()); + case T_short: return Constant.fromValue(left.doubleValue() * right.shortValue()); + case T_int: return Constant.fromValue(left.doubleValue() * right.intValue()); + case T_long: return Constant.fromValue(left.doubleValue() * right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() * right.charValue()); + case T_float: return Constant.fromValue(left.byteValue() * right.floatValue()); + case T_double: return Constant.fromValue(left.byteValue() * right.doubleValue()); + case T_byte: return Constant.fromValue(left.byteValue() * right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() * right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() * right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() * right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() * right.charValue()); + case T_float: return Constant.fromValue(left.shortValue() * right.floatValue()); + case T_double: return Constant.fromValue(left.shortValue() * right.doubleValue()); + case T_byte: return Constant.fromValue(left.shortValue() * right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() * right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() * right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() * right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() * right.charValue()); + case T_float: return Constant.fromValue(left.intValue() * right.floatValue()); + case T_double: return Constant.fromValue(left.intValue() * right.doubleValue()); + case T_byte: return Constant.fromValue(left.intValue() * right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() * right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() * right.intValue()); + case T_long: return Constant.fromValue(left.intValue() * right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() * right.charValue()); + case T_float: return Constant.fromValue(left.longValue() * right.floatValue()); + case T_double: return Constant.fromValue(left.longValue() * right.doubleValue()); + case T_byte: return Constant.fromValue(left.longValue() * right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() * right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() * right.intValue()); + case T_long: return Constant.fromValue(left.longValue() * right.longValue()); + } + } + + return NotAConstant; + } + + public static final Constant computeConstantOperationOR(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_boolean : return Constant.fromValue(left.booleanValue() | right.booleanValue()); + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() | right.charValue()); + case T_byte: return Constant.fromValue(left.charValue() | right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() | right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() | right.intValue()); + case T_long: return Constant.fromValue(left.charValue() | right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() | right.charValue()); + case T_byte: return Constant.fromValue(left.byteValue() | right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() | right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() | right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() | right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() | right.charValue()); + case T_byte: return Constant.fromValue(left.shortValue() | right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() | right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() | right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() | right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() | right.charValue()); + case T_byte: return Constant.fromValue(left.intValue() | right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() | right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() | right.intValue()); + case T_long: return Constant.fromValue(left.intValue() | right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() | right.charValue()); + case T_byte: return Constant.fromValue(left.longValue() | right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() | right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() | right.intValue()); + case T_long: return Constant.fromValue(left.longValue() | right.longValue()); + } + + } + + return NotAConstant; + } + + public static final Constant computeConstantOperationOR_OR(Constant left, int leftId, int operator, Constant right, int rightId) { + + return Constant.fromValue(left.booleanValue() || right.booleanValue()); + } + + public static final Constant computeConstantOperationPLUS(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_Object : + if (rightId == T_String) { + return Constant.fromValue(left.stringValue() + right.stringValue()); + } + case T_boolean : + if (rightId == T_String) { + return Constant.fromValue(left.stringValue() + right.stringValue()); + } + break; + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() + right.charValue()); + case T_float: return Constant.fromValue(left.charValue() + right.floatValue()); + case T_double: return Constant.fromValue(left.charValue() + right.doubleValue()); + case T_byte: return Constant.fromValue(left.charValue() + right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() + right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() + right.intValue()); + case T_long: return Constant.fromValue(left.charValue() + right.longValue()); + case T_String: return Constant.fromValue(left.stringValue() + right.stringValue()); + } + break; + case T_float : + switch (rightId){ + case T_char : return Constant.fromValue(left.floatValue() + right.charValue()); + case T_float: return Constant.fromValue(left.floatValue() + right.floatValue()); + case T_double: return Constant.fromValue(left.floatValue() + right.doubleValue()); + case T_byte: return Constant.fromValue(left.floatValue() + right.byteValue()); + case T_short: return Constant.fromValue(left.floatValue() + right.shortValue()); + case T_int: return Constant.fromValue(left.floatValue() + right.intValue()); + case T_long: return Constant.fromValue(left.floatValue() + right.longValue()); + case T_String: return Constant.fromValue(left.stringValue() + right.stringValue()); + } + break; + case T_double : + switch (rightId){ + case T_char : return Constant.fromValue(left.doubleValue() + right.charValue()); + case T_float: return Constant.fromValue(left.doubleValue() + right.floatValue()); + case T_double: return Constant.fromValue(left.doubleValue() + right.doubleValue()); + case T_byte: return Constant.fromValue(left.doubleValue() + right.byteValue()); + case T_short: return Constant.fromValue(left.doubleValue() + right.shortValue()); + case T_int: return Constant.fromValue(left.doubleValue() + right.intValue()); + case T_long: return Constant.fromValue(left.doubleValue() + right.longValue()); + case T_String: return Constant.fromValue(left.stringValue() + right.stringValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() + right.charValue()); + case T_float: return Constant.fromValue(left.byteValue() + right.floatValue()); + case T_double: return Constant.fromValue(left.byteValue() + right.doubleValue()); + case T_byte: return Constant.fromValue(left.byteValue() + right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() + right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() + right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() + right.longValue()); + case T_String: return Constant.fromValue(left.stringValue() + right.stringValue()); + } + + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() + right.charValue()); + case T_float: return Constant.fromValue(left.shortValue() + right.floatValue()); + case T_double: return Constant.fromValue(left.shortValue() + right.doubleValue()); + case T_byte: return Constant.fromValue(left.shortValue() + right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() + right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() + right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() + right.longValue()); + case T_String: return Constant.fromValue(left.stringValue() + right.stringValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() + right.charValue()); + case T_float: return Constant.fromValue(left.intValue() + right.floatValue()); + case T_double: return Constant.fromValue(left.intValue() + right.doubleValue()); + case T_byte: return Constant.fromValue(left.intValue() + right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() + right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() + right.intValue()); + case T_long: return Constant.fromValue(left.intValue() + right.longValue()); + case T_String: return Constant.fromValue(left.stringValue() + right.stringValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() + right.charValue()); + case T_float: return Constant.fromValue(left.longValue() + right.floatValue()); + case T_double: return Constant.fromValue(left.longValue() + right.doubleValue()); + case T_byte: return Constant.fromValue(left.longValue() + right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() + right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() + right.intValue()); + case T_long: return Constant.fromValue(left.longValue() + right.longValue()); + case T_String: return Constant.fromValue(left.stringValue() + right.stringValue()); + } + break; + case T_String : + switch (rightId){ + case T_char : return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_float: return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_double: return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_byte: return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_short: return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_int: return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_long: return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_String: return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_boolean: return Constant.fromValue(left.stringValue() + right.stringValue()); + } + break; + case T_null : + switch (rightId){ + case T_char : return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_float: return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_double: return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_byte: return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_short: return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_int: return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_long: return Constant.fromValue(left.stringValue() + right.stringValue()); + case T_String: return Constant.fromValue(left.stringValue() + right.stringValue()); + } + + } + + return NotAConstant; + } + + public static final Constant computeConstantOperationREMAINDER(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() % right.charValue()); + case T_float: return Constant.fromValue(left.charValue() % right.floatValue()); + case T_double: return Constant.fromValue(left.charValue() % right.doubleValue()); + case T_byte: return Constant.fromValue(left.charValue() % right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() % right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() % right.intValue()); + case T_long: return Constant.fromValue(left.charValue() % right.longValue()); + } + break; + case T_float : + switch (rightId){ + case T_char : return Constant.fromValue(left.floatValue() % right.charValue()); + case T_float: return Constant.fromValue(left.floatValue() % right.floatValue()); + case T_double: return Constant.fromValue(left.floatValue() % right.doubleValue()); + case T_byte: return Constant.fromValue(left.floatValue() % right.byteValue()); + case T_short: return Constant.fromValue(left.floatValue() % right.shortValue()); + case T_int: return Constant.fromValue(left.floatValue() % right.intValue()); + case T_long: return Constant.fromValue(left.floatValue() % right.longValue()); + } + break; + case T_double : + switch (rightId){ + case T_char : return Constant.fromValue(left.doubleValue() % right.charValue()); + case T_float: return Constant.fromValue(left.doubleValue() % right.floatValue()); + case T_double: return Constant.fromValue(left.doubleValue() % right.doubleValue()); + case T_byte: return Constant.fromValue(left.doubleValue() % right.byteValue()); + case T_short: return Constant.fromValue(left.doubleValue() % right.shortValue()); + case T_int: return Constant.fromValue(left.doubleValue() % right.intValue()); + case T_long: return Constant.fromValue(left.doubleValue() % right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() % right.charValue()); + case T_float: return Constant.fromValue(left.byteValue() % right.floatValue()); + case T_double: return Constant.fromValue(left.byteValue() % right.doubleValue()); + case T_byte: return Constant.fromValue(left.byteValue() % right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() % right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() % right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() % right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() % right.charValue()); + case T_float: return Constant.fromValue(left.shortValue() % right.floatValue()); + case T_double: return Constant.fromValue(left.shortValue() % right.doubleValue()); + case T_byte: return Constant.fromValue(left.shortValue() % right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() % right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() % right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() % right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() % right.charValue()); + case T_float: return Constant.fromValue(left.intValue() % right.floatValue()); + case T_double: return Constant.fromValue(left.intValue() % right.doubleValue()); + case T_byte: return Constant.fromValue(left.intValue() % right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() % right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() % right.intValue()); + case T_long: return Constant.fromValue(left.intValue() % right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() % right.charValue()); + case T_float: return Constant.fromValue(left.longValue() % right.floatValue()); + case T_double: return Constant.fromValue(left.longValue() % right.doubleValue()); + case T_byte: return Constant.fromValue(left.longValue() % right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() % right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() % right.intValue()); + case T_long: return Constant.fromValue(left.longValue() % right.longValue()); + } + + } + + return NotAConstant; + } + + public static final Constant computeConstantOperationRIGHT_SHIFT(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() >> right.charValue()); + case T_byte: return Constant.fromValue(left.charValue() >> right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() >> right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() >> right.intValue()); + case T_long: return Constant.fromValue(left.charValue() >> right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() >> right.charValue()); + case T_byte: return Constant.fromValue(left.byteValue() >> right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() >> right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() >> right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() >> right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() >> right.charValue()); + case T_byte: return Constant.fromValue(left.shortValue() >> right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() >> right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() >> right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() >> right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() >> right.charValue()); + case T_byte: return Constant.fromValue(left.intValue() >> right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() >> right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() >> right.intValue()); + case T_long: return Constant.fromValue(left.intValue() >> right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() >> right.charValue()); + case T_byte: return Constant.fromValue(left.longValue() >> right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() >> right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() >> right.intValue()); + case T_long: return Constant.fromValue(left.longValue() >> right.longValue()); + } + + } + + return NotAConstant; + } + + public static final Constant computeConstantOperationUNSIGNED_RIGHT_SHIFT(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() >>> right.charValue()); + case T_byte: return Constant.fromValue(left.charValue() >>> right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() >>> right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() >>> right.intValue()); + case T_long: return Constant.fromValue(left.charValue() >>> right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() >>> right.charValue()); + case T_byte: return Constant.fromValue(left.byteValue() >>> right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() >>> right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() >>> right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() >>> right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() >>> right.charValue()); + case T_byte: return Constant.fromValue(left.shortValue() >>> right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() >>> right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() >>> right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() >>> right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() >>> right.charValue()); + case T_byte: return Constant.fromValue(left.intValue() >>> right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() >>> right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() >>> right.intValue()); + case T_long: return Constant.fromValue(left.intValue() >>> right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() >>> right.charValue()); + case T_byte: return Constant.fromValue(left.longValue() >>> right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() >>> right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() >>> right.intValue()); + case T_long: return Constant.fromValue(left.longValue() >>> right.longValue()); + } + + } + + return NotAConstant; + } + + public static final Constant computeConstantOperationXOR(Constant left, int leftId, int operator, Constant right, int rightId) { + + switch (leftId){ + case T_boolean : return Constant.fromValue(left.booleanValue() ^ right.booleanValue()); + case T_char : + switch (rightId){ + case T_char : return Constant.fromValue(left.charValue() ^ right.charValue()); + case T_byte: return Constant.fromValue(left.charValue() ^ right.byteValue()); + case T_short: return Constant.fromValue(left.charValue() ^ right.shortValue()); + case T_int: return Constant.fromValue(left.charValue() ^ right.intValue()); + case T_long: return Constant.fromValue(left.charValue() ^ right.longValue()); + } + break; + case T_byte : + switch (rightId){ + case T_char : return Constant.fromValue(left.byteValue() ^ right.charValue()); + case T_byte: return Constant.fromValue(left.byteValue() ^ right.byteValue()); + case T_short: return Constant.fromValue(left.byteValue() ^ right.shortValue()); + case T_int: return Constant.fromValue(left.byteValue() ^ right.intValue()); + case T_long: return Constant.fromValue(left.byteValue() ^ right.longValue()); + } + break; + case T_short : + switch (rightId){ + case T_char : return Constant.fromValue(left.shortValue() ^ right.charValue()); + case T_byte: return Constant.fromValue(left.shortValue() ^ right.byteValue()); + case T_short: return Constant.fromValue(left.shortValue() ^ right.shortValue()); + case T_int: return Constant.fromValue(left.shortValue() ^ right.intValue()); + case T_long: return Constant.fromValue(left.shortValue() ^ right.longValue()); + } + break; + case T_int : + switch (rightId){ + case T_char : return Constant.fromValue(left.intValue() ^ right.charValue()); + case T_byte: return Constant.fromValue(left.intValue() ^ right.byteValue()); + case T_short: return Constant.fromValue(left.intValue() ^ right.shortValue()); + case T_int: return Constant.fromValue(left.intValue() ^ right.intValue()); + case T_long: return Constant.fromValue(left.intValue() ^ right.longValue()); + } + break; + case T_long : + switch (rightId){ + case T_char : return Constant.fromValue(left.longValue() ^ right.charValue()); + case T_byte: return Constant.fromValue(left.longValue() ^ right.byteValue()); + case T_short: return Constant.fromValue(left.longValue() ^ right.shortValue()); + case T_int: return Constant.fromValue(left.longValue() ^ right.intValue()); + case T_long: return Constant.fromValue(left.longValue() ^ right.longValue()); + } + } + + return NotAConstant; + } + + public double doubleValue() { + + throw new ShouldNotImplement(Util.bind("constant.cannotCastedInto",typeName(),"double")); //$NON-NLS-2$ //$NON-NLS-1$ + } + + public float floatValue() { + + throw new ShouldNotImplement(Util.bind("constant.cannotCastedInto",typeName(),"float")); //$NON-NLS-2$ //$NON-NLS-1$ + } + +// public static Constant fromValue(byte value) { +// +// return new ByteConstant(value); +// } + +// public static Constant fromValue(char value) { +// +// return new CharConstant(value); +// } + + public static Constant fromValue(double value) { + + return new DoubleConstant(value); + } + +// public static Constant fromValue(float value) { +// +// return new FloatConstant(value); +// } + + public static Constant fromValue(int value) { + + return new IntConstant(value); + } + +// public static Constant fromValue(long value) { +// +// return new LongConstant(value); +// } + + public static Constant fromValue(String value) { + + return new StringConstant(value); + } + +// public static Constant fromValue(short value) { +// +// return new ShortConstant(value); +// } + + public static Constant fromValue(boolean value) { + + return new BooleanConstant(value); + } + + public int intValue() { + + throw new ShouldNotImplement(Util.bind("constant.cannotCastedInto",typeName(),"int")); //$NON-NLS-2$ //$NON-NLS-1$ + } + + public long longValue() { + + throw new ShouldNotImplement(Util.bind("constant.cannotCastedInto",typeName(),"long")); //$NON-NLS-2$ //$NON-NLS-1$ + } + + public short shortValue() { + + throw new ShouldNotImplement(Util.bind("constant.cannotConvertedTo",typeName(),"short")); //$NON-NLS-2$ //$NON-NLS-1$ + } + + public String stringValue() { + + throw new ShouldNotImplement(Util.bind("constant.cannotConvertedTo",typeName(),"String")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public String toString(){ + + if (this == NotAConstant) return "(Constant) NotAConstant"; //$NON-NLS-1$ + return super.toString(); } + + public abstract int typeID(); + + public String typeName() { + switch (typeID()) { + case T_int : return "int"; //$NON-NLS-1$ + case T_byte : return "byte"; //$NON-NLS-1$ + case T_short : return "short"; //$NON-NLS-1$ + case T_char : return "char"; //$NON-NLS-1$ + case T_float : return "float"; //$NON-NLS-1$ + case T_double : return "double"; //$NON-NLS-1$ + case T_boolean : return "boolean"; //$NON-NLS-1$ + case T_long : return "long";//$NON-NLS-1$ + case T_String : return "java.lang.String"; //$NON-NLS-1$ + case T_null : return "null"; //$NON-NLS-1$ + default: return "unknown"; //$NON-NLS-1$ + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/DoubleConstant.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/DoubleConstant.java new file mode 100644 index 0000000..4b23f59 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/DoubleConstant.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.impl; + +public class DoubleConstant extends Constant { + + double value; + + public DoubleConstant(double value) { + this.value = value; + } + + public byte byteValue() { + return (byte) value; + } + + public char charValue() { + return (char) value; + } + + public double doubleValue() { + return (double) value; + } + + public float floatValue() { + return (float) value; + } + + public int intValue() { + return (int) value; + } + + public long longValue() { + return (long) value; + } + + public short shortValue() { + return (short) value; + } + + public String stringValue() { + String s = Double.toString(value); + if (s == null) + return "null"; //$NON-NLS-1$ + else + return s; + } + + public String toString() { + if (this == NotAConstant) + return "(Constant) NotAConstant"; //$NON-NLS-1$ + return "(double)" + value; //$NON-NLS-1$ + } + + public int typeID() { + return T_double; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/ITypeRequestor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/ITypeRequestor.java new file mode 100644 index 0000000..31d0840 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/ITypeRequestor.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.impl; + +import net.sourceforge.phpdt.internal.compiler.env.IBinaryType; +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; +import net.sourceforge.phpdt.internal.compiler.env.ISourceType; +import net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding; + +public interface ITypeRequestor { + + /** + * Accept the resolved binary form for the requested type. + */ + void accept(IBinaryType binaryType, PackageBinding packageBinding); + + /** + * Accept the requested type's compilation unit. + */ + void accept(ICompilationUnit unit); + + /** + * Accept the unresolved source forms for the requested type. + * Note that the multiple source forms can be answered, in case the target compilation unit + * contains multiple types. The first one is then guaranteed to be the one corresponding to the + * requested type. + */ + void accept(ISourceType[] sourceType, PackageBinding packageBinding); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/IntConstant.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/IntConstant.java new file mode 100644 index 0000000..87e2e3e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/IntConstant.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.impl; + +public class IntConstant extends Constant { + + int value; + + public IntConstant(int value) { + this.value = value; + } + + public byte byteValue() { + return (byte) value; + } + + public char charValue() { + return (char) value; + } + + public double doubleValue() { + return (double) value; + } + + public float floatValue() { + return (float) value; + } + + public int intValue() { + return (int) value; + } + + public long longValue() { + return (long) value; + } + + public short shortValue() { + return (short) value; + } + + public String stringValue() { + //spec 15.17.11 + String s = new Integer(value).toString(); + if (s == null) + return "null"; //$NON-NLS-1$ + else + return s; + } + + public String toString() { + return "(int)" + value; //$NON-NLS-1$ + } + + public int typeID() { + return T_int; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/ReferenceContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/ReferenceContext.java new file mode 100644 index 0000000..54da4ed --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/ReferenceContext.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.impl; + +import net.sourceforge.phpdt.internal.compiler.CompilationResult; + +/* + * Implementors are valid compilation contexts from which we can + * escape in case of error: + * For example: method, type or compilation unit. + */ + + +public interface ReferenceContext { + void abort(int abortLevel); + CompilationResult compilationResult(); + void tagAsHavingErrors(); + boolean hasErrors(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/StringConstant.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/StringConstant.java new file mode 100644 index 0000000..d9893cf --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/impl/StringConstant.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.impl; + +public class StringConstant extends Constant { + public String value; + +public StringConstant(String value) { + this.value = value ; +} +public boolean compileTimeEqual(StringConstant right){ + //String are intermed in the compiler==>thus if two string constant + //get to be compared, it is an equal on the vale which is done + if (this.value == null) { + return right.value == null; + } + return this.value.equals(right.value); +} +public String stringValue() { + //spec 15.17.11 + + //the next line do not go into the toString() send....! + return value ; + + /* + String s = value.toString() ; + if (s == null) + return "null"; + else + return s; + */ + +} +public String toString(){ + + return "(String)\"" + value +"\""; } //$NON-NLS-2$ //$NON-NLS-1$ +public int typeID() { + return T_String; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ArrayBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ArrayBinding.java new file mode 100644 index 0000000..6ccc14b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ArrayBinding.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; + +public final class ArrayBinding extends TypeBinding { + // creation and initialization of the length field + // the declaringClass of this field is intentionally set to null so it can be distinguished. + public static final FieldBinding LengthField = new FieldBinding(LENGTH, IntBinding, AccPublic | AccFinal, null, Constant.NotAConstant); + + public TypeBinding leafComponentType; + public int dimensions; + + char[] constantPoolName; +public ArrayBinding(TypeBinding type, int dimensions) { + this.tagBits |= IsArrayType; + this.leafComponentType = type; + this.dimensions = dimensions; +} +/* Answer the receiver's constant pool name. +* +* NOTE: This method should only be used during/after code gen. +*/ + +public char[] constantPoolName() /* [Ljava/lang/Object; */ { + if (constantPoolName != null) + return constantPoolName; + + char[] brackets = new char[dimensions]; + for (int i = dimensions - 1; i >= 0; i--) + brackets[i] = '['; + return constantPoolName = CharOperation.concat(brackets, leafComponentType.signature()); +} +String debugName() { + StringBuffer brackets = new StringBuffer(dimensions * 2); + for (int i = dimensions; --i >= 0;) + brackets.append("[]"); //$NON-NLS-1$ + return leafComponentType.debugName() + brackets.toString(); +} +public int dimensions() { + return this.dimensions; +} + +/* Answer an array whose dimension size is one less than the receiver. +* +* When the receiver's dimension size is one then answer the leaf component type. +*/ + +public TypeBinding elementsType(Scope scope) { + if (dimensions == 1) + return leafComponentType; + else + return scope.createArray(leafComponentType, dimensions - 1); +} +public PackageBinding getPackage() { + return leafComponentType.getPackage(); +} +/* Answer true if the receiver type can be assigned to the argument type (right) +*/ + +public boolean isCompatibleWith(TypeBinding right) { + if (this == right) + return true; + + char[][] rightName; + if (right.isArrayType()) { + ArrayBinding rightArray = (ArrayBinding) right; + if (rightArray.leafComponentType.isBaseType()) + return false; // relying on the fact that all equal arrays are identical + if (dimensions == rightArray.dimensions) + return leafComponentType.isCompatibleWith(rightArray.leafComponentType); + if (dimensions < rightArray.dimensions) + return false; // cannot assign 'String[]' into 'Object[][]' but can assign 'byte[][]' into 'Object[]' + rightName = ((ReferenceBinding) rightArray.leafComponentType).compoundName; + } else { + if (right.isBaseType()) + return false; + rightName = ((ReferenceBinding) right).compoundName; + } + //Check dimensions - Java does not support explicitly sized dimensions for types. + //However, if it did, the type checking support would go here. + + if (CharOperation.equals(rightName, JAVA_LANG_OBJECT)) + return true; + if (CharOperation.equals(rightName, JAVA_LANG_CLONEABLE)) + return true; + if (CharOperation.equals(rightName, JAVA_IO_SERIALIZABLE)) + return true; + return false; +} + +public TypeBinding leafComponentType(){ + return leafComponentType; +} + +/* API +* Answer the problem id associated with the receiver. +* NoError if the receiver is a valid binding. +*/ + +public int problemId() { + return leafComponentType.problemId(); +} +/** +* Answer the source name for the type. +* In the case of member types, as the qualified name from its top level type. +* For example, for a member type N defined inside M & A: "A.M.N". +*/ + +public char[] qualifiedSourceName() { + char[] brackets = new char[dimensions * 2]; + for (int i = dimensions * 2 - 1; i >= 0; i -= 2) { + brackets[i] = ']'; + brackets[i - 1] = '['; + } + return CharOperation.concat(leafComponentType.qualifiedSourceName(), brackets); +} +public char[] readableName() /* java.lang.Object[] */ { + char[] brackets = new char[dimensions * 2]; + for (int i = dimensions * 2 - 1; i >= 0; i -= 2) { + brackets[i] = ']'; + brackets[i - 1] = '['; + } + return CharOperation.concat(leafComponentType.readableName(), brackets); +} +public char[] shortReadableName(){ + char[] brackets = new char[dimensions * 2]; + for (int i = dimensions * 2 - 1; i >= 0; i -= 2) { + brackets[i] = ']'; + brackets[i - 1] = '['; + } + return CharOperation.concat(leafComponentType.shortReadableName(), brackets); +} +public char[] sourceName() { + char[] brackets = new char[dimensions * 2]; + for (int i = dimensions * 2 - 1; i >= 0; i -= 2) { + brackets[i] = ']'; + brackets[i - 1] = '['; + } + return CharOperation.concat(leafComponentType.sourceName(), brackets); +} +public String toString() { + return leafComponentType != null ? debugName() : "NULL TYPE ARRAY"; //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BaseTypeBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BaseTypeBinding.java new file mode 100644 index 0000000..2115b38 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BaseTypeBinding.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +public final class BaseTypeBinding extends TypeBinding { + public char[] simpleName; + private char [] constantPoolName; +BaseTypeBinding(int id, char[] name, char[] constantPoolName) { + this.tagBits |= IsBaseType; + this.id = id; + this.simpleName = name; + this.constantPoolName = constantPoolName; +} +/* Answer the receiver's constant pool name. +*/ + +public char[] constantPoolName() { + return constantPoolName; +} +public PackageBinding getPackage() { + return null; +} +/* Answer true if the receiver type can be assigned to the argument type (right) +*/ + +public final boolean isCompatibleWith(TypeBinding right) { + if (this == right) + return true; + if (!right.isBaseType()) + return this == NullBinding; + + switch (right.id) { + case T_boolean : + case T_byte : + case T_char : + return false; + case T_double : + switch (id) { + case T_byte : + case T_char : + case T_short : + case T_int : + case T_long : + case T_float : + return true; + default : + return false; + } + case T_float : + switch (id) { + case T_byte : + case T_char : + case T_short : + case T_int : + case T_long : + return true; + default : + return false; + } + case T_long : + switch (id) { + case T_byte : + case T_char : + case T_short : + case T_int : + return true; + default : + return false; + } + case T_int : + switch (id) { + case T_byte : + case T_char : + case T_short : + return true; + default : + return false; + } + case T_short : + return (id == T_byte); + } + return false; +} +public static final boolean isNarrowing(int left, int right) { + //can "left" store a "right" using some narrowing conversion + //(is left smaller than right) + + switch (left) { + case T_boolean : + return right == T_boolean; + case T_char : + case T_byte : + if (right == T_byte) return true; + case T_short : + if (right == T_short) return true; + if (right == T_char) return true; + case T_int : + if (right == T_int) return true; + case T_long : + if (right == T_long) return true; + case T_float : + if (right == T_float) return true; + case T_double : + if (right == T_double) return true; + default : + return false; + } +} +public static final boolean isWidening(int left, int right) { + //can "left" store a "right" using some widening conversion + //(is left "bigger" than right) + + switch (left) { + case T_boolean : + return right == T_boolean; + case T_char : + return right == T_char; + case T_double : + if (right == T_double) return true; + case T_float : + if (right == T_float) return true; + case T_long : + if (right == T_long) return true; + case T_int : + if (right == T_int) return true; + if (right == T_char) return true; + case T_short : + if (right == T_short) return true; + case T_byte : + if (right == T_byte) return true; + default : + return false; + } +} +public char[] qualifiedSourceName() { + return simpleName; +} +public char[] readableName() { + return simpleName; +} +public char[] shortReadableName(){ + return simpleName; +} +public char[] sourceName() { + return simpleName; +} +public String toString() { + return new String(constantPoolName) + " (id=" + id + ")"; //$NON-NLS-1$ //$NON-NLS-2$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BaseTypes.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BaseTypes.java new file mode 100644 index 0000000..209ae95 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BaseTypes.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +public interface BaseTypes { + final BaseTypeBinding IntBinding = new BaseTypeBinding(TypeIds.T_int, "int".toCharArray(), new char[] {'I'}); //$NON-NLS-1$ + final BaseTypeBinding ByteBinding = new BaseTypeBinding(TypeIds.T_byte, "byte".toCharArray(), new char[] {'B'}); //$NON-NLS-1$ + final BaseTypeBinding ShortBinding = new BaseTypeBinding(TypeIds.T_short, "short".toCharArray(), new char[] {'S'}); //$NON-NLS-1$ + final BaseTypeBinding CharBinding = new BaseTypeBinding(TypeIds.T_char, "char".toCharArray(), new char[] {'C'}); //$NON-NLS-1$ + final BaseTypeBinding LongBinding = new BaseTypeBinding(TypeIds.T_long, "long".toCharArray(), new char[] {'J'}); //$NON-NLS-1$ + final BaseTypeBinding FloatBinding = new BaseTypeBinding(TypeIds.T_float, "float".toCharArray(), new char[] {'F'}); //$NON-NLS-1$ + final BaseTypeBinding DoubleBinding = new BaseTypeBinding(TypeIds.T_double, "double".toCharArray(), new char[] {'D'}); //$NON-NLS-1$ + final BaseTypeBinding BooleanBinding = new BaseTypeBinding(TypeIds.T_boolean, "boolean".toCharArray(), new char[] {'Z'}); //$NON-NLS-1$ + final BaseTypeBinding NullBinding = new BaseTypeBinding(TypeIds.T_null, "null".toCharArray(), new char[] {'N'}); //N stands for null even if it is never internally used //$NON-NLS-1$ + final BaseTypeBinding VoidBinding = new BaseTypeBinding(TypeIds.T_void, "void".toCharArray(), new char[] {'V'}); //$NON-NLS-1$ +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BinaryTypeBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BinaryTypeBinding.java new file mode 100644 index 0000000..b9dafb5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BinaryTypeBinding.java @@ -0,0 +1,507 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.env.IBinaryField; +import net.sourceforge.phpdt.internal.compiler.env.IBinaryMethod; +import net.sourceforge.phpdt.internal.compiler.env.IBinaryNestedType; +import net.sourceforge.phpdt.internal.compiler.env.IBinaryType; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; +import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration; + +/* +Not all fields defined by this type are initialized when it is created. +Some are initialized only when needed. + +Accessors have been provided for some public fields so all TypeBindings have the same API... +but access public fields directly whenever possible. +Non-public fields have accessors which should be used everywhere you expect the field to be initialized. + +null is NOT a valid value for a non-public field... it just means the field is not initialized. +*/ + +public final class BinaryTypeBinding extends ReferenceBinding { + // all of these fields are ONLY guaranteed to be initialized if accessed using their public accessor method + private ReferenceBinding superclass; + private ReferenceBinding enclosingType; + private ReferenceBinding[] superInterfaces; + private FieldBinding[] fields; + private MethodBinding[] methods; + private ReferenceBinding[] memberTypes; + + // For the link with the principle structure + private LookupEnvironment environment; +public BinaryTypeBinding(PackageBinding packageBinding, IBinaryType binaryType, LookupEnvironment environment) { + this.compoundName = CharOperation.splitOn('/', binaryType.getName()); + computeId(); + + this.tagBits |= IsBinaryBinding; + this.environment = environment; + this.fPackage = packageBinding; + this. fileName = binaryType.getFileName(); + + // source name must be one name without "$". + char[] possibleSourceName = this.compoundName[this.compoundName.length - 1]; + int start = CharOperation.lastIndexOf('$', possibleSourceName) + 1; + if (start == 0) { + this.sourceName = possibleSourceName; + } else { + this.sourceName = new char[possibleSourceName.length - start]; + System.arraycopy(possibleSourceName, start, this.sourceName, 0, this.sourceName.length); + } + + this.modifiers = binaryType.getModifiers(); + if (binaryType.isInterface()) + this.modifiers |= AccInterface; +} + +public FieldBinding[] availableFields() { + FieldBinding[] availableFields = new FieldBinding[fields.length]; + int count = 0; + + for (int i = 0; i < fields.length;i++) { + try { + availableFields[count] = resolveTypeFor(fields[i]); + count++; + } catch (AbortCompilation a){ + } + } + + System.arraycopy(availableFields, 0, availableFields = new FieldBinding[count], 0, count); + return availableFields; +} + +public MethodBinding[] availableMethods() { + if ((modifiers & AccUnresolved) == 0) + return methods; + + MethodBinding[] availableMethods = new MethodBinding[methods.length]; + int count = 0; + + for (int i = 0; i < methods.length;i++) { + try { + availableMethods[count] = resolveTypesFor(methods[i]); + count++; + } catch (AbortCompilation a){ + } + } + System.arraycopy(availableMethods, 0, availableMethods = new MethodBinding[count], 0, count); + return availableMethods; +} + +void cachePartsFrom(IBinaryType binaryType, boolean needFieldsAndMethods) { + char[] superclassName = binaryType.getSuperclassName(); + if (superclassName != null) + // attempt to find the superclass if it exists in the cache (otherwise - resolve it when requested) + this.superclass = environment.getTypeFromConstantPoolName(superclassName, 0, -1); + + char[] enclosingTypeName = binaryType.getEnclosingTypeName(); + if (enclosingTypeName != null) { + // attempt to find the enclosing type if it exists in the cache (otherwise - resolve it when requested) + this.enclosingType = environment.getTypeFromConstantPoolName(enclosingTypeName, 0, -1); + this.tagBits |= MemberTypeMask; // must be a member type not a top-level or local type +// if (this.enclosingType().isStrictfp()) +// this.modifiers |= AccStrictfp; + if (this.enclosingType().isDeprecated()) + this.modifiers |= AccDeprecatedImplicitly; + } + + this.memberTypes = NoMemberTypes; + IBinaryNestedType[] memberTypeStructures = binaryType.getMemberTypes(); + if (memberTypeStructures != null) { + int size = memberTypeStructures.length; + if (size > 0) { + this.memberTypes = new ReferenceBinding[size]; + for (int i = 0; i < size; i++) + // attempt to find each member type if it exists in the cache (otherwise - resolve it when requested) + this.memberTypes[i] = environment.getTypeFromConstantPoolName(memberTypeStructures[i].getName(), 0, -1); + } + } + + this.superInterfaces = NoSuperInterfaces; + char[][] interfaceNames = binaryType.getInterfaceNames(); + if (interfaceNames != null) { + int size = interfaceNames.length; + if (size > 0) { + this.superInterfaces = new ReferenceBinding[size]; + for (int i = 0; i < size; i++) + // attempt to find each superinterface if it exists in the cache (otherwise - resolve it when requested) + this.superInterfaces[i] = environment.getTypeFromConstantPoolName(interfaceNames[i], 0, -1); + } + } + if (needFieldsAndMethods){ + createFields(binaryType.getFields()); + createMethods(binaryType.getMethods()); + } +} +private void createFields(IBinaryField[] iFields) { + this.fields = NoFields; + if (iFields != null) { + int size = iFields.length; + if (size > 0) { + this.fields = new FieldBinding[size]; + for (int i = 0; i < size; i++) { + IBinaryField field = iFields[i]; + this.fields[i] = + new FieldBinding( + field.getName(), + environment.getTypeFromSignature(field.getTypeName(), 0, -1), + field.getModifiers(), + this, + field.getConstant()); + } + } + } +} +private MethodBinding createMethod(IBinaryMethod method) { + int modifiers = method.getModifiers() | AccUnresolved; + + ReferenceBinding[] exceptions = NoExceptions; + char[][] exceptionTypes = method.getExceptionTypeNames(); + if (exceptionTypes != null) { + int size = exceptionTypes.length; + if (size > 0) { + exceptions = new ReferenceBinding[size]; + for (int i = 0; i < size; i++) + exceptions[i] = environment.getTypeFromConstantPoolName(exceptionTypes[i], 0, -1); + } + } + + TypeBinding[] parameters = NoParameters; + char[] signature = method.getMethodDescriptor(); // of the form (I[Ljava/jang/String;)V + int numOfParams = 0; + char nextChar; + int index = 0; // first character is always '(' so skip it + while ((nextChar = signature[++index]) != ')') { + if (nextChar != '[') { + numOfParams++; + if (nextChar == 'L') + while ((nextChar = signature[++index]) != ';'); + } + } + + // Ignore synthetic argument for member types. + int startIndex = (method.isConstructor() && isMemberType() && !isStatic()) ? 1 : 0; + int size = numOfParams - startIndex; + if (size > 0) { + parameters = new TypeBinding[size]; + index = 1; + int end = 0; // first character is always '(' so skip it + for (int i = 0; i < numOfParams; i++) { + while ((nextChar = signature[++end]) == '['); + if (nextChar == 'L') + while ((nextChar = signature[++end]) != ';'); + + if (i >= startIndex) // skip the synthetic arg if necessary + parameters[i - startIndex] = environment.getTypeFromSignature(signature, index, end); + index = end + 1; + } + } + + MethodBinding binding = null; + if (method.isConstructor()) + binding = new MethodBinding(modifiers, parameters, exceptions, this); + else + binding = new MethodBinding( + modifiers, + method.getSelector(), + environment.getTypeFromSignature(signature, index + 1, -1), // index is currently pointing at the ')' + parameters, + exceptions, + this); + return binding; +} +/** + * Create method bindings for binary type, filtering out and synthetics + */ +private void createMethods(IBinaryMethod[] iMethods) { + int total = 0, initialTotal = 0, iClinit = -1; + int[] toSkip = null; + if (iMethods != null) { + total = initialTotal = iMethods.length; + for (int i = total; --i >= 0;) { + IBinaryMethod method = iMethods[i]; +// if ((method.getModifiers() & AccSynthetic) != 0) { +// // discard synthetics methods +// if (toSkip == null) toSkip = new int[iMethods.length]; +// toSkip[i] = -1; +// total--; +// } else + if (iClinit == -1) { + char[] methodName = method.getSelector(); + if (methodName.length == 8 && methodName[0] == '<') { + // discard + iClinit = i; + total--; + } + } + } + } + if (total == 0) { + this.methods = NoMethods; + return; + } + + this.methods = new MethodBinding[total]; + if (total == initialTotal) { + for (int i = 0; i < initialTotal; i++) + this.methods[i] = createMethod(iMethods[i]); + } else { + for (int i = 0, index = 0; i < initialTotal; i++) + if (iClinit != i && (toSkip == null || toSkip[i] != -1)) + this.methods[index++] = createMethod(iMethods[i]); + } + modifiers |= AccUnresolved; // until methods() is sent +} +/* Answer the receiver's enclosing type... null if the receiver is a top level type. +* +* NOTE: enclosingType of a binary type is resolved when needed +*/ + +public ReferenceBinding enclosingType() { + if (enclosingType == null) + return null; + if (enclosingType instanceof UnresolvedReferenceBinding) + enclosingType = ((UnresolvedReferenceBinding) enclosingType).resolve(environment); + return enclosingType; +} +// NOTE: the type of each field of a binary type is resolved when needed + +public FieldBinding[] fields() { + for (int i = fields.length; --i >= 0;) + resolveTypeFor(fields[i]); + return fields; +} +// NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed + +public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) { + int argCount = argumentTypes.length; + nextMethod : for (int m = methods.length; --m >= 0;) { + MethodBinding method = methods[m]; + if (method.selector == ConstructorDeclaration.ConstantPoolName && method.parameters.length == argCount) { + resolveTypesFor(method); + TypeBinding[] toMatch = method.parameters; + for (int p = 0; p < argCount; p++) + if (toMatch[p] != argumentTypes[p]) + continue nextMethod; + return method; + } + } + return null; +} +// NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed +// searches up the hierarchy as long as no potential (but not exact) match was found. + +public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes) { + int argCount = argumentTypes.length; + int selectorLength = selector.length; + boolean foundNothing = true; + nextMethod : for (int m = methods.length; --m >= 0;) { + MethodBinding method = methods[m]; + if (method.selector.length == selectorLength && CharOperation.prefixEquals(method.selector, selector)) { + foundNothing = false; // inner type lookups must know that a method with this name exists + if (method.parameters.length == argCount) { + resolveTypesFor(method); + TypeBinding[] toMatch = method.parameters; + for (int p = 0; p < argCount; p++) + if (toMatch[p] != argumentTypes[p]) + continue nextMethod; + return method; + } + } + } + + if (foundNothing) { + if (isInterface()) { + if (superInterfaces.length == 1) + return superInterfaces[0].getExactMethod(selector, argumentTypes); + } else if (superclass != null) { + return superclass.getExactMethod(selector, argumentTypes); + } + } + return null; +} +// NOTE: the type of a field of a binary type is resolved when needed + +public FieldBinding getField(char[] fieldName) { + int fieldLength = fieldName.length; + for (int f = fields.length; --f >= 0;) { + char[] name = fields[f].name; + if (name.length == fieldLength && CharOperation.prefixEquals(name, fieldName)) + return resolveTypeFor(fields[f]); + } + return null; +} +// NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed + +public MethodBinding[] getMethods(char[] selector) { + int count = 0; + int lastIndex = -1; + int selectorLength = selector.length; + for (int m = 0, length = methods.length; m < length; m++) { + MethodBinding method = methods[m]; + if (method.selector.length == selectorLength && CharOperation.prefixEquals(method.selector, selector)) { + resolveTypesFor(method); + count++; + lastIndex = m; + } + } + if (count == 1) + return new MethodBinding[] {methods[lastIndex]}; + if (count > 0) { + MethodBinding[] result = new MethodBinding[count]; + count = 0; + for (int m = 0; m <= lastIndex; m++) { + MethodBinding method = methods[m]; + if (method.selector.length == selectorLength && CharOperation.prefixEquals(method.selector, selector)) + result[count++] = method; + } + return result; + } + return NoMethods; +} +// NOTE: member types of binary types are resolved when needed + +public ReferenceBinding[] memberTypes() { + for (int i = memberTypes.length; --i >= 0;) + if (memberTypes[i] instanceof UnresolvedReferenceBinding) + memberTypes[i] = ((UnresolvedReferenceBinding) memberTypes[i]).resolve(environment); + return memberTypes; +} +// NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed + +public MethodBinding[] methods() { + if ((modifiers & AccUnresolved) == 0) + return methods; + + for (int i = methods.length; --i >= 0;) + resolveTypesFor(methods[i]); + modifiers ^= AccUnresolved; + return methods; +} +private TypeBinding resolveType(TypeBinding type) { + if (type instanceof UnresolvedReferenceBinding) + return ((UnresolvedReferenceBinding) type).resolve(environment); + if (type instanceof ArrayBinding) { + ArrayBinding array = (ArrayBinding) type; + if (array.leafComponentType instanceof UnresolvedReferenceBinding) + array.leafComponentType = ((UnresolvedReferenceBinding) array.leafComponentType).resolve(environment); + } + return type; +} +private FieldBinding resolveTypeFor(FieldBinding field) { + field.type = resolveType(field.type); + return field; +} +private MethodBinding resolveTypesFor(MethodBinding method) { + if ((method.modifiers & AccUnresolved) == 0) + return method; + + if (!method.isConstructor()) + method.returnType = resolveType(method.returnType); + for (int i = method.parameters.length; --i >= 0;) + method.parameters[i] = resolveType(method.parameters[i]); + for (int i = method.thrownExceptions.length; --i >= 0;) + if (method.thrownExceptions[i] instanceof UnresolvedReferenceBinding) + method.thrownExceptions[i] = ((UnresolvedReferenceBinding) method.thrownExceptions[i]).resolve(environment); + method.modifiers ^= AccUnresolved; + return method; +} +/* Answer the receiver's superclass... null if the receiver is Object or an interface. +* +* NOTE: superclass of a binary type is resolved when needed +*/ + +public ReferenceBinding superclass() { + if (superclass == null) + return null; + if (superclass instanceof UnresolvedReferenceBinding) + superclass = ((UnresolvedReferenceBinding) superclass).resolve(environment); + return superclass; +} +// NOTE: superInterfaces of binary types are resolved when needed + +public ReferenceBinding[] superInterfaces() { + for (int i = superInterfaces.length; --i >= 0;) + if (superInterfaces[i] instanceof UnresolvedReferenceBinding) + superInterfaces[i] = ((UnresolvedReferenceBinding) superInterfaces[i]).resolve(environment); + return superInterfaces; +} +public String toString() { + String s = ""; //$NON-NLS-1$ + + if (isDeprecated()) s += "deprecated "; //$NON-NLS-1$ + if (isPublic()) s += "public "; //$NON-NLS-1$ + if (isProtected()) s += "protected "; //$NON-NLS-1$ + if (isPrivate()) s += "private "; //$NON-NLS-1$ + if (isAbstract() && isClass()) s += "abstract "; //$NON-NLS-1$ + if (isStatic() && isNestedType()) s += "static "; //$NON-NLS-1$ + if (isFinal()) s += "final "; //$NON-NLS-1$ + + s += isInterface() ? "interface " : "class "; //$NON-NLS-1$ //$NON-NLS-2$ + s += (compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED TYPE"; //$NON-NLS-1$ + + s += "\n\textends "; //$NON-NLS-1$ + s += (superclass != null) ? superclass.debugName() : "NULL TYPE"; //$NON-NLS-1$ + + if (superInterfaces != null) { + if (superInterfaces != NoSuperInterfaces) { + s += "\n\timplements : "; //$NON-NLS-1$ + for (int i = 0, length = superInterfaces.length; i < length; i++) { + if (i > 0) + s += ", "; //$NON-NLS-1$ + s += (superInterfaces[i] != null) ? superInterfaces[i].debugName() : "NULL TYPE"; //$NON-NLS-1$ + } + } + } else { + s += "NULL SUPERINTERFACES"; //$NON-NLS-1$ + } + + if (enclosingType != null) { + s += "\n\tenclosing type : "; //$NON-NLS-1$ + s += enclosingType.debugName(); + } + + if (fields != null) { + if (fields != NoFields) { + s += "\n/* fields */"; //$NON-NLS-1$ + for (int i = 0, length = fields.length; i < length; i++) + s += (fields[i] != null) ? "\n" + fields[i].toString() : "\nNULL FIELD"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } else { + s += "NULL FIELDS"; //$NON-NLS-1$ + } + + if (methods != null) { + if (methods != NoMethods) { + s += "\n/* methods */"; //$NON-NLS-1$ + for (int i = 0, length = methods.length; i < length; i++) + s += (methods[i] != null) ? "\n" + methods[i].toString() : "\nNULL METHOD"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } else { + s += "NULL METHODS"; //$NON-NLS-1$ + } + + if (memberTypes != null) { + if (memberTypes != NoMemberTypes) { + s += "\n/* members */"; //$NON-NLS-1$ + for (int i = 0, length = memberTypes.length; i < length; i++) + s += (memberTypes[i] != null) ? "\n" + memberTypes[i].toString() : "\nNULL TYPE"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } else { + s += "NULL MEMBER TYPES"; //$NON-NLS-1$ + } + + s += "\n\n\n"; //$NON-NLS-1$ + return s; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/Binding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/Binding.java new file mode 100644 index 0000000..c446988 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/Binding.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +public abstract class Binding implements BindingIds, CompilerModifiers, ProblemReasons { + /* API + * Answer the receiver's binding type from Binding.BindingID. + * + * Note: Do NOT expect this to be used very often... only in switch statements with + * more than 2 possible choices. + */ + public abstract int bindingType(); + /* API + * Answer true if the receiver is not a problem binding + */ + + public final boolean isValidBinding() { + return problemId() == NoError; + } + /* API + * Answer the problem id associated with the receiver. + * NoError if the receiver is a valid binding. + */ + + public int problemId() { + return NoError; + } + /* Answer a printable representation of the receiver. + */ + public abstract char[] readableName(); + + /* Shorter printable representation of the receiver (no qualified type) + */ + public char[] shortReadableName(){ + return readableName(); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BindingIds.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BindingIds.java new file mode 100644 index 0000000..e55c779 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BindingIds.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +public interface BindingIds { + final int FIELD = 1; + final int LOCAL = 2; + final int VARIABLE = FIELD | LOCAL; + final int TYPE = 4; + final int METHOD = 8; + final int PACKAGE = 16; + final int IMPORT = 32; +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BlockScope.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BlockScope.java new file mode 100644 index 0000000..35c9d53 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/BlockScope.java @@ -0,0 +1,1323 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; +import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.Argument; +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; +import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; + +public class BlockScope extends Scope { + + // Local variable management + public LocalVariableBinding[] locals; + public int localIndex; // position for next variable + public int startIndex; // start position in this scope - for ordering scopes vs. variables + public int offset; // for variable allocation throughout scopes + public int maxOffset; // for variable allocation throughout scopes + + // finally scopes must be shifted behind respective try&catch scope(s) so as to avoid + // collisions of secret variables (return address, save value). + public BlockScope[] shiftScopes; + + public final static VariableBinding[] EmulationPathToImplicitThis = {}; + public final static VariableBinding[] NoEnclosingInstanceInConstructorCall = {}; + public final static VariableBinding[] NoEnclosingInstanceInStaticContext = {}; + + public Scope[] subscopes = new Scope[1]; // need access from code assist + public int scopeIndex = 0; // need access from code assist + + protected BlockScope(int kind, Scope parent) { + + super(kind, parent); + } + + public BlockScope(BlockScope parent) { + + this(parent, true); + } + + public BlockScope(BlockScope parent, boolean addToParentScope) { + + this(BLOCK_SCOPE, parent); + locals = new LocalVariableBinding[5]; + if (addToParentScope) parent.addSubscope(this); + this.startIndex = parent.localIndex; + } + + public BlockScope(BlockScope parent, int variableCount) { + + this(BLOCK_SCOPE, parent); + locals = new LocalVariableBinding[variableCount]; + parent.addSubscope(this); + this.startIndex = parent.localIndex; + } + + /* Create the class scope & binding for the anonymous type. + */ + public final void addAnonymousType( + TypeDeclaration anonymousType, + ReferenceBinding superBinding) { + + ClassScope anonymousClassScope = new ClassScope(this, anonymousType); + anonymousClassScope.buildAnonymousTypeBinding( + enclosingSourceType(), + superBinding); + } + + /* Create the class scope & binding for the local type. + */ + public final void addLocalType(TypeDeclaration localType) { + + // check that the localType does not conflict with an enclosing type + ReferenceBinding type = enclosingSourceType(); + do { + if (CharOperation.equals(type.sourceName, localType.name)) { + problemReporter().hidingEnclosingType(localType); + return; + } + type = type.enclosingType(); + } while (type != null); + + // check that the localType does not conflict with another sibling local type + Scope scope = this; + do { + if (((BlockScope) scope).findLocalType(localType.name) != null) { + problemReporter().duplicateNestedType(localType); + return; + } + } while ((scope = scope.parent) instanceof BlockScope); + + ClassScope localTypeScope = new ClassScope(this, localType); + addSubscope(localTypeScope); + localTypeScope.buildLocalTypeBinding(enclosingSourceType()); + } + + /* Insert a local variable into a given scope, updating its position + * and checking there are not too many locals or arguments allocated. + */ + public final void addLocalVariable(LocalVariableBinding binding) { + + checkAndSetModifiersForVariable(binding); + + // insert local in scope + if (localIndex == locals.length) + System.arraycopy( + locals, + 0, + (locals = new LocalVariableBinding[localIndex * 2]), + 0, + localIndex); + locals[localIndex++] = binding; + + // update local variable binding + binding.declaringScope = this; + binding.id = this.outerMostMethodScope().analysisIndex++; + // share the outermost method scope analysisIndex + } + + public void addSubscope(Scope childScope) { + if (scopeIndex == subscopes.length) + System.arraycopy( + subscopes, + 0, + (subscopes = new Scope[scopeIndex * 2]), + 0, + scopeIndex); + subscopes[scopeIndex++] = childScope; + } + + /* Answer true if the receiver is suitable for assigning final blank fields. + * + * in other words, it is inside an initializer, a constructor or a clinit + */ + public final boolean allowBlankFinalFieldAssignment(FieldBinding binding) { + + if (enclosingSourceType() != binding.declaringClass) + return false; + + MethodScope methodScope = methodScope(); + if (methodScope.isStatic != binding.isStatic()) + return false; + return methodScope.isInsideInitializer() // inside initializer + || ((AbstractMethodDeclaration) methodScope.referenceContext) + .isInitializationMethod(); // inside constructor or clinit + } + String basicToString(int tab) { + String newLine = "\n"; //$NON-NLS-1$ + for (int i = tab; --i >= 0;) + newLine += "\t"; //$NON-NLS-1$ + + String s = newLine + "--- Block Scope ---"; //$NON-NLS-1$ + newLine += "\t"; //$NON-NLS-1$ + s += newLine + "locals:"; //$NON-NLS-1$ + for (int i = 0; i < localIndex; i++) + s += newLine + "\t" + locals[i].toString(); //$NON-NLS-1$ + s += newLine + "startIndex = " + startIndex; //$NON-NLS-1$ + return s; + } + + private void checkAndSetModifiersForVariable(LocalVariableBinding varBinding) { + + int modifiers = varBinding.modifiers; + if ((modifiers & AccAlternateModifierProblem) != 0 && varBinding.declaration != null){ + problemReporter().duplicateModifierForVariable(varBinding.declaration, this instanceof MethodScope); + } + int realModifiers = modifiers & AccJustFlag; + + int unexpectedModifiers = ~AccFinal; + if ((realModifiers & unexpectedModifiers) != 0 && varBinding.declaration != null){ + problemReporter().illegalModifierForVariable(varBinding.declaration, this instanceof MethodScope); + } + varBinding.modifiers = modifiers; + } + + /* Compute variable positions in scopes given an initial position offset + * ignoring unused local variables. + * + * No argument is expected here (ilocal is the first non-argument local of the outermost scope) + * Arguments are managed by the MethodScope method + */ +// void computeLocalVariablePositions(int ilocal, int initOffset, CodeStream codeStream) { +// +// this.offset = initOffset; +// this.maxOffset = initOffset; +// +// // local variable init +// int maxLocals = this.localIndex; +// boolean hasMoreVariables = ilocal < maxLocals; +// +// // scope init +// int iscope = 0, maxScopes = this.scopeIndex; +// boolean hasMoreScopes = maxScopes > 0; +// +// // iterate scopes and variables in parallel +// while (hasMoreVariables || hasMoreScopes) { +// if (hasMoreScopes +// && (!hasMoreVariables || (subscopes[iscope].startIndex() <= ilocal))) { +// // consider subscope first +// if (subscopes[iscope] instanceof BlockScope) { +// BlockScope subscope = (BlockScope) subscopes[iscope]; +// int subOffset = subscope.shiftScopes == null ? this.offset : subscope.maxShiftedOffset(); +// subscope.computeLocalVariablePositions(0, subOffset, codeStream); +// if (subscope.maxOffset > this.maxOffset) +// this.maxOffset = subscope.maxOffset; +// } +// hasMoreScopes = ++iscope < maxScopes; +// } else { +// +// // consider variable first +// LocalVariableBinding local = locals[ilocal]; // if no local at all, will be locals[ilocal]==null +// +// // check if variable is actually used, and may force it to be preserved +// boolean generateCurrentLocalVar = (local.useFlag == LocalVariableBinding.USED && (local.constant == Constant.NotAConstant)); +// +// // do not report fake used variable +// if (local.useFlag == LocalVariableBinding.UNUSED +// && (local.declaration != null) // unused (and non secret) local +// && ((local.declaration.bits & AstNode.IsLocalDeclarationReachableMASK) != 0)) { // declaration is reachable +// +// if (!(local.declaration instanceof Argument)) // do not report unused catch arguments +// this.problemReporter().unusedLocalVariable(local.declaration); +// } +// +// // could be optimized out, but does need to preserve unread variables ? +//// if (!generateCurrentLocalVar) { +//// if (local.declaration != null && environment().options.preserveAllLocalVariables) { +//// generateCurrentLocalVar = true; // force it to be preserved in the generated code +//// local.useFlag = LocalVariableBinding.USED; +//// } +//// } +// +// // allocate variable +// if (generateCurrentLocalVar) { +// +// if (local.declaration != null) { +// codeStream.record(local); // record user-defined local variables for attribute generation +// } +// // assign variable position +// local.resolvedPosition = this.offset; +// +// if ((local.type == LongBinding) || (local.type == DoubleBinding)) { +// this.offset += 2; +// } else { +// this.offset++; +// } +// if (this.offset > 0xFFFF) { // no more than 65535 words of locals +// this.problemReporter().noMoreAvailableSpaceForLocal( +// local, +// local.declaration == null ? (AstNode)this.methodScope().referenceContext : local.declaration); +// } +// } else { +// local.resolvedPosition = -1; // not generated +// } +// hasMoreVariables = ++ilocal < maxLocals; +// } +// } +// if (this.offset > this.maxOffset) +// this.maxOffset = this.offset; +// } + + /* Answer true if the variable name already exists within the receiver's scope. + */ + public final LocalVariableBinding duplicateName(char[] name) { + for (int i = 0; i < localIndex; i++) + if (CharOperation.equals(name, locals[i].name)) + return locals[i]; + + if (this instanceof MethodScope) + return null; + else + return ((BlockScope) parent).duplicateName(name); + } + + /* + * Record the suitable binding denoting a synthetic field or constructor argument, + * mapping to the actual outer local variable in the scope context. + * Note that this may not need any effect, in case the outer local variable does not + * need to be emulated and can directly be used as is (using its back pointer to its + * declaring scope). + */ + public void emulateOuterAccess(LocalVariableBinding outerLocalVariable) { + + MethodScope currentMethodScope; + if ((currentMethodScope = this.methodScope()) + != outerLocalVariable.declaringScope.methodScope()) { + NestedTypeBinding currentType = (NestedTypeBinding) this.enclosingSourceType(); + + //do nothing for member types, pre emulation was performed already + if (!currentType.isLocalType()) { + return; + } + // must also add a synthetic field if we're not inside a constructor + if (!currentMethodScope.isInsideInitializerOrConstructor()) { + currentType.addSyntheticArgumentAndField(outerLocalVariable); + } else { + currentType.addSyntheticArgument(outerLocalVariable); + } + } + } + + /* Note that it must never produce a direct access to the targetEnclosingType, + * but instead a field sequence (this$2.this$1.this$0) so as to handle such a test case: + * + * class XX { + * void foo() { + * class A { + * class B { + * class C { + * boolean foo() { + * return (Object) A.this == (Object) B.this; + * } + * } + * } + * } + * new A().new B().new C(); + * } + * } + * where we only want to deal with ONE enclosing instance for C (could not figure out an A for C) + */ + public final ReferenceBinding findLocalType(char[] name) { + + for (int i = 0, length = scopeIndex; i < length; i++) { + if (subscopes[i] instanceof ClassScope) { + SourceTypeBinding sourceType = + ((ClassScope) subscopes[i]).referenceContext.binding; + if (CharOperation.equals(sourceType.sourceName(), name)) + return sourceType; + } + } + return null; + } + + public LocalVariableBinding findVariable(char[] variable) { + + int variableLength = variable.length; + for (int i = 0, length = locals.length; i < length; i++) { + LocalVariableBinding local = locals[i]; + if (local == null) + return null; + if (local.name.length == variableLength + && CharOperation.prefixEquals(local.name, variable)) + return local; + } + return null; + } + /* API + * flag is a mask of the following values VARIABLE (= FIELD or LOCAL), TYPE. + * Only bindings corresponding to the mask will be answered. + * + * if the VARIABLE mask is set then + * If the first name provided is a field (or local) then the field (or local) is answered + * Otherwise, package names and type names are consumed until a field is found. + * In this case, the field is answered. + * + * if the TYPE mask is set, + * package names and type names are consumed until the end of the input. + * Only if all of the input is consumed is the type answered + * + * All other conditions are errors, and a problem binding is returned. + * + * NOTE: If a problem binding is returned, senders should extract the compound name + * from the binding & not assume the problem applies to the entire compoundName. + * + * The VARIABLE mask has precedence over the TYPE mask. + * + * InvocationSite implements + * isSuperAccess(); this is used to determine if the discovered field is visible. + * setFieldIndex(int); this is used to record the number of names that were consumed. + * + * For example, getBinding({"foo","y","q", VARIABLE, site) will answer + * the binding for the field or local named "foo" (or an error binding if none exists). + * In addition, setFieldIndex(1) will be sent to the invocation site. + * If a type named "foo" exists, it will not be detected (and an error binding will be answered) + * + * IMPORTANT NOTE: This method is written under the assumption that compoundName is longer than length 1. + */ + public Binding getBinding(char[][] compoundName, int mask, InvocationSite invocationSite) { + + Binding binding = getBinding(compoundName[0], mask | TYPE | PACKAGE, invocationSite); + invocationSite.setFieldIndex(1); + if (binding instanceof VariableBinding) return binding; + compilationUnitScope().recordSimpleReference(compoundName[0]); + if (!binding.isValidBinding()) return binding; + + int length = compoundName.length; + int currentIndex = 1; + foundType : if (binding instanceof PackageBinding) { + PackageBinding packageBinding = (PackageBinding) binding; + while (currentIndex < length) { + compilationUnitScope().recordReference(packageBinding.compoundName, compoundName[currentIndex]); + binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]); + invocationSite.setFieldIndex(currentIndex); + if (binding == null) { + if (currentIndex == length) + // must be a type if its the last name, otherwise we have no idea if its a package or type + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + NotFound); + else + return new ProblemBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + NotFound); + } + if (binding instanceof ReferenceBinding) { + if (!binding.isValidBinding()) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + binding.problemId()); + if (!((ReferenceBinding) binding).canBeSeenBy(this)) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + binding, + NotVisible); + break foundType; + } + packageBinding = (PackageBinding) binding; + } + + // It is illegal to request a PACKAGE from this method. + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + NotFound); + } + + // know binding is now a ReferenceBinding + while (currentIndex < length) { + ReferenceBinding typeBinding = (ReferenceBinding) binding; + char[] nextName = compoundName[currentIndex++]; + invocationSite.setFieldIndex(currentIndex); + invocationSite.setActualReceiverType(typeBinding); + if ((mask & FIELD) != 0 && (binding = findField(typeBinding, nextName, invocationSite)) != null) { + if (!binding.isValidBinding()) + return new ProblemFieldBinding( + ((FieldBinding) binding).declaringClass, + CharOperation.subarray(compoundName, 0, currentIndex), + binding.problemId()); + break; // binding is now a field + } + if ((binding = findMemberType(nextName, typeBinding)) == null) { + if ((mask & FIELD) != 0) { + return new ProblemBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + typeBinding, + NotFound); + } else { + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + typeBinding, + NotFound); + } + } + if (!binding.isValidBinding()) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + binding.problemId()); + } + + if ((mask & FIELD) != 0 && (binding instanceof FieldBinding)) { + // was looking for a field and found a field + FieldBinding field = (FieldBinding) binding; + if (!field.isStatic()) + return new ProblemFieldBinding( + field.declaringClass, + CharOperation.subarray(compoundName, 0, currentIndex), + NonStaticReferenceInStaticContext); + return binding; + } + if ((mask & TYPE) != 0 && (binding instanceof ReferenceBinding)) { + // was looking for a type and found a type + return binding; + } + + // handle the case when a field or type was asked for but we resolved the compoundName to a type or field + return new ProblemBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + NotFound); + } + + // Added for code assist... NOT Public API + public final Binding getBinding( + char[][] compoundName, + InvocationSite invocationSite) { + int currentIndex = 0; + int length = compoundName.length; + Binding binding = + getBinding( + compoundName[currentIndex++], + VARIABLE | TYPE | PACKAGE, + invocationSite); + if (!binding.isValidBinding()) + return binding; + + foundType : if (binding instanceof PackageBinding) { + while (currentIndex < length) { + PackageBinding packageBinding = (PackageBinding) binding; + binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]); + if (binding == null) { + if (currentIndex == length) + // must be a type if its the last name, otherwise we have no idea if its a package or type + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + NotFound); + else + return new ProblemBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + NotFound); + } + if (binding instanceof ReferenceBinding) { + if (!binding.isValidBinding()) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + binding.problemId()); + if (!((ReferenceBinding) binding).canBeSeenBy(this)) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + binding, + NotVisible); + break foundType; + } + } + return binding; + } + + foundField : if (binding instanceof ReferenceBinding) { + while (currentIndex < length) { + ReferenceBinding typeBinding = (ReferenceBinding) binding; + char[] nextName = compoundName[currentIndex++]; + if ((binding = findField(typeBinding, nextName, invocationSite)) != null) { + if (!binding.isValidBinding()) + return new ProblemFieldBinding( + ((FieldBinding) binding).declaringClass, + CharOperation.subarray(compoundName, 0, currentIndex), + binding.problemId()); + if (!((FieldBinding) binding).isStatic()) + return new ProblemFieldBinding( + ((FieldBinding) binding).declaringClass, + CharOperation.subarray(compoundName, 0, currentIndex), + NonStaticReferenceInStaticContext); + break foundField; // binding is now a field + } + if ((binding = findMemberType(nextName, typeBinding)) == null) + return new ProblemBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + typeBinding, + NotFound); + if (!binding.isValidBinding()) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + binding.problemId()); + } + return binding; + } + + VariableBinding variableBinding = (VariableBinding) binding; + while (currentIndex < length) { + TypeBinding typeBinding = variableBinding.type; + if (typeBinding == null) + return new ProblemFieldBinding( + null, + CharOperation.subarray(compoundName, 0, currentIndex + 1), + NotFound); + variableBinding = + findField(typeBinding, compoundName[currentIndex++], invocationSite); + if (variableBinding == null) + return new ProblemFieldBinding( + null, + CharOperation.subarray(compoundName, 0, currentIndex), + NotFound); + if (!variableBinding.isValidBinding()) + return variableBinding; + } + return variableBinding; + } + + /* API + * + * Answer the binding that corresponds to the argument name. + * flag is a mask of the following values VARIABLE (= FIELD or LOCAL), TYPE, PACKAGE. + * Only bindings corresponding to the mask can be answered. + * + * For example, getBinding("foo", VARIABLE, site) will answer + * the binding for the field or local named "foo" (or an error binding if none exists). + * If a type named "foo" exists, it will not be detected (and an error binding will be answered) + * + * The VARIABLE mask has precedence over the TYPE mask. + * + * If the VARIABLE mask is not set, neither fields nor locals will be looked for. + * + * InvocationSite implements: + * isSuperAccess(); this is used to determine if the discovered field is visible. + * + * Limitations: cannot request FIELD independently of LOCAL, or vice versa + */ + public Binding getBinding(char[] name, int mask, InvocationSite invocationSite) { + + Binding binding = null; + FieldBinding problemField = null; + if ((mask & VARIABLE) != 0) { + if (this.kind == BLOCK_SCOPE || this.kind == METHOD_SCOPE) { + LocalVariableBinding variableBinding = findVariable(name); + // looks in this scope only + if (variableBinding != null) return variableBinding; + } + + boolean insideStaticContext = false; + boolean insideConstructorCall = false; + if (this.kind == METHOD_SCOPE) { + MethodScope methodScope = (MethodScope) this; + insideStaticContext |= methodScope.isStatic; + insideConstructorCall |= methodScope.isConstructorCall; + } + + FieldBinding foundField = null; + // can be a problem field which is answered if a valid field is not found + ProblemFieldBinding foundInsideProblem = null; + // inside Constructor call or inside static context + Scope scope = parent; + int depth = 0; + int foundDepth = 0; + ReferenceBinding foundActualReceiverType = null; + done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found + switch (scope.kind) { + case METHOD_SCOPE : + MethodScope methodScope = (MethodScope) scope; + insideStaticContext |= methodScope.isStatic; + insideConstructorCall |= methodScope.isConstructorCall; + // Fall through... could duplicate the code below to save a cast - questionable optimization + case BLOCK_SCOPE : + LocalVariableBinding variableBinding = ((BlockScope) scope).findVariable(name); + // looks in this scope only + if (variableBinding != null) { + if (foundField != null && foundField.isValidBinding()) + return new ProblemFieldBinding( + foundField.declaringClass, + name, + InheritedNameHidesEnclosingName); + if (depth > 0) + invocationSite.setDepth(depth); + return variableBinding; + } + break; + case CLASS_SCOPE : + ClassScope classScope = (ClassScope) scope; + SourceTypeBinding enclosingType = classScope.referenceContext.binding; + FieldBinding fieldBinding = + classScope.findField(enclosingType, name, invocationSite); + // Use next line instead if willing to enable protected access accross inner types + // FieldBinding fieldBinding = findField(enclosingType, name, invocationSite); + if (fieldBinding != null) { // skip it if we did not find anything + if (fieldBinding.problemId() == Ambiguous) { + if (foundField == null || foundField.problemId() == NotVisible) + // supercedes any potential InheritedNameHidesEnclosingName problem + return fieldBinding; + else + // make the user qualify the field, likely wants the first inherited field (javac generates an ambiguous error instead) + return new ProblemFieldBinding( + fieldBinding.declaringClass, + name, + InheritedNameHidesEnclosingName); + } + + ProblemFieldBinding insideProblem = null; + if (fieldBinding.isValidBinding()) { + if (!fieldBinding.isStatic()) { + if (insideConstructorCall) { + insideProblem = + new ProblemFieldBinding( + fieldBinding.declaringClass, + name, + NonStaticReferenceInConstructorInvocation); + } else if (insideStaticContext) { + insideProblem = + new ProblemFieldBinding( + fieldBinding.declaringClass, + name, + NonStaticReferenceInStaticContext); + } + } +// if (enclosingType == fieldBinding.declaringClass +// || environment().options.complianceLevel >= CompilerOptions.JDK1_4){ +// // found a valid field in the 'immediate' scope (ie. not inherited) +// // OR in 1.4 mode (inherited shadows enclosing) +// if (foundField == null) { +// if (depth > 0){ +// invocationSite.setDepth(depth); +// invocationSite.setActualReceiverType(enclosingType); +// } +// // return the fieldBinding if it is not declared in a superclass of the scope's binding (that is, inherited) +// return insideProblem == null ? fieldBinding : insideProblem; +// } +// if (foundField.isValidBinding()) +// // if a valid field was found, complain when another is found in an 'immediate' enclosing type (that is, not inherited) +// if (foundField.declaringClass != fieldBinding.declaringClass) +// // ie. have we found the same field - do not trust field identity yet +// return new ProblemFieldBinding( +// fieldBinding.declaringClass, +// name, +// InheritedNameHidesEnclosingName); +// } + } + + if (foundField == null + || (foundField.problemId() == NotVisible + && fieldBinding.problemId() != NotVisible)) { + // only remember the fieldBinding if its the first one found or the previous one was not visible & fieldBinding is... + foundDepth = depth; + foundActualReceiverType = enclosingType; + foundInsideProblem = insideProblem; + foundField = fieldBinding; + } + } + depth++; + insideStaticContext |= enclosingType.isStatic(); + // 1EX5I8Z - accessing outer fields within a constructor call is permitted + // in order to do so, we change the flag as we exit from the type, not the method + // itself, because the class scope is used to retrieve the fields. + MethodScope enclosingMethodScope = scope.methodScope(); + insideConstructorCall = + enclosingMethodScope == null ? false : enclosingMethodScope.isConstructorCall; + break; + case COMPILATION_UNIT_SCOPE : + break done; + } + scope = scope.parent; + } + + if (foundInsideProblem != null){ + return foundInsideProblem; + } + if (foundField != null) { + if (foundField.isValidBinding()){ + if (foundDepth > 0){ + invocationSite.setDepth(foundDepth); + invocationSite.setActualReceiverType(foundActualReceiverType); + } + return foundField; + } + problemField = foundField; + } + } + + // We did not find a local or instance variable. + if ((mask & TYPE) != 0) { + if ((binding = getBaseType(name)) != null) + return binding; + binding = getTypeOrPackage(name, (mask & PACKAGE) == 0 ? TYPE : TYPE | PACKAGE); + if (binding.isValidBinding() || mask == TYPE) + return binding; + // answer the problem type binding if we are only looking for a type + } else if ((mask & PACKAGE) != 0) { + compilationUnitScope().recordSimpleReference(name); + if ((binding = environment().getTopLevelPackage(name)) != null) + return binding; + } + if (problemField != null) + return problemField; + else + return new ProblemBinding(name, enclosingSourceType(), NotFound); + } + + /* API + * + * Answer the constructor binding that corresponds to receiverType, argumentTypes. + * + * InvocationSite implements + * isSuperAccess(); this is used to determine if the discovered constructor is visible. + * + * If no visible constructor is discovered, an error binding is answered. + */ + public MethodBinding getConstructor( + ReferenceBinding receiverType, + TypeBinding[] argumentTypes, + InvocationSite invocationSite) { + + compilationUnitScope().recordTypeReference(receiverType); + compilationUnitScope().recordTypeReferences(argumentTypes); + MethodBinding methodBinding = receiverType.getExactConstructor(argumentTypes); + if (methodBinding != null) { + if (methodBinding.canBeSeenBy(invocationSite, this)) + return methodBinding; + } + MethodBinding[] methods = + receiverType.getMethods(ConstructorDeclaration.ConstantPoolName); + if (methods == NoMethods) { + return new ProblemMethodBinding( + ConstructorDeclaration.ConstantPoolName, + argumentTypes, + NotFound); + } + MethodBinding[] compatible = new MethodBinding[methods.length]; + int compatibleIndex = 0; + for (int i = 0, length = methods.length; i < length; i++) + if (areParametersAssignable(methods[i].parameters, argumentTypes)) + compatible[compatibleIndex++] = methods[i]; + if (compatibleIndex == 0) + return new ProblemMethodBinding( + ConstructorDeclaration.ConstantPoolName, + argumentTypes, + NotFound); + // need a more descriptive error... cannot convert from X to Y + + MethodBinding[] visible = new MethodBinding[compatibleIndex]; + int visibleIndex = 0; + for (int i = 0; i < compatibleIndex; i++) { + MethodBinding method = compatible[i]; + if (method.canBeSeenBy(invocationSite, this)) + visible[visibleIndex++] = method; + } + if (visibleIndex == 1) + return visible[0]; + if (visibleIndex == 0) + return new ProblemMethodBinding( + compatible[0], + ConstructorDeclaration.ConstantPoolName, + compatible[0].parameters, + NotVisible); + return mostSpecificClassMethodBinding(visible, visibleIndex); + } + + /* + * This retrieves the argument that maps to an enclosing instance of the suitable type, + * if not found then answers nil -- do not create one + * + * #implicitThis : the implicit this will be ok + * #((arg) this$n) : available as a constructor arg + * #((arg) this$n ... this$p) : available as as a constructor arg + a sequence of fields + * #((fieldDescr) this$n ... this$p) : available as a sequence of fields + * nil : not found + * + * Note that this algorithm should answer the shortest possible sequence when + * shortcuts are available: + * this$0 . this$0 . this$0 + * instead of + * this$2 . this$1 . this$0 . this$1 . this$0 + * thus the code generation will be more compact and runtime faster + */ + public VariableBinding[] getEmulationPath(LocalVariableBinding outerLocalVariable) { + + MethodScope currentMethodScope = this.methodScope(); + SourceTypeBinding sourceType = currentMethodScope.enclosingSourceType(); + + // identity check + if (currentMethodScope == outerLocalVariable.declaringScope.methodScope()) { + return new VariableBinding[] { outerLocalVariable }; + // implicit this is good enough + } + // use synthetic constructor arguments if possible + if (currentMethodScope.isInsideInitializerOrConstructor() + && (sourceType.isNestedType())) { + SyntheticArgumentBinding syntheticArg; + if ((syntheticArg = ((NestedTypeBinding) sourceType).getSyntheticArgument(outerLocalVariable)) != null) { + return new VariableBinding[] { syntheticArg }; + } + } + // use a synthetic field then + if (!currentMethodScope.isStatic) { + FieldBinding syntheticField; + if ((syntheticField = sourceType.getSyntheticField(outerLocalVariable)) != null) { + return new VariableBinding[] { syntheticField }; + } + } + return null; + } + + /* + * This retrieves the argument that maps to an enclosing instance of the suitable type, + * if not found then answers nil -- do not create one + * + * #implicitThis : the implicit this will be ok + * #((arg) this$n) : available as a constructor arg + * #((arg) this$n access$m... access$p) : available as as a constructor arg + a sequence of synthetic accessors to synthetic fields + * #((fieldDescr) this$n access#m... access$p) : available as a first synthetic field + a sequence of synthetic accessors to synthetic fields + * nil : not found + * jls 15.9.2 + */ + public Object[] getEmulationPath( + ReferenceBinding targetEnclosingType, + boolean onlyExactMatch, + boolean ignoreEnclosingArgInConstructorCall) { + //TODO: (philippe) investigate why exactly test76 fails if ignoreEnclosingArgInConstructorCall is always false + MethodScope currentMethodScope = this.methodScope(); + SourceTypeBinding sourceType = currentMethodScope.enclosingSourceType(); + + // identity check + if (!currentMethodScope.isStatic + && (!currentMethodScope.isConstructorCall || ignoreEnclosingArgInConstructorCall) + && (sourceType == targetEnclosingType + || (!onlyExactMatch && targetEnclosingType.isSuperclassOf(sourceType)))) { + if (currentMethodScope.isConstructorCall) { + return NoEnclosingInstanceInConstructorCall; + } + if (currentMethodScope.isStatic){ + return NoEnclosingInstanceInStaticContext; + } + return EmulationPathToImplicitThis; // implicit this is good enough + } + if (!sourceType.isNestedType() || sourceType.isStatic()) { // no emulation from within non-inner types + if (currentMethodScope.isConstructorCall) { + return NoEnclosingInstanceInConstructorCall; + } + if (currentMethodScope.isStatic){ + return NoEnclosingInstanceInStaticContext; + } + return null; + } + boolean insideConstructor = currentMethodScope.isInsideInitializerOrConstructor(); + // use synthetic constructor arguments if possible + if (insideConstructor) { + SyntheticArgumentBinding syntheticArg; + if ((syntheticArg = ((NestedTypeBinding) sourceType).getSyntheticArgument(targetEnclosingType, onlyExactMatch)) != null) { + return new Object[] { syntheticArg }; + } + } + + // use a direct synthetic field then + if (currentMethodScope.isStatic) { + return NoEnclosingInstanceInStaticContext; + } + FieldBinding syntheticField = sourceType.getSyntheticField(targetEnclosingType, onlyExactMatch); + if (syntheticField != null) { + if (currentMethodScope.isConstructorCall){ + return NoEnclosingInstanceInConstructorCall; + } + return new Object[] { syntheticField }; + } + // could be reached through a sequence of enclosing instance link (nested members) + Object[] path = new Object[2]; // probably at least 2 of them + ReferenceBinding currentType = sourceType.enclosingType(); + if (insideConstructor) { + path[0] = ((NestedTypeBinding) sourceType).getSyntheticArgument((SourceTypeBinding) currentType, onlyExactMatch); + } else { + if (currentMethodScope.isConstructorCall){ + return NoEnclosingInstanceInConstructorCall; + } + path[0] = sourceType.getSyntheticField((SourceTypeBinding) currentType, onlyExactMatch); + } + if (path[0] != null) { // keep accumulating + + int count = 1; + ReferenceBinding currentEnclosingType; + while ((currentEnclosingType = currentType.enclosingType()) != null) { + + //done? + if (currentType == targetEnclosingType + || (!onlyExactMatch && targetEnclosingType.isSuperclassOf(currentType))) break; + + if (currentMethodScope != null) { + currentMethodScope = currentMethodScope.enclosingMethodScope(); + if (currentMethodScope != null && currentMethodScope.isConstructorCall){ + return NoEnclosingInstanceInConstructorCall; + } + if (currentMethodScope != null && currentMethodScope.isStatic){ + return NoEnclosingInstanceInStaticContext; + } + } + + syntheticField = ((NestedTypeBinding) currentType).getSyntheticField((SourceTypeBinding) currentEnclosingType, onlyExactMatch); + if (syntheticField == null) break; + + // append inside the path + if (count == path.length) { + System.arraycopy(path, 0, (path = new Object[count + 1]), 0, count); + } + // private access emulation is necessary since synthetic field is private + path[count++] = ((SourceTypeBinding) syntheticField.declaringClass).addSyntheticMethod(syntheticField, true); + currentType = currentEnclosingType; + } + if (currentType == targetEnclosingType + || (!onlyExactMatch && targetEnclosingType.isSuperclassOf(currentType))) { + return path; + } + } + return null; + } + + /* API + * + * Answer the field binding that corresponds to fieldName. + * Start the lookup at the receiverType. + * InvocationSite implements + * isSuperAccess(); this is used to determine if the discovered field is visible. + * Only fields defined by the receiverType or its supertypes are answered; + * a field of an enclosing type will not be found using this API. + * + * If no visible field is discovered, an error binding is answered. + */ + public FieldBinding getField( + TypeBinding receiverType, + char[] fieldName, + InvocationSite invocationSite) { + + FieldBinding field = findField(receiverType, fieldName, invocationSite); + if (field == null) + return new ProblemFieldBinding( + receiverType instanceof ReferenceBinding + ? (ReferenceBinding) receiverType + : null, + fieldName, + NotFound); + else + return field; + } + + /* API + * + * Answer the method binding that corresponds to selector, argumentTypes. + * Start the lookup at the enclosing type of the receiver. + * InvocationSite implements + * isSuperAccess(); this is used to determine if the discovered method is visible. + * setDepth(int); this is used to record the depth of the discovered method + * relative to the enclosing type of the receiver. (If the method is defined + * in the enclosing type of the receiver, the depth is 0; in the next enclosing + * type, the depth is 1; and so on + * + * If no visible method is discovered, an error binding is answered. + */ + public MethodBinding getImplicitMethod( + char[] selector, + TypeBinding[] argumentTypes, + InvocationSite invocationSite) { + + boolean insideStaticContext = false; + boolean insideConstructorCall = false; + MethodBinding foundMethod = null; + ProblemMethodBinding foundFuzzyProblem = null; + // the weird method lookup case (matches method name in scope, then arg types, then visibility) + ProblemMethodBinding foundInsideProblem = null; + // inside Constructor call or inside static context + Scope scope = this; + int depth = 0; + done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found + switch (scope.kind) { + case METHOD_SCOPE : + MethodScope methodScope = (MethodScope) scope; + insideStaticContext |= methodScope.isStatic; + insideConstructorCall |= methodScope.isConstructorCall; + break; + case CLASS_SCOPE : + ClassScope classScope = (ClassScope) scope; + SourceTypeBinding receiverType = classScope.referenceContext.binding; + boolean isExactMatch = true; + // retrieve an exact visible match (if possible) + MethodBinding methodBinding = + (foundMethod == null) + ? classScope.findExactMethod( + receiverType, + selector, + argumentTypes, + invocationSite) + : classScope.findExactMethod( + receiverType, + foundMethod.selector, + foundMethod.parameters, + invocationSite); + // ? findExactMethod(receiverType, selector, argumentTypes, invocationSite) + // : findExactMethod(receiverType, foundMethod.selector, foundMethod.parameters, invocationSite); + if (methodBinding == null) { + // answers closest approximation, may not check argumentTypes or visibility + isExactMatch = false; + methodBinding = + classScope.findMethod(receiverType, selector, argumentTypes, invocationSite); + // methodBinding = findMethod(receiverType, selector, argumentTypes, invocationSite); + } + if (methodBinding != null) { // skip it if we did not find anything + if (methodBinding.problemId() == Ambiguous) { + if (foundMethod == null || foundMethod.problemId() == NotVisible) + // supercedes any potential InheritedNameHidesEnclosingName problem + return methodBinding; + else + // make the user qualify the method, likely wants the first inherited method (javac generates an ambiguous error instead) + return new ProblemMethodBinding( + selector, + argumentTypes, + InheritedNameHidesEnclosingName); + } + + ProblemMethodBinding fuzzyProblem = null; + ProblemMethodBinding insideProblem = null; + if (methodBinding.isValidBinding()) { + if (!isExactMatch) { + if (!areParametersAssignable(methodBinding.parameters, argumentTypes)) { + if (foundMethod == null || foundMethod.problemId() == NotVisible){ + // inherited mismatch is reported directly, not looking at enclosing matches + return new ProblemMethodBinding(methodBinding, selector, argumentTypes, NotFound); + } + // make the user qualify the method, likely wants the first inherited method (javac generates an ambiguous error instead) + fuzzyProblem = new ProblemMethodBinding(selector, methodBinding.parameters, InheritedNameHidesEnclosingName); + + } else if (!methodBinding.canBeSeenBy(receiverType, invocationSite, classScope)) { + // using instead of for visibility check does grant all access to innerclass + fuzzyProblem = + new ProblemMethodBinding( + methodBinding, + selector, + methodBinding.parameters, + NotVisible); + } + } + if (fuzzyProblem == null && !methodBinding.isStatic()) { + if (insideConstructorCall) { + insideProblem = + new ProblemMethodBinding( + methodBinding.selector, + methodBinding.parameters, + NonStaticReferenceInConstructorInvocation); + } else if (insideStaticContext) { + insideProblem = + new ProblemMethodBinding( + methodBinding.selector, + methodBinding.parameters, + NonStaticReferenceInStaticContext); + } + } + +// if (receiverType == methodBinding.declaringClass +// || (receiverType.getMethods(selector)) != NoMethods +// || ((fuzzyProblem == null || fuzzyProblem.problemId() != NotVisible) && environment().options.complianceLevel >= CompilerOptions.JDK1_4)){ +// // found a valid method in the 'immediate' scope (ie. not inherited) +// // OR the receiverType implemented a method with the correct name +// // OR in 1.4 mode (inherited visible shadows enclosing) +// if (foundMethod == null) { +// if (depth > 0){ +// invocationSite.setDepth(depth); +// invocationSite.setActualReceiverType(receiverType); +// } +// // return the methodBinding if it is not declared in a superclass of the scope's binding (that is, inherited) +// if (fuzzyProblem != null) +// return fuzzyProblem; +// if (insideProblem != null) +// return insideProblem; +// return methodBinding; +// } +// // if a method was found, complain when another is found in an 'immediate' enclosing type (that is, not inherited) +// // NOTE: Unlike fields, a non visible method hides a visible method +// if (foundMethod.declaringClass != methodBinding.declaringClass) +// // ie. have we found the same method - do not trust field identity yet +// return new ProblemMethodBinding( +// methodBinding.selector, +// methodBinding.parameters, +// InheritedNameHidesEnclosingName); +// } + } + + if (foundMethod == null + || (foundMethod.problemId() == NotVisible + && methodBinding.problemId() != NotVisible)) { + // only remember the methodBinding if its the first one found or the previous one was not visible & methodBinding is... + // remember that private methods are visible if defined directly by an enclosing class + if (depth > 0){ + invocationSite.setDepth(depth); + invocationSite.setActualReceiverType(receiverType); + } + foundFuzzyProblem = fuzzyProblem; + foundInsideProblem = insideProblem; + if (fuzzyProblem == null) + foundMethod = methodBinding; // only keep it if no error was found + } + } + depth++; + insideStaticContext |= receiverType.isStatic(); + // 1EX5I8Z - accessing outer fields within a constructor call is permitted + // in order to do so, we change the flag as we exit from the type, not the method + // itself, because the class scope is used to retrieve the fields. + MethodScope enclosingMethodScope = scope.methodScope(); + insideConstructorCall = + enclosingMethodScope == null ? false : enclosingMethodScope.isConstructorCall; + break; + case COMPILATION_UNIT_SCOPE : + break done; + } + scope = scope.parent; + } + + if (foundFuzzyProblem != null) + return foundFuzzyProblem; + if (foundInsideProblem != null) + return foundInsideProblem; + if (foundMethod != null) + return foundMethod; + return new ProblemMethodBinding(selector, argumentTypes, NotFound); + } + + /* API + * + * Answer the method binding that corresponds to selector, argumentTypes. + * Start the lookup at the receiverType. + * InvocationSite implements + * isSuperAccess(); this is used to determine if the discovered method is visible. + * + * Only methods defined by the receiverType or its supertypes are answered; + * use getImplicitMethod() to discover methods of enclosing types. + * + * If no visible method is discovered, an error binding is answered. + */ + public MethodBinding getMethod( + TypeBinding receiverType, + char[] selector, + TypeBinding[] argumentTypes, + InvocationSite invocationSite) { + + if (receiverType.isArrayType()) + return findMethodForArray( + (ArrayBinding) receiverType, + selector, + argumentTypes, + invocationSite); + if (receiverType.isBaseType()) + return new ProblemMethodBinding(selector, argumentTypes, NotFound); + + ReferenceBinding currentType = (ReferenceBinding) receiverType; + if (!currentType.canBeSeenBy(this)) + return new ProblemMethodBinding(selector, argumentTypes, ReceiverTypeNotVisible); + + // retrieve an exact visible match (if possible) + MethodBinding methodBinding = + findExactMethod(currentType, selector, argumentTypes, invocationSite); + if (methodBinding != null) + return methodBinding; + + // answers closest approximation, may not check argumentTypes or visibility + methodBinding = + findMethod(currentType, selector, argumentTypes, invocationSite); + if (methodBinding == null) + return new ProblemMethodBinding(selector, argumentTypes, NotFound); + if (methodBinding.isValidBinding()) { + if (!areParametersAssignable(methodBinding.parameters, argumentTypes)) + return new ProblemMethodBinding( + methodBinding, + selector, + argumentTypes, + NotFound); + if (!methodBinding.canBeSeenBy(currentType, invocationSite, this)) + return new ProblemMethodBinding( + methodBinding, + selector, + methodBinding.parameters, + NotVisible); + } + return methodBinding; + } + + public int maxShiftedOffset() { + int max = -1; + if (this.shiftScopes != null){ + for (int i = 0, length = this.shiftScopes.length; i < length; i++){ + int subMaxOffset = this.shiftScopes[i].maxOffset; + if (subMaxOffset > max) max = subMaxOffset; + } + } + return max; + } + + /* Answer the problem reporter to use for raising new problems. + * + * Note that as a side-effect, this updates the current reference context + * (unit, type or method) in case the problem handler decides it is necessary + * to abort. + */ + public ProblemReporter problemReporter() { + + return outerMostMethodScope().problemReporter(); + } + + /* + * Code responsible to request some more emulation work inside the invocation type, so as to supply + * correct synthetic arguments to any allocation of the target type. + */ + public void propagateInnerEmulation(ReferenceBinding targetType, boolean isEnclosingInstanceSupplied) { + + // no need to propagate enclosing instances, they got eagerly allocated already. + + SyntheticArgumentBinding[] syntheticArguments; + if ((syntheticArguments = targetType.syntheticOuterLocalVariables()) != null) { + for (int i = 0, max = syntheticArguments.length; i < max; i++) { + SyntheticArgumentBinding syntheticArg = syntheticArguments[i]; + // need to filter out the one that could match a supplied enclosing instance + if (!(isEnclosingInstanceSupplied + && (syntheticArg.type == targetType.enclosingType()))) { + this.emulateOuterAccess(syntheticArg.actualOuterLocalVariable); + } + } + } + } + + /* Answer the reference type of this scope. + * + * It is the nearest enclosing type of this scope. + */ + public TypeDeclaration referenceType() { + + return methodScope().referenceType(); + } + + // start position in this scope - for ordering scopes vs. variables + int startIndex() { + return startIndex; + } + + public String toString() { + return toString(0); + } + + public String toString(int tab) { + + String s = basicToString(tab); + for (int i = 0; i < scopeIndex; i++) + if (subscopes[i] instanceof BlockScope) + s += ((BlockScope) subscopes[i]).toString(tab + 1) + "\n"; //$NON-NLS-1$ + return s; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ClassScope.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ClassScope.java new file mode 100644 index 0000000..6ec975c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ClassScope.java @@ -0,0 +1,875 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; +import net.sourceforge.phpdt.internal.compiler.util.HashtableOfObject; +import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.Clinit; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeReference; + +public class ClassScope extends Scope { + public TypeDeclaration referenceContext; + + public ClassScope(Scope parent, TypeDeclaration context) { + super(CLASS_SCOPE, parent); + this.referenceContext = context; + } + + void buildAnonymousTypeBinding(SourceTypeBinding enclosingType, ReferenceBinding supertype) { + + LocalTypeBinding anonymousType = buildLocalType(enclosingType, enclosingType.fPackage); + + SourceTypeBinding sourceType = referenceContext.binding; + if (supertype.isInterface()) { + sourceType.superclass = getJavaLangObject(); + sourceType.superInterfaces = new ReferenceBinding[] { supertype }; + } else { + sourceType.superclass = supertype; + sourceType.superInterfaces = TypeBinding.NoSuperInterfaces; + } + connectMemberTypes(); + buildFieldsAndMethods(); + anonymousType.faultInTypesForFieldsAndMethods(); + sourceType.verifyMethods(environment().methodVerifier()); + } + + private void buildFields() { + if (referenceContext.fields == null) { + referenceContext.binding.fields = NoFields; + return; + } + // count the number of fields vs. initializers + FieldDeclaration[] fields = referenceContext.fields; + int size = fields.length; + int count = 0; + for (int i = 0; i < size; i++) + if (fields[i].isField()) + count++; + + // iterate the field declarations to create the bindings, lose all duplicates + FieldBinding[] fieldBindings = new FieldBinding[count]; + HashtableOfObject knownFieldNames = new HashtableOfObject(count); + boolean duplicate = false; + count = 0; + for (int i = 0; i < size; i++) { + FieldDeclaration field = fields[i]; + if (!field.isField()) { + if (referenceContext.binding.isInterface()) + problemReporter().interfaceCannotHaveInitializers(referenceContext.binding, field); + } else { + FieldBinding fieldBinding = new FieldBinding(field, null, referenceContext.binding); + // field's type will be resolved when needed for top level types + checkAndSetModifiersForField(fieldBinding, field); + + if (knownFieldNames.containsKey(field.name)) { + duplicate = true; + FieldBinding previousBinding = (FieldBinding) knownFieldNames.get(field.name); + if (previousBinding != null) { + for (int f = 0; f < i; f++) { + FieldDeclaration previousField = fields[f]; + if (previousField.binding == previousBinding) { + problemReporter().duplicateFieldInType(referenceContext.binding, previousField); + previousField.binding = null; + break; + } + } + } + knownFieldNames.put(field.name, null); // ensure that the duplicate field is found & removed + problemReporter().duplicateFieldInType(referenceContext.binding, field); + field.binding = null; + } else { + knownFieldNames.put(field.name, fieldBinding); + // remember that we have seen a field with this name + if (fieldBinding != null) + fieldBindings[count++] = fieldBinding; + } + } + } + // remove duplicate fields + if (duplicate) { + FieldBinding[] newFieldBindings = new FieldBinding[knownFieldNames.size() - 1]; + // we know we'll be removing at least 1 duplicate name + size = count; + count = 0; + for (int i = 0; i < size; i++) { + FieldBinding fieldBinding = fieldBindings[i]; + if (knownFieldNames.get(fieldBinding.name) != null) + newFieldBindings[count++] = fieldBinding; + } + fieldBindings = newFieldBindings; + } + + if (count != fieldBindings.length) + System.arraycopy(fieldBindings, 0, fieldBindings = new FieldBinding[count], 0, count); + for (int i = 0; i < count; i++) + fieldBindings[i].id = i; + referenceContext.binding.fields = fieldBindings; + } + + void buildFieldsAndMethods() { + buildFields(); + buildMethods(); + + SourceTypeBinding sourceType = referenceContext.binding; + if (sourceType.isMemberType() && !sourceType.isLocalType()) + ((MemberTypeBinding) sourceType).checkSyntheticArgsAndFields(); + + ReferenceBinding[] memberTypes = sourceType.memberTypes; + for (int i = 0, length = memberTypes.length; i < length; i++) + ((SourceTypeBinding) memberTypes[i]).scope.buildFieldsAndMethods(); + } + + private LocalTypeBinding buildLocalType( + SourceTypeBinding enclosingType, + PackageBinding packageBinding) { + referenceContext.scope = this; + referenceContext.staticInitializerScope = new MethodScope(this, referenceContext, true); + referenceContext.initializerScope = new MethodScope(this, referenceContext, false); + + // build the binding or the local type + LocalTypeBinding localType = new LocalTypeBinding(this, enclosingType); + referenceContext.binding = localType; + checkAndSetModifiers(); + + // Look at member types + ReferenceBinding[] memberTypeBindings = NoMemberTypes; + if (referenceContext.memberTypes != null) { + int size = referenceContext.memberTypes.length; + memberTypeBindings = new ReferenceBinding[size]; + int count = 0; + nextMember : for (int i = 0; i < size; i++) { + TypeDeclaration memberContext = referenceContext.memberTypes[i]; + if (memberContext.isInterface()) { + problemReporter().nestedClassCannotDeclareInterface(memberContext); + continue nextMember; + } + ReferenceBinding type = localType; + // check that the member does not conflict with an enclosing type + do { + if (CharOperation.equals(type.sourceName, memberContext.name)) { + problemReporter().hidingEnclosingType(memberContext); + continue nextMember; + } + type = type.enclosingType(); + } while (type != null); + // check the member type does not conflict with another sibling member type + for (int j = 0; j < i; j++) { + if (CharOperation.equals(referenceContext.memberTypes[j].name, memberContext.name)) { + problemReporter().duplicateNestedType(memberContext); + continue nextMember; + } + } + + ClassScope memberScope = new ClassScope(this, referenceContext.memberTypes[i]); + LocalTypeBinding memberBinding = memberScope.buildLocalType(localType, packageBinding); + memberBinding.setAsMemberType(); + memberTypeBindings[count++] = memberBinding; + } + if (count != size) + System.arraycopy(memberTypeBindings, 0, memberTypeBindings = new ReferenceBinding[count], 0, count); + } + localType.memberTypes = memberTypeBindings; + return localType; + } + + void buildLocalTypeBinding(SourceTypeBinding enclosingType) { + + LocalTypeBinding localType = buildLocalType(enclosingType, enclosingType.fPackage); + connectTypeHierarchy(); + buildFieldsAndMethods(); + localType.faultInTypesForFieldsAndMethods(); + + referenceContext.binding.verifyMethods(environment().methodVerifier()); + } + + private void buildMethods() { + if (referenceContext.methods == null) { + referenceContext.binding.methods = NoMethods; + return; + } + + // iterate the method declarations to create the bindings + AbstractMethodDeclaration[] methods = referenceContext.methods; + int size = methods.length; + int clinitIndex = -1; + for (int i = 0; i < size; i++) { + if (methods[i] instanceof Clinit) { + clinitIndex = i; + break; + } + } + MethodBinding[] methodBindings = new MethodBinding[clinitIndex == -1 ? size : size - 1]; + + int count = 0; + for (int i = 0; i < size; i++) { + if (i != clinitIndex) { + MethodScope scope = new MethodScope(this, methods[i], false); + MethodBinding methodBinding = scope.createMethod(methods[i]); + if (methodBinding != null) // is null if binding could not be created + methodBindings[count++] = methodBinding; + } + } + if (count != methodBindings.length) + System.arraycopy(methodBindings, 0, methodBindings = new MethodBinding[count], 0, count); + + referenceContext.binding.methods = methodBindings; + referenceContext.binding.modifiers |= AccUnresolved; // until methods() is sent + } + SourceTypeBinding buildType(SourceTypeBinding enclosingType, PackageBinding packageBinding) { + // provide the typeDeclaration with needed scopes + referenceContext.scope = this; + referenceContext.staticInitializerScope = new MethodScope(this, referenceContext, true); + referenceContext.initializerScope = new MethodScope(this, referenceContext, false); + + if (enclosingType == null) { + char[][] className = CharOperation.arrayConcat(packageBinding.compoundName, referenceContext.name); + referenceContext.binding = new SourceTypeBinding(className, packageBinding, this); + } else { + char[][] className = CharOperation.deepCopy(enclosingType.compoundName); + className[className.length - 1] = + CharOperation.concat(className[className.length - 1], referenceContext.name, '$'); + referenceContext.binding = new MemberTypeBinding(className, this, enclosingType); + } + + SourceTypeBinding sourceType = referenceContext.binding; + sourceType.fPackage.addType(sourceType); + checkAndSetModifiers(); + + // Look at member types + ReferenceBinding[] memberTypeBindings = NoMemberTypes; + if (referenceContext.memberTypes != null) { + int size = referenceContext.memberTypes.length; + memberTypeBindings = new ReferenceBinding[size]; + int count = 0; + nextMember : for (int i = 0; i < size; i++) { + TypeDeclaration memberContext = referenceContext.memberTypes[i]; + if (memberContext.isInterface() + && sourceType.isNestedType() + && sourceType.isClass() + && !sourceType.isStatic()) { + problemReporter().nestedClassCannotDeclareInterface(memberContext); + continue nextMember; + } + ReferenceBinding type = sourceType; + // check that the member does not conflict with an enclosing type + do { + if (CharOperation.equals(type.sourceName, memberContext.name)) { + problemReporter().hidingEnclosingType(memberContext); + continue nextMember; + } + type = type.enclosingType(); + } while (type != null); + // check that the member type does not conflict with another sibling member type + for (int j = 0; j < i; j++) { + if (CharOperation.equals(referenceContext.memberTypes[j].name, memberContext.name)) { + problemReporter().duplicateNestedType(memberContext); + continue nextMember; + } + } + + ClassScope memberScope = new ClassScope(this, memberContext); + memberTypeBindings[count++] = memberScope.buildType(sourceType, packageBinding); + } + if (count != size) + System.arraycopy(memberTypeBindings, 0, memberTypeBindings = new ReferenceBinding[count], 0, count); + } + sourceType.memberTypes = memberTypeBindings; + return sourceType; + } + + private void checkAndSetModifiers() { + SourceTypeBinding sourceType = referenceContext.binding; + int modifiers = sourceType.modifiers; + if ((modifiers & AccAlternateModifierProblem) != 0) + problemReporter().duplicateModifierForType(sourceType); + + ReferenceBinding enclosingType = sourceType.enclosingType(); + boolean isMemberType = sourceType.isMemberType(); + + if (isMemberType) { + // checks for member types before local types to catch local members +// if (enclosingType.isStrictfp()) +// modifiers |= AccStrictfp; + if (enclosingType.isDeprecated()) + modifiers |= AccDeprecatedImplicitly; + if (enclosingType.isInterface()) + modifiers |= AccPublic; + } else if (sourceType.isLocalType()) { + if (sourceType.isAnonymousType()) + modifiers |= AccFinal; + ReferenceContext refContext = methodScope().referenceContext; + if (refContext instanceof TypeDeclaration) { + ReferenceBinding type = ((TypeDeclaration) refContext).binding; +// if (type.isStrictfp()) +// modifiers |= AccStrictfp; + if (type.isDeprecated()) + modifiers |= AccDeprecatedImplicitly; + } else { + MethodBinding method = ((AbstractMethodDeclaration) refContext).binding; + if (method != null){ +// if (method.isStrictfp()) +// modifiers |= AccStrictfp; + if (method.isDeprecated()) + modifiers |= AccDeprecatedImplicitly; + } + } + } + // after this point, tests on the 16 bits reserved. + int realModifiers = modifiers & AccJustFlag; + + if ((realModifiers & AccInterface) != 0) { + // detect abnormal cases for interfaces + if (isMemberType) { + int unexpectedModifiers = + ~(AccPublic | AccPrivate | AccProtected | AccStatic | AccAbstract | AccInterface );//| AccStrictfp); + if ((realModifiers & unexpectedModifiers) != 0) + problemReporter().illegalModifierForMemberInterface(sourceType); + /* + } else if (sourceType.isLocalType()) { //interfaces cannot be defined inside a method + int unexpectedModifiers = ~(AccAbstract | AccInterface | AccStrictfp); + if ((realModifiers & unexpectedModifiers) != 0) + problemReporter().illegalModifierForLocalInterface(sourceType); + */ + } else { + int unexpectedModifiers = ~(AccPublic | AccAbstract | AccInterface);// | AccStrictfp); + if ((realModifiers & unexpectedModifiers) != 0) + problemReporter().illegalModifierForInterface(sourceType); + } + modifiers |= AccAbstract; + } else { + // detect abnormal cases for types + if (isMemberType) { // includes member types defined inside local types + int unexpectedModifiers = + ~(AccPublic | AccPrivate | AccProtected | AccStatic | AccAbstract | AccFinal);// | AccStrictfp); + if ((realModifiers & unexpectedModifiers) != 0) + problemReporter().illegalModifierForMemberClass(sourceType); + } else if (sourceType.isLocalType()) { + int unexpectedModifiers = ~(AccAbstract | AccFinal);// | AccStrictfp); + if ((realModifiers & unexpectedModifiers) != 0) + problemReporter().illegalModifierForLocalClass(sourceType); + } else { + int unexpectedModifiers = ~(AccPublic | AccAbstract | AccFinal);// | AccStrictfp); + if ((realModifiers & unexpectedModifiers) != 0) + problemReporter().illegalModifierForClass(sourceType); + } + + // check that Final and Abstract are not set together + if ((realModifiers & (AccFinal | AccAbstract)) == (AccFinal | AccAbstract)) + problemReporter().illegalModifierCombinationFinalAbstractForClass(sourceType); + } + + if (isMemberType) { + // test visibility modifiers inconsistency, isolate the accessors bits + if (enclosingType.isInterface()) { + if ((realModifiers & (AccProtected | AccPrivate)) != 0) { + problemReporter().illegalVisibilityModifierForInterfaceMemberType(sourceType); + + // need to keep the less restrictive + if ((realModifiers & AccProtected) != 0) + modifiers ^= AccProtected; + if ((realModifiers & AccPrivate) != 0) + modifiers ^= AccPrivate; + } + } else { + int accessorBits = realModifiers & (AccPublic | AccProtected | AccPrivate); + if ((accessorBits & (accessorBits - 1)) > 1) { + problemReporter().illegalVisibilityModifierCombinationForMemberType(sourceType); + + // need to keep the less restrictive + if ((accessorBits & AccPublic) != 0) { + if ((accessorBits & AccProtected) != 0) + modifiers ^= AccProtected; + if ((accessorBits & AccPrivate) != 0) + modifiers ^= AccPrivate; + } + if ((accessorBits & AccProtected) != 0) + if ((accessorBits & AccPrivate) != 0) + modifiers ^= AccPrivate; + } + } + + // static modifier test + if ((realModifiers & AccStatic) == 0) { + if (enclosingType.isInterface()) + modifiers |= AccStatic; + } else { + if (!enclosingType.isStatic()) + // error the enclosing type of a static field must be static or a top-level type + problemReporter().illegalStaticModifierForMemberType(sourceType); + } + } + + sourceType.modifiers = modifiers; + } + + /* This method checks the modifiers of a field. + * + * 9.3 & 8.3 + * Need to integrate the check for the final modifiers for nested types + * + * Note : A scope is accessible by : fieldBinding.declaringClass.scope + */ + private void checkAndSetModifiersForField(FieldBinding fieldBinding, FieldDeclaration fieldDecl) { + int modifiers = fieldBinding.modifiers; + if ((modifiers & AccAlternateModifierProblem) != 0) + problemReporter().duplicateModifierForField(fieldBinding.declaringClass, fieldDecl); + + if (fieldBinding.declaringClass.isInterface()) { + int expectedValue = AccPublic | AccStatic | AccFinal; + // set the modifiers + modifiers |= expectedValue; + + // and then check that they are the only ones + if ((modifiers & AccJustFlag) != expectedValue) + problemReporter().illegalModifierForInterfaceField(fieldBinding.declaringClass, fieldDecl); + fieldBinding.modifiers = modifiers; + return; + } + + // after this point, tests on the 16 bits reserved. + int realModifiers = modifiers & AccJustFlag; + int unexpectedModifiers = + ~(AccPublic | AccPrivate | AccProtected | AccFinal | AccStatic);// | AccTransient | AccVolatile); + if ((realModifiers & unexpectedModifiers) != 0) + problemReporter().illegalModifierForField(fieldBinding.declaringClass, fieldDecl); + + int accessorBits = realModifiers & (AccPublic | AccProtected | AccPrivate); + if ((accessorBits & (accessorBits - 1)) > 1) { + problemReporter().illegalVisibilityModifierCombinationForField( + fieldBinding.declaringClass, + fieldDecl); + + // need to keep the less restrictive + if ((accessorBits & AccPublic) != 0) { + if ((accessorBits & AccProtected) != 0) + modifiers ^= AccProtected; + if ((accessorBits & AccPrivate) != 0) + modifiers ^= AccPrivate; + } + if ((accessorBits & AccProtected) != 0) + if ((accessorBits & AccPrivate) != 0) + modifiers ^= AccPrivate; + } + +// if ((realModifiers & (AccFinal | AccVolatile)) == (AccFinal | AccVolatile)) +// problemReporter().illegalModifierCombinationFinalVolatileForField( +// fieldBinding.declaringClass, +// fieldDecl); + + if (fieldDecl.initialization == null && (modifiers & AccFinal) != 0) { + modifiers |= AccBlankFinal; + } + fieldBinding.modifiers = modifiers; + } + + private void checkForInheritedMemberTypes(SourceTypeBinding sourceType) { + // search up the hierarchy of the sourceType to see if any superType defines a member type + // when no member types are defined, tag the sourceType & each superType with the HasNoMemberTypes bit + ReferenceBinding currentType = sourceType; + ReferenceBinding[][] interfacesToVisit = null; + int lastPosition = -1; + do { + if ((currentType.tagBits & HasNoMemberTypes) != 0) + break; // already know it has no inherited member types, can stop looking up + if (currentType.memberTypes() != NoMemberTypes) + return; // has member types + ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); + if (itsInterfaces != NoSuperInterfaces) { + if (interfacesToVisit == null) + interfacesToVisit = new ReferenceBinding[5][]; + if (++lastPosition == interfacesToVisit.length) + System.arraycopy( + interfacesToVisit, + 0, + interfacesToVisit = new ReferenceBinding[lastPosition * 2][], + 0, + lastPosition); + interfacesToVisit[lastPosition] = itsInterfaces; + } + } while ((currentType = currentType.superclass()) != null); + + boolean hasMembers = false; + if (interfacesToVisit != null) { + done : for (int i = 0; i <= lastPosition; i++) { + ReferenceBinding[] interfaces = interfacesToVisit[i]; + for (int j = 0, length = interfaces.length; j < length; j++) { + ReferenceBinding anInterface = interfaces[j]; + if ((anInterface.tagBits & InterfaceVisited) == 0) { // if interface as not already been visited + anInterface.tagBits |= InterfaceVisited; + if ((anInterface.tagBits & HasNoMemberTypes) != 0) + continue; // already know it has no inherited member types + if (anInterface.memberTypes() != NoMemberTypes) { + hasMembers = true; + break done; + } + + ReferenceBinding[] itsInterfaces = anInterface.superInterfaces(); + if (itsInterfaces != NoSuperInterfaces) { + if (++lastPosition == interfacesToVisit.length) + System.arraycopy( + interfacesToVisit, + 0, + interfacesToVisit = new ReferenceBinding[lastPosition * 2][], + 0, + lastPosition); + interfacesToVisit[lastPosition] = itsInterfaces; + } + } + } + } + + for (int i = 0; i <= lastPosition; i++) { + ReferenceBinding[] interfaces = interfacesToVisit[i]; + for (int j = 0, length = interfaces.length; j < length; j++) { + interfaces[j].tagBits &= ~InterfaceVisited; + if (!hasMembers) + interfaces[j].tagBits |= HasNoMemberTypes; + } + } + } + + if (!hasMembers) { + currentType = sourceType; + do { + currentType.tagBits |= HasNoMemberTypes; + } while ((currentType = currentType.superclass()) != null); + } + } + + private void connectMemberTypes() { + SourceTypeBinding sourceType = referenceContext.binding; + if (sourceType.memberTypes != NoMemberTypes) + for (int i = 0, size = sourceType.memberTypes.length; i < size; i++) + ((SourceTypeBinding) sourceType.memberTypes[i]).scope.connectTypeHierarchy(); + } + /* + Our current belief based on available JCK tests is: + inherited member types are visible as a potential superclass. + inherited interfaces are not visible when defining a superinterface. + + Error recovery story: + ensure the superclass is set to java.lang.Object if a problem is detected + resolving the superclass. + + Answer false if an error was reported against the sourceType. + */ + private boolean connectSuperclass() { + SourceTypeBinding sourceType = referenceContext.binding; + if (isJavaLangObject(sourceType)) { // handle the case of redefining java.lang.Object up front + sourceType.superclass = null; + sourceType.superInterfaces = NoSuperInterfaces; + if (referenceContext.superclass != null || referenceContext.superInterfaces != null) + problemReporter().objectCannotHaveSuperTypes(sourceType); + return true; // do not propagate Object's hierarchy problems down to every subtype + } + if (referenceContext.superclass == null) { + sourceType.superclass = getJavaLangObject(); + return !detectCycle(sourceType, sourceType.superclass, null); + } + ReferenceBinding superclass = findSupertype(referenceContext.superclass); + if (superclass != null) { // is null if a cycle was detected cycle + if (!superclass.isValidBinding()) { + problemReporter().invalidSuperclass(sourceType, referenceContext.superclass, superclass); + } else if (superclass.isInterface()) { + problemReporter().superclassMustBeAClass(sourceType, referenceContext.superclass, superclass); + } else if (superclass.isFinal()) { + problemReporter().classExtendFinalClass(sourceType, referenceContext.superclass, superclass); + } else { + // only want to reach here when no errors are reported + referenceContext.superclass.resolvedType = superclass; + sourceType.superclass = superclass; + return true; + } + } + sourceType.tagBits |= HierarchyHasProblems; + sourceType.superclass = getJavaLangObject(); + if ((sourceType.superclass.tagBits & BeginHierarchyCheck) == 0) + detectCycle(sourceType, sourceType.superclass, null); + return false; // reported some error against the source type + } + + /* + Our current belief based on available JCK 1.3 tests is: + inherited member types are visible as a potential superclass. + inherited interfaces are visible when defining a superinterface. + + Error recovery story: + ensure the superinterfaces contain only valid visible interfaces. + + Answer false if an error was reported against the sourceType. + */ + private boolean connectSuperInterfaces() { + SourceTypeBinding sourceType = referenceContext.binding; + sourceType.superInterfaces = NoSuperInterfaces; + if (referenceContext.superInterfaces == null) + return true; + if (isJavaLangObject(sourceType)) // already handled the case of redefining java.lang.Object + return true; + + boolean noProblems = true; + int length = referenceContext.superInterfaces.length; + ReferenceBinding[] interfaceBindings = new ReferenceBinding[length]; + int count = 0; + nextInterface : for (int i = 0; i < length; i++) { + ReferenceBinding superInterface = findSupertype(referenceContext.superInterfaces[i]); + if (superInterface == null) { // detected cycle + noProblems = false; + continue nextInterface; + } + if (!superInterface.isValidBinding()) { + problemReporter().invalidSuperinterface( + sourceType, + referenceContext.superInterfaces[i], + superInterface); + sourceType.tagBits |= HierarchyHasProblems; + noProblems = false; + continue nextInterface; + } + // Check for a duplicate interface once the name is resolved, otherwise we may be confused (ie : a.b.I and c.d.I) + for (int k = 0; k < count; k++) { + if (interfaceBindings[k] == superInterface) { + // should this be treated as a warning? + problemReporter().duplicateSuperinterface(sourceType, referenceContext, superInterface); + continue nextInterface; + } + } + if (superInterface.isClass()) { + problemReporter().superinterfaceMustBeAnInterface(sourceType, referenceContext, superInterface); + sourceType.tagBits |= HierarchyHasProblems; + noProblems = false; + continue nextInterface; + } + + referenceContext.superInterfaces[i].resolvedType = superInterface; + // only want to reach here when no errors are reported + interfaceBindings[count++] = superInterface; + } + // hold onto all correctly resolved superinterfaces + if (count > 0) { + if (count != length) + System.arraycopy(interfaceBindings, 0, interfaceBindings = new ReferenceBinding[count], 0, count); + sourceType.superInterfaces = interfaceBindings; + } + return noProblems; + } + + void connectTypeHierarchy() { + SourceTypeBinding sourceType = referenceContext.binding; + if ((sourceType.tagBits & BeginHierarchyCheck) == 0) { + boolean noProblems = true; + sourceType.tagBits |= BeginHierarchyCheck; + if (sourceType.isClass()) + noProblems &= connectSuperclass(); + noProblems &= connectSuperInterfaces(); + sourceType.tagBits |= EndHierarchyCheck; + if (noProblems && sourceType.isHierarchyInconsistent()) + problemReporter().hierarchyHasProblems(sourceType); + } + connectMemberTypes(); + checkForInheritedMemberTypes(sourceType); + } + + private void connectTypeHierarchyWithoutMembers() { + // must ensure the imports are resolved + if (parent instanceof CompilationUnitScope) { + if (((CompilationUnitScope) parent).imports == null) + ((CompilationUnitScope) parent).checkAndSetImports(); + } else if (parent instanceof ClassScope) { + // ensure that the enclosing type has already been checked + ((ClassScope) parent).connectTypeHierarchyWithoutMembers(); + } + + // double check that the hierarchy search has not already begun... + SourceTypeBinding sourceType = referenceContext.binding; + if ((sourceType.tagBits & BeginHierarchyCheck) != 0) + return; + + boolean noProblems = true; + sourceType.tagBits |= BeginHierarchyCheck; + if (sourceType.isClass()) + noProblems &= connectSuperclass(); + noProblems &= connectSuperInterfaces(); + sourceType.tagBits |= EndHierarchyCheck; + if (noProblems && sourceType.isHierarchyInconsistent()) + problemReporter().hierarchyHasProblems(sourceType); + } + + // Answer whether a cycle was found between the sourceType & the superType + private boolean detectCycle( + SourceTypeBinding sourceType, + ReferenceBinding superType, + TypeReference reference) { + if (sourceType == superType) { + problemReporter().hierarchyCircularity(sourceType, superType, reference); + sourceType.tagBits |= HierarchyHasProblems; + return true; + } + + if (superType.isBinaryBinding()) { + // force its superclass & superinterfaces to be found... 2 possibilities exist - the source type is included in the hierarchy of: + // - a binary type... this case MUST be caught & reported here + // - another source type... this case is reported against the other source type + boolean hasCycle = false; + if (superType.superclass() != null) { + if (sourceType == superType.superclass()) { + problemReporter().hierarchyCircularity(sourceType, superType, reference); + sourceType.tagBits |= HierarchyHasProblems; + superType.tagBits |= HierarchyHasProblems; + return true; + } + hasCycle |= detectCycle(sourceType, superType.superclass(), reference); + if ((superType.superclass().tagBits & HierarchyHasProblems) != 0) { + sourceType.tagBits |= HierarchyHasProblems; + superType.tagBits |= HierarchyHasProblems; // propagate down the hierarchy + } + } + + ReferenceBinding[] itsInterfaces = superType.superInterfaces(); + if (itsInterfaces != NoSuperInterfaces) { + for (int i = 0, length = itsInterfaces.length; i < length; i++) { + ReferenceBinding anInterface = itsInterfaces[i]; + if (sourceType == anInterface) { + problemReporter().hierarchyCircularity(sourceType, superType, reference); + sourceType.tagBits |= HierarchyHasProblems; + superType.tagBits |= HierarchyHasProblems; + return true; + } + hasCycle |= detectCycle(sourceType, anInterface, reference); + if ((anInterface.tagBits & HierarchyHasProblems) != 0) { + sourceType.tagBits |= HierarchyHasProblems; + superType.tagBits |= HierarchyHasProblems; + } + } + } + return hasCycle; + } + + if ((superType.tagBits & EndHierarchyCheck) == 0 + && (superType.tagBits & BeginHierarchyCheck) != 0) { + problemReporter().hierarchyCircularity(sourceType, superType, reference); + sourceType.tagBits |= HierarchyHasProblems; + superType.tagBits |= HierarchyHasProblems; + return true; + } + if ((superType.tagBits & BeginHierarchyCheck) == 0) + // ensure if this is a source superclass that it has already been checked + ((SourceTypeBinding) superType).scope.connectTypeHierarchyWithoutMembers(); + if ((superType.tagBits & HierarchyHasProblems) != 0) + sourceType.tagBits |= HierarchyHasProblems; + return false; + } + + private ReferenceBinding findSupertype(TypeReference typeReference) { + typeReference.aboutToResolve(this); // allows us to trap completion & selection nodes + char[][] compoundName = typeReference.getTypeName(); + compilationUnitScope().recordQualifiedReference(compoundName); + SourceTypeBinding sourceType = referenceContext.binding; + int size = compoundName.length; + int n = 1; + ReferenceBinding superType; + + // resolve the first name of the compoundName + if (CharOperation.equals(compoundName[0], sourceType.sourceName)) { + superType = sourceType; + // match against the sourceType even though nested members cannot be supertypes + } else { + Binding typeOrPackage = parent.getTypeOrPackage(compoundName[0], TYPE | PACKAGE); + if (typeOrPackage == null || !typeOrPackage.isValidBinding()) + return new ProblemReferenceBinding( + compoundName[0], + typeOrPackage == null ? NotFound : typeOrPackage.problemId()); + + boolean checkVisibility = false; + for (; n < size; n++) { + if (!(typeOrPackage instanceof PackageBinding)) + break; + PackageBinding packageBinding = (PackageBinding) typeOrPackage; + typeOrPackage = packageBinding.getTypeOrPackage(compoundName[n]); + if (typeOrPackage == null || !typeOrPackage.isValidBinding()) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, n + 1), + typeOrPackage == null ? NotFound : typeOrPackage.problemId()); + checkVisibility = true; + } + + // convert to a ReferenceBinding + if (typeOrPackage instanceof PackageBinding) // error, the compoundName is a packageName + return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, n), NotFound); + superType = (ReferenceBinding) typeOrPackage; + compilationUnitScope().recordTypeReference(superType); // to record supertypes + + if (checkVisibility + && n == size) { // if we're finished and know the final supertype then check visibility + if (!superType.canBeSeenBy(sourceType.fPackage)) + // its a toplevel type so just check package access + return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, n), superType, NotVisible); + } + } + // at this point we know we have a type but we have to look for cycles + while (true) { + // must detect cycles & force connection up the hierarchy... also handle cycles with binary types. + // must be guaranteed that the superType knows its entire hierarchy + if (detectCycle(sourceType, superType, typeReference)) + return null; // cycle error was already reported + + if (n >= size) + break; + + // retrieve the next member type + char[] typeName = compoundName[n++]; + superType = findMemberType(typeName, superType); + if (superType == null) + return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, n), NotFound); + if (!superType.isValidBinding()) { + superType.compoundName = CharOperation.subarray(compoundName, 0, n); + return superType; + } + } + return superType; + } + + /* Answer the problem reporter to use for raising new problems. + * + * Note that as a side-effect, this updates the current reference context + * (unit, type or method) in case the problem handler decides it is necessary + * to abort. + */ + public ProblemReporter problemReporter() { + MethodScope outerMethodScope; + if ((outerMethodScope = outerMostMethodScope()) == null) { + ProblemReporter problemReporter = referenceCompilationUnit().problemReporter; + problemReporter.referenceContext = referenceContext; + return problemReporter; + } else { + return outerMethodScope.problemReporter(); + } + } + + /* Answer the reference type of this scope. + * It is the nearest enclosing type of this scope. + */ + public TypeDeclaration referenceType() { + return referenceContext; + } + + public String toString() { + if (referenceContext != null) + return "--- Class Scope ---\n\n" //$NON-NLS-1$ + +referenceContext.binding.toString(); + else + return "--- Class Scope ---\n\n Binding not initialized" ; //$NON-NLS-1$ + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/CompilationUnitScope.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/CompilationUnitScope.java new file mode 100644 index 0000000..d50f6f7 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/CompilationUnitScope.java @@ -0,0 +1,576 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import java.util.ArrayList; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; +import net.sourceforge.phpdt.internal.compiler.util.CompoundNameVector; +import net.sourceforge.phpdt.internal.compiler.util.HashtableOfType; +import net.sourceforge.phpdt.internal.compiler.util.ObjectVector; +import net.sourceforge.phpdt.internal.compiler.util.SimpleNameVector; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; + +public class CompilationUnitScope extends Scope { + + public LookupEnvironment environment; + public CompilationUnitDeclaration referenceContext; + public char[][] currentPackageName; + public PackageBinding fPackage; + public ImportBinding[] imports; + + public SourceTypeBinding[] topLevelTypes; + + private CompoundNameVector qualifiedReferences; + private SimpleNameVector simpleNameReferences; + private ObjectVector referencedTypes; + + HashtableOfType constantPoolNameUsage; + + public CompilationUnitScope(CompilationUnitDeclaration unit, LookupEnvironment environment) { + super(COMPILATION_UNIT_SCOPE, null); + this.environment = environment; + this.referenceContext = unit; + unit.scope = this; + this.currentPackageName = unit.currentPackage == null ? CharOperation.NO_CHAR_CHAR : unit.currentPackage.tokens; + + // if (environment.options.produceReferenceInfo) { + // this.qualifiedReferences = new CompoundNameVector(); + // this.simpleNameReferences = new SimpleNameVector(); + // this.referencedTypes = new ObjectVector(); + // } else { + this.qualifiedReferences = null; // used to test if dependencies should be recorded + this.simpleNameReferences = null; + this.referencedTypes = null; + // } + } + void buildFieldsAndMethods() { + for (int i = 0, length = topLevelTypes.length; i < length; i++) + topLevelTypes[i].scope.buildFieldsAndMethods(); + } + void buildTypeBindings() { + if (referenceContext.compilationResult.compilationUnit != null) { + char[][] expectedPackageName = referenceContext.compilationResult.compilationUnit.getPackageName(); + if (expectedPackageName != null && !CharOperation.equals(currentPackageName, expectedPackageName)) { + + // only report if the unit isn't structurally empty + // if (referenceContext.currentPackage != null + // || referenceContext.types != null + // || referenceContext.imports != null) { + // problemReporter().packageIsNotExpectedPackage(referenceContext); + // } + currentPackageName = expectedPackageName.length == 0 ? CharOperation.NO_CHAR_CHAR : expectedPackageName; + } + } + if (currentPackageName == CharOperation.NO_CHAR_CHAR) { + if ((fPackage = environment.defaultPackage) == null) { + problemReporter().mustSpecifyPackage(referenceContext); + return; + } + } else { + if ((fPackage = environment.createPackage(currentPackageName)) == null) { +// problemReporter().packageCollidesWithType(referenceContext); + return; + } + recordQualifiedReference(currentPackageName); // always dependent on your own package + } + + // Skip typeDeclarations which know of previously reported errors + ArrayList types = referenceContext.types; + int typeLength = (types == null) ? 0 : types.size(); + topLevelTypes = new SourceTypeBinding[typeLength]; + int count = 0; + nextType : for (int i = 0; i < typeLength; i++) { + if (types.get(i) instanceof TypeDeclaration) { + TypeDeclaration typeDecl = (TypeDeclaration) types.get(i); + ReferenceBinding typeBinding = fPackage.getType0(typeDecl.name); + recordSimpleReference(typeDecl.name); // needed to detect collision cases + if (typeBinding != null && !(typeBinding instanceof UnresolvedReferenceBinding)) { + // if a type exists, it must be a valid type - cannot be a NotFound problem type + // unless its an unresolved type which is now being defined + problemReporter().duplicateTypes(referenceContext, typeDecl); + continue nextType; + } + if (fPackage != environment.defaultPackage && fPackage.getPackage(typeDecl.name) != null) { + // if a package exists, it must be a valid package - cannot be a NotFound problem package + problemReporter().typeCollidesWithPackage(referenceContext, typeDecl); + continue nextType; + } + + if ((typeDecl.modifiers & AccPublic) != 0) { + char[] mainTypeName; + if ((mainTypeName = referenceContext.getMainTypeName()) != null + // mainTypeName == null means that implementor of ICompilationUnit decided to return null + && !CharOperation.equals(mainTypeName, typeDecl.name)) { + problemReporter().publicClassMustMatchFileName(referenceContext, typeDecl); + continue nextType; + } + } + + ClassScope child = new ClassScope(this, typeDecl); + SourceTypeBinding type = child.buildType(null, fPackage); + if (type != null) { + topLevelTypes[count++] = type; + } + } + } + + // shrink topLevelTypes... only happens if an error was reported + if (count != topLevelTypes.length) + System.arraycopy(topLevelTypes, 0, topLevelTypes = new SourceTypeBinding[count], 0, count); + } + void checkAndSetImports() { + // initialize the default imports if necessary... share the default java.lang.* import + if (environment.defaultImports == null) { + Binding importBinding = environment.getTopLevelPackage(JAVA); + if (importBinding != null) + importBinding = ((PackageBinding) importBinding).getTypeOrPackage(JAVA_LANG[1]); + + // abort if java.lang cannot be found... + if (importBinding == null || !importBinding.isValidBinding()) + problemReporter().isClassPathCorrect(JAVA_LANG_OBJECT, referenceCompilationUnit()); + + environment.defaultImports = new ImportBinding[] { new ImportBinding(JAVA_LANG, true, importBinding, null)}; + } + if (referenceContext.imports == null) { + imports = environment.defaultImports; + return; + } + + // allocate the import array, add java.lang.* by default + int numberOfStatements = referenceContext.imports.length; + int numberOfImports = numberOfStatements + 1; + for (int i = 0; i < numberOfStatements; i++) { + ImportReference importReference = referenceContext.imports[i]; + if (importReference.onDemand && CharOperation.equals(JAVA_LANG, importReference.tokens)) { + numberOfImports--; + break; + } + } + ImportBinding[] resolvedImports = new ImportBinding[numberOfImports]; + resolvedImports[0] = environment.defaultImports[0]; + int index = 1; + + nextImport : for (int i = 0; i < numberOfStatements; i++) { + ImportReference importReference = referenceContext.imports[i]; + char[][] compoundName = importReference.tokens; + + // skip duplicates or imports of the current package + for (int j = 0; j < index; j++) + if (resolvedImports[j].onDemand == importReference.onDemand) + if (CharOperation.equals(compoundName, resolvedImports[j].compoundName)) + continue nextImport; + if (importReference.onDemand == true) + if (CharOperation.equals(compoundName, currentPackageName)) + continue nextImport; + + if (importReference.onDemand) { + Binding importBinding = findOnDemandImport(compoundName); + if (!importBinding.isValidBinding()) + continue nextImport; // we report all problems in faultInImports() + resolvedImports[index++] = new ImportBinding(compoundName, true, importBinding, importReference); + } else { + resolvedImports[index++] = new ImportBinding(compoundName, false, null, importReference); + } + } + + // shrink resolvedImports... only happens if an error was reported + if (resolvedImports.length > index) + System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[index], 0, index); + imports = resolvedImports; + } + /* + * INTERNAL USE-ONLY + * Innerclasses get their name computed as they are generated, since some may not + * be actually outputed if sitting inside unreachable code. + */ + public char[] computeConstantPoolName(LocalTypeBinding localType) { + if (localType.constantPoolName() != null) { + return localType.constantPoolName(); + } + // delegates to the outermost enclosing classfile, since it is the only one with a global vision of its innertypes. + + if (constantPoolNameUsage == null) + constantPoolNameUsage = new HashtableOfType(); + + ReferenceBinding outerMostEnclosingType = localType.scope.outerMostClassScope().enclosingSourceType(); + + // ensure there is not already such a local type name defined by the user + int index = 0; + char[] candidateName; + while (true) { + if (localType.isMemberType()) { + if (index == 0) { + candidateName = CharOperation.concat(localType.enclosingType().constantPoolName(), localType.sourceName, '$'); + } else { + // in case of collision, then member name gets extra $1 inserted + // e.g. class X { { class L{} new X(){ class L{} } } } + candidateName = + CharOperation.concat(localType.enclosingType().constantPoolName(), '$', String.valueOf(index).toCharArray(), '$', localType.sourceName); + } + } else if (localType.isAnonymousType()) { + candidateName = CharOperation.concat(outerMostEnclosingType.constantPoolName(), String.valueOf(index + 1).toCharArray(), '$'); + } else { + candidateName = + CharOperation.concat(outerMostEnclosingType.constantPoolName(), '$', String.valueOf(index + 1).toCharArray(), '$', localType.sourceName); + } + if (constantPoolNameUsage.get(candidateName) != null) { + index++; + } else { + constantPoolNameUsage.put(candidateName, localType); + break; + } + } + return candidateName; + } + + void connectTypeHierarchy() { + for (int i = 0, length = topLevelTypes.length; i < length; i++) + topLevelTypes[i].scope.connectTypeHierarchy(); + } + void faultInImports() { + if (referenceContext.imports == null) + return; + + // collect the top level type names if a single type import exists + int numberOfStatements = referenceContext.imports.length; + HashtableOfType typesBySimpleNames = null; + for (int i = 0; i < numberOfStatements; i++) { + if (!referenceContext.imports[i].onDemand) { + typesBySimpleNames = new HashtableOfType(topLevelTypes.length + numberOfStatements); + for (int j = 0, length = topLevelTypes.length; j < length; j++) + typesBySimpleNames.put(topLevelTypes[j].sourceName, topLevelTypes[j]); + break; + } + } + + // allocate the import array, add java.lang.* by default + int numberOfImports = numberOfStatements + 1; + for (int i = 0; i < numberOfStatements; i++) { + ImportReference importReference = referenceContext.imports[i]; + if (importReference.onDemand && CharOperation.equals(JAVA_LANG, importReference.tokens)) { + numberOfImports--; + break; + } + } + ImportBinding[] resolvedImports = new ImportBinding[numberOfImports]; + resolvedImports[0] = environment.defaultImports[0]; + int index = 1; + + nextImport : for (int i = 0; i < numberOfStatements; i++) { + ImportReference importReference = referenceContext.imports[i]; + char[][] compoundName = importReference.tokens; + + // skip duplicates or imports of the current package + for (int j = 0; j < index; j++) + if (resolvedImports[j].onDemand == importReference.onDemand) + if (CharOperation.equals(compoundName, resolvedImports[j].compoundName)) { + problemReporter().unusedImport(importReference); // since skipped, must be reported now + continue nextImport; + } + if (importReference.onDemand == true) + if (CharOperation.equals(compoundName, currentPackageName)) { + problemReporter().unusedImport(importReference); // since skipped, must be reported now + continue nextImport; + } + if (importReference.onDemand) { + Binding importBinding = findOnDemandImport(compoundName); + if (!importBinding.isValidBinding()) { + problemReporter().importProblem(importReference, importBinding); + continue nextImport; + } + resolvedImports[index++] = new ImportBinding(compoundName, true, importBinding, importReference); + } else { + Binding typeBinding = findSingleTypeImport(compoundName); + if (!typeBinding.isValidBinding()) { + problemReporter().importProblem(importReference, typeBinding); + continue nextImport; + } + if (typeBinding instanceof PackageBinding) { + problemReporter().cannotImportPackage(importReference); + continue nextImport; + } + if (typeBinding instanceof ReferenceBinding) { + ReferenceBinding referenceBinding = (ReferenceBinding) typeBinding; + if (importReference.isTypeUseDeprecated(referenceBinding, this)) { + problemReporter().deprecatedType((TypeBinding) typeBinding, importReference); + } + } + ReferenceBinding existingType = typesBySimpleNames.get(compoundName[compoundName.length - 1]); + if (existingType != null) { + // duplicate test above should have caught this case, but make sure + if (existingType == typeBinding) { + continue nextImport; + } + // either the type collides with a top level type or another imported type + for (int j = 0, length = topLevelTypes.length; j < length; j++) { + if (CharOperation.equals(topLevelTypes[j].sourceName, existingType.sourceName)) { + problemReporter().conflictingImport(importReference); + continue nextImport; + } + } + problemReporter().duplicateImport(importReference); + continue nextImport; + } + resolvedImports[index++] = new ImportBinding(compoundName, false, typeBinding, importReference); + typesBySimpleNames.put(compoundName[compoundName.length - 1], (ReferenceBinding) typeBinding); + } + } + + // shrink resolvedImports... only happens if an error was reported + if (resolvedImports.length > index) + System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[index], 0, index); + imports = resolvedImports; + } + public void faultInTypes() { + faultInImports(); + if (topLevelTypes==null) { + topLevelTypes = new SourceTypeBinding[0]; + } + for (int i = 0, length = topLevelTypes.length; i < length; i++) + topLevelTypes[i].faultInTypesForFieldsAndMethods(); + } + private Binding findOnDemandImport(char[][] compoundName) { + recordQualifiedReference(compoundName); + + Binding binding = environment.getTopLevelPackage(compoundName[0]); + int i = 1; + int length = compoundName.length; + foundNothingOrType : if (binding != null) { + PackageBinding packageBinding = (PackageBinding) binding; + while (i < length) { + binding = packageBinding.getTypeOrPackage(compoundName[i++]); + if (binding == null || !binding.isValidBinding()) { + binding = null; + break foundNothingOrType; + } + if (!(binding instanceof PackageBinding)) + break foundNothingOrType; + + packageBinding = (PackageBinding) binding; + } + return packageBinding; + } + + ReferenceBinding type; + if (binding == null) { + // if (environment.defaultPackage == null + // || environment.options.complianceLevel >= CompilerOptions.JDK1_4){ + // return new ProblemReferenceBinding( + // CharOperation.subarray(compoundName, 0, i), + // NotFound); + // } + type = findType(compoundName[0], environment.defaultPackage, environment.defaultPackage); + if (type == null || !type.isValidBinding()) + return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), NotFound); + i = 1; // reset to look for member types inside the default package type + } else { + type = (ReferenceBinding) binding; + } + + for (; i < length; i++) { + if (!type.canBeSeenBy(fPackage)) { + return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), type, NotVisible); + } + // does not look for inherited member types on purpose + if ((type = type.getMemberType(compoundName[i])) == null) { + return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i + 1), NotFound); + } + } + if (!type.canBeSeenBy(fPackage)) + return new ProblemReferenceBinding(compoundName, type, NotVisible); + return type; + } + private Binding findSingleTypeImport(char[][] compoundName) { + if (compoundName.length == 1) { + // findType records the reference + // the name cannot be a package + // if (environment.defaultPackage == null + // || environment.options.complianceLevel >= CompilerOptions.JDK1_4) + // return new ProblemReferenceBinding(compoundName, NotFound); + ReferenceBinding typeBinding = findType(compoundName[0], environment.defaultPackage, fPackage); + if (typeBinding == null) + return new ProblemReferenceBinding(compoundName, NotFound); + else + return typeBinding; + } + return findOnDemandImport(compoundName); + } + /* Answer the problem reporter to use for raising new problems. + * + * Note that as a side-effect, this updates the current reference context + * (unit, type or method) in case the problem handler decides it is necessary + * to abort. + */ + + public ProblemReporter problemReporter() { + ProblemReporter problemReporter = referenceContext.problemReporter; + problemReporter.referenceContext = referenceContext; + return problemReporter; + } + + /* + What do we hold onto: + + 1. when we resolve 'a.b.c', say we keep only 'a.b.c' + & when we fail to resolve 'c' in 'a.b', lets keep 'a.b.c' + THEN when we come across a new/changed/removed item named 'a.b.c', + we would find all references to 'a.b.c' + -> This approach fails because every type is resolved in every onDemand import to + detect collision cases... so the references could be 10 times bigger than necessary. + + 2. when we resolve 'a.b.c', lets keep 'a.b' & 'c' + & when we fail to resolve 'c' in 'a.b', lets keep 'a.b' & 'c' + THEN when we come across a new/changed/removed item named 'a.b.c', + we would find all references to 'a.b' & 'c' + -> This approach does not have a space problem but fails to handle collision cases. + What happens if a type is added named 'a.b'? We would search for 'a' & 'b' but + would not find a match. + + 3. when we resolve 'a.b.c', lets keep 'a', 'a.b' & 'a', 'b', 'c' + & when we fail to resolve 'c' in 'a.b', lets keep 'a', 'a.b' & 'a', 'b', 'c' + THEN when we come across a new/changed/removed item named 'a.b.c', + we would find all references to 'a.b' & 'c' + OR 'a.b' -> 'a' & 'b' + OR 'a' -> '' & 'a' + -> As long as each single char[] is interned, we should not have a space problem + and can handle collision cases. + + 4. when we resolve 'a.b.c', lets keep 'a.b' & 'a', 'b', 'c' + & when we fail to resolve 'c' in 'a.b', lets keep 'a.b' & 'a', 'b', 'c' + THEN when we come across a new/changed/removed item named 'a.b.c', + we would find all references to 'a.b' & 'c' + OR 'a.b' -> 'a' & 'b' in the simple name collection + OR 'a' -> 'a' in the simple name collection + -> As long as each single char[] is interned, we should not have a space problem + and can handle collision cases. + */ + void recordQualifiedReference(char[][] qualifiedName) { + if (qualifiedReferences == null) + return; // not recording dependencies + + int length = qualifiedName.length; + if (length > 1) { + while (!qualifiedReferences.contains(qualifiedName)) { + qualifiedReferences.add(qualifiedName); + if (length == 2) { + recordSimpleReference(qualifiedName[0]); + recordSimpleReference(qualifiedName[1]); + return; + } + length--; + recordSimpleReference(qualifiedName[length]); + System.arraycopy(qualifiedName, 0, qualifiedName = new char[length][], 0, length); + } + } else if (length == 1) { + recordSimpleReference(qualifiedName[0]); + } + } + void recordReference(char[][] qualifiedEnclosingName, char[] simpleName) { + recordQualifiedReference(qualifiedEnclosingName); + recordSimpleReference(simpleName); + } + void recordSimpleReference(char[] simpleName) { + if (simpleNameReferences == null) + return; // not recording dependencies + + if (!simpleNameReferences.contains(simpleName)) + simpleNameReferences.add(simpleName); + } + void recordTypeReference(TypeBinding type) { + if (referencedTypes == null) + return; // not recording dependencies + + if (type.isArrayType()) + type = ((ArrayBinding) type).leafComponentType; + if (!type.isBaseType() && !referencedTypes.containsIdentical(type)) + referencedTypes.add(type); + } + void recordTypeReferences(TypeBinding[] types) { + if (qualifiedReferences == null) + return; // not recording dependencies + if (types == null || types.length == 0) + return; + + for (int i = 0, max = types.length; i < max; i++) { + // No need to record supertypes of method arguments & thrown exceptions, just the compoundName + // If a field/method is retrieved from such a type then a separate call does the job + TypeBinding type = types[i]; + if (type.isArrayType()) + type = ((ArrayBinding) type).leafComponentType; + if (!type.isBaseType()) { + ReferenceBinding actualType = (ReferenceBinding) type; + if (!actualType.isLocalType()) + recordQualifiedReference(actualType.isMemberType() ? CharOperation.splitOn('.', actualType.readableName()) : actualType.compoundName); + } + } + } + Binding resolveSingleTypeImport(ImportBinding importBinding) { + if (importBinding.resolvedImport == null) { + importBinding.resolvedImport = findSingleTypeImport(importBinding.compoundName); + if (!importBinding.resolvedImport.isValidBinding() || importBinding.resolvedImport instanceof PackageBinding) { + if (this.imports != null) { + ImportBinding[] newImports = new ImportBinding[imports.length - 1]; + for (int i = 0, n = 0, max = this.imports.length; i < max; i++) + if (this.imports[i] != importBinding) { + newImports[n++] = this.imports[i]; + } + this.imports = newImports; + } + return null; + } + } + return importBinding.resolvedImport; + } + public void storeDependencyInfo() { + // add the type hierarchy of each referenced type + // cannot do early since the hierarchy may not be fully resolved + for (int i = 0; i < referencedTypes.size; i++) { // grows as more types are added + ReferenceBinding type = (ReferenceBinding) referencedTypes.elementAt(i); + if (!type.isLocalType()) { + recordQualifiedReference(type.isMemberType() ? CharOperation.splitOn('.', type.readableName()) : type.compoundName); + ReferenceBinding enclosing = type.enclosingType(); + if (enclosing != null && !referencedTypes.containsIdentical(enclosing)) + referencedTypes.add(enclosing); // to record its supertypes + } + ReferenceBinding superclass = type.superclass(); + if (superclass != null && !referencedTypes.containsIdentical(superclass)) + referencedTypes.add(superclass); // to record its supertypes + ReferenceBinding[] interfaces = type.superInterfaces(); + if (interfaces != null && interfaces.length > 0) + for (int j = 0, length = interfaces.length; j < length; j++) + if (!referencedTypes.containsIdentical(interfaces[j])) + referencedTypes.add(interfaces[j]); // to record its supertypes + } + + int size = qualifiedReferences.size; + char[][][] qualifiedRefs = new char[size][][]; + for (int i = 0; i < size; i++) + qualifiedRefs[i] = qualifiedReferences.elementAt(i); + referenceContext.compilationResult.qualifiedReferences = qualifiedRefs; + + size = simpleNameReferences.size; + char[][] simpleRefs = new char[size][]; + for (int i = 0; i < size; i++) + simpleRefs[i] = simpleNameReferences.elementAt(i); + referenceContext.compilationResult.simpleNameReferences = simpleRefs; + } + public String toString() { + return "--- CompilationUnit Scope : " + new String(referenceContext.getFileName()); //$NON-NLS-1$ + } + public void verifyMethods(MethodVerifier verifier) { + for (int i = 0, length = topLevelTypes.length; i < length; i++) + topLevelTypes[i].verifyMethods(verifier); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/CompilerModifiers.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/CompilerModifiers.java new file mode 100644 index 0000000..0e881bc --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/CompilerModifiers.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.internal.compiler.env.IConstants; + +public interface CompilerModifiers extends IConstants { // modifier constant + // those constants are depending upon ClassFileConstants (relying that classfiles only use the 16 lower bits) + final int AccDefault = 0; + final int AccJustFlag = 0xFFFF; + final int AccCatchesExceptions = 0x10000; // bit17 + final int AccThrowsExceptions = 0x20000; // bit18 - also IConstants.AccSynthetic + final int AccProblem = 0x40000; // bit19 + final int AccFromClassFile = 0x80000; // bit20 + final int AccIsConstantValue = 0x80000; // bit20 + final int AccDefaultAbstract = 0x80000; // bit20 + // bit21 - IConstants.AccDeprecated + final int AccDeprecatedImplicitly = 0x200000; // bit22 to record whether deprecated itself or contained by a deprecated type + final int AccAlternateModifierProblem = 0x400000; // bit23 + final int AccModifierProblem = 0x800000; // bit24 + final int AccSemicolonBody = 0x1000000; // bit25 + final int AccUnresolved = 0x2000000; // bit26 + final int AccClearPrivateModifier = 0x4000000; // bit27 might be requested during private access emulation + final int AccBlankFinal = 0x4000000; // bit27 for blank final variables + final int AccPrivateUsed = 0x8000000; // bit28 used to diagnose unused private members + final int AccVisibilityMASK = AccPublic | AccProtected | AccPrivate; + + final int AccOverriding = 0x10000000; // bit29 to record fact a method overrides another one + final int AccImplementing = 0x20000000; // bit30 to record fact a method implements another one (it is concrete and overrides an abstract one) +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/FieldBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/FieldBinding.java new file mode 100644 index 0000000..1884c48 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/FieldBinding.java @@ -0,0 +1,211 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration; + + + +public class FieldBinding extends VariableBinding { + public ReferenceBinding declaringClass; +protected FieldBinding() { +} +public FieldBinding(char[] name, TypeBinding type, int modifiers, ReferenceBinding declaringClass, Constant constant) { + this.modifiers = modifiers; + this.type = type; + this.name = name; + this.declaringClass = declaringClass; + this.constant = constant; + + // propagate the deprecated modifier + if (this.declaringClass != null) + if (this.declaringClass.isViewedAsDeprecated() && !isDeprecated()) + this.modifiers |= AccDeprecatedImplicitly; +} +public FieldBinding(FieldDeclaration field, TypeBinding type, ReferenceBinding declaringClass) { + this(field.name, type, field.modifiers, declaringClass, null); + + field.binding = this; +} +// special API used to change field declaring class for runtime visibility check +public FieldBinding(FieldBinding initialFieldBinding, ReferenceBinding declaringClass) { + this.modifiers = initialFieldBinding.modifiers; + this.type = initialFieldBinding.type; + this.name = initialFieldBinding.name; + this.declaringClass = declaringClass; + this.constant = initialFieldBinding.constant; + this.id = initialFieldBinding.id; +} +/* API +* Answer the receiver's binding type from Binding.BindingID. +*/ + +public final int bindingType() { + return FIELD; +} +/* Answer true if the receiver is visible to the type provided by the scope. +* InvocationSite implements isSuperAccess() to provide additional information +* if the receiver is protected. +* +* NOTE: Cannot invoke this method with a compilation unit scope. +*/ + +public final boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) { + if (isPublic()) return true; + + SourceTypeBinding invocationType = scope.enclosingSourceType(); + if (invocationType == declaringClass && invocationType == receiverType) return true; + + if (isProtected()) { + // answer true if the invocationType is the declaringClass or they are in the same package + // OR the invocationType is a subclass of the declaringClass + // AND the receiverType is the invocationType or its subclass + // OR the method is a static method accessed directly through a type + // OR previous assertions are true for one of the enclosing type + if (invocationType == declaringClass) return true; + if (invocationType.fPackage == declaringClass.fPackage) return true; + + ReferenceBinding currentType = invocationType; + int depth = 0; + do { + if (declaringClass.isSuperclassOf(currentType)) { + if (invocationSite.isSuperAccess()){ + return true; + } + // receiverType can be an array binding in one case... see if you can change it + if (receiverType instanceof ArrayBinding){ + return false; + } + if (isStatic()){ + return true; // see 1FMEPDL - return invocationSite.isTypeAccess(); + } + if (currentType == receiverType || currentType.isSuperclassOf((ReferenceBinding) receiverType)){ + if (depth > 0) invocationSite.setDepth(depth); + return true; + } + } + depth++; + currentType = currentType.enclosingType(); + } while (currentType != null); + return false; + } + + if (isPrivate()) { + // answer true if the receiverType is the declaringClass + // AND the invocationType and the declaringClass have a common enclosingType + if (receiverType != declaringClass) return false; + + if (invocationType != declaringClass) { + ReferenceBinding outerInvocationType = invocationType; + ReferenceBinding temp = outerInvocationType.enclosingType(); + while (temp != null) { + outerInvocationType = temp; + temp = temp.enclosingType(); + } + + ReferenceBinding outerDeclaringClass = declaringClass; + temp = outerDeclaringClass.enclosingType(); + while (temp != null) { + outerDeclaringClass = temp; + temp = temp.enclosingType(); + } + if (outerInvocationType != outerDeclaringClass) return false; + } + return true; + } + + // isDefault() + if (invocationType.fPackage != declaringClass.fPackage) return false; + + // receiverType can be an array binding in one case... see if you can change it + if (receiverType instanceof ArrayBinding) + return false; + ReferenceBinding type = (ReferenceBinding) receiverType; + PackageBinding declaringPackage = declaringClass.fPackage; + do { + if (declaringClass == type) return true; + if (declaringPackage != type.fPackage) return false; + } while ((type = type.superclass()) != null); + return false; +} +public final int getAccessFlags() { + return modifiers & AccJustFlag; +} + +/* Answer true if the receiver has default visibility +*/ + +public final boolean isDefault() { + return !isPublic() && !isProtected() && !isPrivate(); +} +/* Answer true if the receiver is a deprecated field +*/ + +public final boolean isDeprecated() { + return (modifiers & AccDeprecated) != 0; +} +/* Answer true if the receiver has private visibility +*/ + +public final boolean isPrivate() { + return (modifiers & AccPrivate) != 0; +} +/* Answer true if the receiver has private visibility and is used locally +*/ + +public final boolean isPrivateUsed() { + return (modifiers & AccPrivateUsed) != 0; +} +/* Answer true if the receiver has protected visibility +*/ + +public final boolean isProtected() { + return (modifiers & AccProtected) != 0; +} +/* Answer true if the receiver has public visibility +*/ + +public final boolean isPublic() { + return (modifiers & AccPublic) != 0; +} +/* Answer true if the receiver is a static field +*/ + +public final boolean isStatic() { + return (modifiers & AccStatic) != 0; +} +/* Answer true if the receiver is not defined in the source of the declaringClass +*/ + +//public final boolean isSynthetic() { +// return (modifiers & AccSynthetic) != 0; +//} +/* Answer true if the receiver is a transient field +*/ + +//public final boolean isTransient() { +// return (modifiers & AccTransient) != 0; +//} +/* Answer true if the receiver's declaring type is deprecated (or any of its enclosing types) +*/ + +public final boolean isViewedAsDeprecated() { + return (modifiers & AccDeprecated) != 0 || + (modifiers & AccDeprecatedImplicitly) != 0; +} +/* Answer true if the receiver is a volatile field +*/ + +//public final boolean isVolatile() { +// return (modifiers & AccVolatile) != 0; +//} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ImportBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ImportBinding.java new file mode 100644 index 0000000..8fc5dce --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ImportBinding.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference; + +public class ImportBinding extends Binding { + public char[][] compoundName; + public boolean onDemand; + public ImportReference reference; + + Binding resolvedImport; // must ensure the import is resolved + +public ImportBinding(char[][] compoundName, boolean isOnDemand, Binding binding, ImportReference reference) { + this.compoundName = compoundName; + this.onDemand = isOnDemand; + this.resolvedImport = binding; + this.reference = reference; +} +/* API +* Answer the receiver's binding type from Binding.BindingID. +*/ + +public final int bindingType() { + return IMPORT; +} +public char[] readableName() { + if (onDemand) + return CharOperation.concat(CharOperation.concatWith(compoundName, '.'), ".*".toCharArray()); //$NON-NLS-1$ + else + return CharOperation.concatWith(compoundName, '.'); +} +public String toString() { + return "import : " + new String(readableName()); //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/InnerEmulationDependency.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/InnerEmulationDependency.java new file mode 100644 index 0000000..0a7071d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/InnerEmulationDependency.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +public class InnerEmulationDependency{ + + public BlockScope scope; + public boolean wasEnclosingInstanceSupplied; + + public InnerEmulationDependency(BlockScope scope, boolean wasEnclosingInstanceSupplied) { + this.scope = scope; + this.wasEnclosingInstanceSupplied = wasEnclosingInstanceSupplied; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/InvocationSite.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/InvocationSite.java new file mode 100644 index 0000000..af3ec22 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/InvocationSite.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +public interface InvocationSite { + boolean isSuperAccess(); + boolean isTypeAccess(); + void setDepth(int depth); + void setFieldIndex(int depth); + + // in case the receiver type does not match the actual receiver type + // e.g. pkg.Type.C (receiver type of C is type of source context, + // but actual receiver type is pkg.Type) + // e.g2. in presence of implicit access to enclosing type + void setActualReceiverType(ReferenceBinding receiverType); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/LocalTypeBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/LocalTypeBinding.java new file mode 100644 index 0000000..73c9e06 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/LocalTypeBinding.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpeclipse.internal.compiler.ast.AnonymousLocalTypeDeclaration; + +public final class LocalTypeBinding extends NestedTypeBinding { + final static char[] LocalTypePrefix = { '$', 'L', 'o', 'c', 'a', 'l', '$' }; + + private InnerEmulationDependency[] dependents; + ArrayBinding[] localArrayBindings; // used to cache array bindings of various dimensions for this local type + +public LocalTypeBinding(ClassScope scope, SourceTypeBinding enclosingType) { + super( + new char[][] {CharOperation.concat(LocalTypePrefix, scope.referenceContext.name)}, + scope, + enclosingType); + + if (this.sourceName == AnonymousLocalTypeDeclaration.ANONYMOUS_EMPTY_NAME) + this.tagBits |= AnonymousTypeMask; + else + this.tagBits |= LocalTypeMask; +} +/* Record a dependency onto a source target type which may be altered +* by the end of the innerclass emulation. Later on, we will revisit +* all its dependents so as to update them (see updateInnerEmulationDependents()). +*/ + +public void addInnerEmulationDependent(BlockScope scope, boolean wasEnclosingInstanceSupplied) { + int index; + if (dependents == null) { + index = 0; + dependents = new InnerEmulationDependency[1]; + } else { + index = dependents.length; + for (int i = 0; i < index; i++) + if (dependents[i].scope == scope) + return; // already stored + System.arraycopy(dependents, 0, (dependents = new InnerEmulationDependency[index + 1]), 0, index); + } + dependents[index] = new InnerEmulationDependency(scope, wasEnclosingInstanceSupplied); + // System.out.println("Adding dependency: "+ new String(scope.enclosingType().readableName()) + " --> " + new String(this.readableName())); +} +/* Answer the receiver's constant pool name. +* +* NOTE: This method should only be used during/after code gen. +*/ + +public char[] constantPoolName() /* java/lang/Object */ { + return constantPoolName; +} + +ArrayBinding createArrayType(int dimensionCount) { + if (localArrayBindings == null) { + localArrayBindings = new ArrayBinding[] {new ArrayBinding(this, dimensionCount)}; + return localArrayBindings[0]; + } + + // find the cached array binding for this dimensionCount (if any) + int length = localArrayBindings.length; + for (int i = 0; i < length; i++) + if (localArrayBindings[i].dimensions == dimensionCount) + return localArrayBindings[i]; + + // no matching array + System.arraycopy(localArrayBindings, 0, localArrayBindings = new ArrayBinding[length + 1], 0, length); + return localArrayBindings[length] = new ArrayBinding(this, dimensionCount); +} + +public char[] readableName() { + if (isAnonymousType()) { + if (superInterfaces == NoSuperInterfaces) + return ("<"+Util.bind("binding.subclass",new String(superclass.readableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$ + else + return ("<"+Util.bind("binding.implementation",new String(superInterfaces[0].readableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$ + } else if (isMemberType()) { + return CharOperation.concat(enclosingType().readableName(), sourceName, '.'); + } else { + return sourceName; + } +} + +public char[] shortReadableName() { + if (isAnonymousType()) { + if (superInterfaces == NoSuperInterfaces) + return ("<"+Util.bind("binding.subclass",new String(superclass.shortReadableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$ + else + return ("<"+Util.bind("binding.implementation",new String(superInterfaces[0].shortReadableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$ + } else if (isMemberType()) { + return CharOperation.concat(enclosingType().shortReadableName(), sourceName, '.'); + } else { + return sourceName; + } +} + +// Record that the type is a local member type +public void setAsMemberType() { + tagBits |= MemberTypeMask; +} + +public void setConstantPoolName(char[] computedConstantPoolName) /* java/lang/Object */ { + this.constantPoolName = computedConstantPoolName; +} + +public char[] sourceName() { + if (isAnonymousType()) { + //return readableName(); + if (superInterfaces == NoSuperInterfaces) + return ("<"+Util.bind("binding.subclass",new String(superclass.sourceName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$ + else + return ("<"+Util.bind("binding.implementation",new String(superInterfaces[0].sourceName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$ + + } else + return sourceName; +} +public String toString() { + if (isAnonymousType()) + return "Anonymous type : " + super.toString(); //$NON-NLS-1$ + if (isMemberType()) + return "Local member type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$ + return "Local type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$ +} +/* Trigger the dependency mechanism forcing the innerclass emulation +* to be propagated to all dependent source types. +*/ + +public void updateInnerEmulationDependents() { + if (dependents != null) { + for (int i = 0; i < dependents.length; i++) { + InnerEmulationDependency dependency = dependents[i]; + // System.out.println("Updating " + new String(this.readableName()) + " --> " + new String(dependency.scope.enclosingType().readableName())); + dependency.scope.propagateInnerEmulation(this, dependency.wasEnclosingInstanceSupplied); + } + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/LocalVariableBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/LocalVariableBinding.java new file mode 100644 index 0000000..eba475f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/LocalVariableBinding.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpeclipse.internal.compiler.ast.LocalDeclaration; + +public class LocalVariableBinding extends VariableBinding { + + public boolean isArgument; + public int resolvedPosition; // for code generation (position in method context) + + public static final int UNUSED = 0; + public static final int USED = 1; + public static final int FAKE_USED = 2; + public int useFlag; // for flow analysis (default is UNUSED) + + public BlockScope declaringScope; // back-pointer to its declaring scope + public LocalDeclaration declaration; // for source-positions + + public int[] initializationPCs; + public int initializationCount = 0; + + // for synthetic local variables + public LocalVariableBinding(char[] name, TypeBinding type, int modifiers, boolean isArgument) { + + this.name = name; + this.type = type; + this.modifiers = modifiers; + if (this.isArgument = isArgument) + this.constant = Constant.NotAConstant; + } + + // regular local variable or argument + public LocalVariableBinding(LocalDeclaration declaration, TypeBinding type, int modifiers, boolean isArgument) { + + this(declaration.name, type, modifiers, isArgument); + this.declaration = declaration; + } + + /* API + * Answer the receiver's binding type from Binding.BindingID. + */ + public final int bindingType() { + + return LOCAL; + } + + // Answer whether the variable binding is a secret variable added for code gen purposes + public boolean isSecret() { + + return declaration == null && !isArgument; + } + + public void recordInitializationEndPC(int pc) { + + if (initializationPCs[((initializationCount - 1) << 1) + 1] == -1) + initializationPCs[((initializationCount - 1) << 1) + 1] = pc; + } + + public void recordInitializationStartPC(int pc) { + + if (initializationPCs == null) return; + // optimize cases where reopening a contiguous interval + if ((initializationCount > 0) && (initializationPCs[ ((initializationCount - 1) << 1) + 1] == pc)) { + initializationPCs[ ((initializationCount - 1) << 1) + 1] = -1; // reuse previous interval (its range will be augmented) + } else { + int index = initializationCount << 1; + if (index == initializationPCs.length) { + System.arraycopy(initializationPCs, 0, (initializationPCs = new int[initializationCount << 2]), 0, index); + } + initializationPCs[index] = pc; + initializationPCs[index + 1] = -1; + initializationCount++; + } + } + + public String toString() { + + String s = super.toString(); + switch (useFlag){ + case USED: + s += "[pos: " + String.valueOf(resolvedPosition) + "]"; //$NON-NLS-2$ //$NON-NLS-1$ + break; + case UNUSED: + s += "[pos: unused]"; //$NON-NLS-1$ + break; + case FAKE_USED: + s += "[pos: fake_used]"; //$NON-NLS-1$ + break; + } + s += "[id:" + String.valueOf(id) + "]"; //$NON-NLS-2$ //$NON-NLS-1$ + if (initializationCount > 0) { + s += "[pc: "; //$NON-NLS-1$ + for (int i = 0; i < initializationCount; i++) { + if (i > 0) + s += ", "; //$NON-NLS-1$ + s += String.valueOf(initializationPCs[i << 1]) + "-" + ((initializationPCs[(i << 1) + 1] == -1) ? "?" : String.valueOf(initializationPCs[(i<< 1) + 1])); //$NON-NLS-2$ //$NON-NLS-1$ + } + s += "]"; //$NON-NLS-1$ + } + return s; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/LookupEnvironment.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/LookupEnvironment.java new file mode 100644 index 0000000..d497ee5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/LookupEnvironment.java @@ -0,0 +1,583 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.env.IBinaryType; +import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment; +import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer; +import net.sourceforge.phpdt.internal.compiler.impl.ITypeRequestor; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; +import net.sourceforge.phpdt.internal.compiler.util.HashtableOfPackage; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; + +public class LookupEnvironment implements BaseTypes, ProblemReasons, TypeConstants { +// public CompilerOptions options; + public ProblemReporter problemReporter; + public ITypeRequestor typeRequestor; + + PackageBinding defaultPackage; + ImportBinding[] defaultImports; + HashtableOfPackage knownPackages; + static final ProblemPackageBinding TheNotFoundPackage = new ProblemPackageBinding(CharOperation.NO_CHAR, NotFound); + static final ProblemReferenceBinding TheNotFoundType = new ProblemReferenceBinding(CharOperation.NO_CHAR, NotFound); + + private INameEnvironment nameEnvironment; + private MethodVerifier verifier; + private ArrayBinding[][] uniqueArrayBindings; + + private CompilationUnitDeclaration[] units = new CompilationUnitDeclaration[4]; + private int lastUnitIndex = -1; + private int lastCompletedUnitIndex = -1; + + // indicate in which step on the compilation we are. + // step 1 : build the reference binding + // step 2 : conect the hierarchy (connect bindings) + // step 3 : build fields and method bindings. + private int stepCompleted; + final static int BUILD_TYPE_HIERARCHY = 1; + final static int CHECK_AND_SET_IMPORTS = 2; + final static int CONNECT_TYPE_HIERARCHY = 3; + final static int BUILD_FIELDS_AND_METHODS = 4; +public LookupEnvironment(ITypeRequestor typeRequestor,ProblemReporter problemReporter, INameEnvironment nameEnvironment) { +// CompilerOptions options, ProblemReporter problemReporter, INameEnvironment nameEnvironment) { + this.typeRequestor = typeRequestor; +// this.options = options; + this.problemReporter = problemReporter; + this.defaultPackage = new PackageBinding(this); // assume the default package always exists + this.defaultImports = null; + this.nameEnvironment = nameEnvironment; + this.knownPackages = new HashtableOfPackage(); + this.uniqueArrayBindings = new ArrayBinding[5][]; + this.uniqueArrayBindings[0] = new ArrayBinding[50]; // start off the most common 1 dimension array @ 50 +} +/* Ask the oracle for a type which corresponds to the compoundName. +* Answer null if the name cannot be found. +*/ + +public ReferenceBinding askForType(char[][] compoundName) { + NameEnvironmentAnswer answer = nameEnvironment.findType(compoundName); + if (answer == null) + return null; + + if (answer.isBinaryType()) + // the type was found as a .class file + typeRequestor.accept(answer.getBinaryType(), computePackageFrom(compoundName)); + else if (answer.isCompilationUnit()) + // the type was found as a .java file, try to build it then search the cache + typeRequestor.accept(answer.getCompilationUnit()); + else if (answer.isSourceType()) + // the type was found as a source model + typeRequestor.accept(answer.getSourceTypes(), computePackageFrom(compoundName)); + + return getCachedType(compoundName); +} +/* Ask the oracle for a type named name in the packageBinding. +* Answer null if the name cannot be found. +*/ + +ReferenceBinding askForType(PackageBinding packageBinding, char[] name) { + if (packageBinding == null) { + if (defaultPackage == null) + return null; + packageBinding = defaultPackage; + } + NameEnvironmentAnswer answer = nameEnvironment.findType(name, packageBinding.compoundName); + if (answer == null) + return null; + + if (answer.isBinaryType()) + // the type was found as a .class file + typeRequestor.accept(answer.getBinaryType(), packageBinding); + else if (answer.isCompilationUnit()) + // the type was found as a .java file, try to build it then search the cache + typeRequestor.accept(answer.getCompilationUnit()); + else if (answer.isSourceType()) + // the type was found as a source model + typeRequestor.accept(answer.getSourceTypes(), packageBinding); + + return packageBinding.getType0(name); +} +/* Create the initial type bindings for the compilation unit. +* +* See completeTypeBindings() for a description of the remaining steps +* +* NOTE: This method can be called multiple times as additional source files are needed +*/ + +public void buildTypeBindings(CompilationUnitDeclaration unit) { + CompilationUnitScope scope = new CompilationUnitScope(unit, this); + scope.buildTypeBindings(); + + int unitsLength = units.length; + if (++lastUnitIndex >= unitsLength) + System.arraycopy(units, 0, units = new CompilationUnitDeclaration[2 * unitsLength], 0, unitsLength); + units[lastUnitIndex] = unit; +} +/* Cache the binary type since we know it is needed during this compile. +* +* Answer the created BinaryTypeBinding or null if the type is already in the cache. +*/ + +public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType) { + return cacheBinaryType(binaryType, true); +} +/* Cache the binary type since we know it is needed during this compile. +* +* Answer the created BinaryTypeBinding or null if the type is already in the cache. +*/ + +public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType, boolean needFieldsAndMethods) { + char[][] compoundName = CharOperation.splitOn('/', binaryType.getName()); + ReferenceBinding existingType = getCachedType(compoundName); + + if (existingType == null || existingType instanceof UnresolvedReferenceBinding) + // only add the binary type if its not already in the cache + return createBinaryTypeFrom(binaryType, computePackageFrom(compoundName), needFieldsAndMethods); + return null; // the type already exists & can be retrieved from the cache +} +/* +* 1. Connect the type hierarchy for the type bindings created for parsedUnits. +* 2. Create the field bindings +* 3. Create the method bindings +*/ + +/* We know each known compilationUnit is free of errors at this point... +* +* Each step will create additional bindings unless a problem is detected, in which +* case either the faulty import/superinterface/field/method will be skipped or a +* suitable replacement will be substituted (such as Object for a missing superclass) +*/ + +public void completeTypeBindings() { + stepCompleted = BUILD_TYPE_HIERARCHY; + +// for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { +// units[i].scope.checkAndSetImports(); +// } + stepCompleted = CHECK_AND_SET_IMPORTS; + +// for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { +// units[i].scope.connectTypeHierarchy(); +// } + stepCompleted = CONNECT_TYPE_HIERARCHY; + + for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { +// units[i].scope.buildFieldsAndMethods(); + units[i] = null; // release unnecessary reference to the parsed unit + } + stepCompleted = BUILD_FIELDS_AND_METHODS; + lastCompletedUnitIndex = lastUnitIndex; +} +/* +* 1. Connect the type hierarchy for the type bindings created for parsedUnits. +* 2. Create the field bindings +* 3. Create the method bindings +*/ + +/* +* Each step will create additional bindings unless a problem is detected, in which +* case either the faulty import/superinterface/field/method will be skipped or a +* suitable replacement will be substituted (such as Object for a missing superclass) +*/ + +public void completeTypeBindings(CompilationUnitDeclaration parsedUnit) { + if (stepCompleted == BUILD_FIELDS_AND_METHODS) { + // This can only happen because the original set of units are completely built and + // are now being processed, so we want to treat all the additional units as a group + // until they too are completely processed. + completeTypeBindings(); + } else { + if (parsedUnit.scope == null) return; // parsing errors were too severe + + if (stepCompleted >= CHECK_AND_SET_IMPORTS) + parsedUnit.scope.checkAndSetImports(); + + if (stepCompleted >= CONNECT_TYPE_HIERARCHY) + parsedUnit.scope.connectTypeHierarchy(); + } +} +/* +* Used by other compiler tools which do not start by calling completeTypeBindings(). +* +* 1. Connect the type hierarchy for the type bindings created for parsedUnits. +* 2. Create the field bindings +* 3. Create the method bindings +*/ + +public void completeTypeBindings(CompilationUnitDeclaration parsedUnit, boolean buildFieldsAndMethods) { + if (parsedUnit.scope == null) return; // parsing errors were too severe + + parsedUnit.scope.checkAndSetImports(); + parsedUnit.scope.connectTypeHierarchy(); + + if (buildFieldsAndMethods) + parsedUnit.scope.buildFieldsAndMethods(); +} +private PackageBinding computePackageFrom(char[][] constantPoolName) { + if (constantPoolName.length == 1) + return defaultPackage; + + PackageBinding packageBinding = getPackage0(constantPoolName[0]); + if (packageBinding == null || packageBinding == TheNotFoundPackage) { + packageBinding = new PackageBinding(constantPoolName[0], this); + knownPackages.put(constantPoolName[0], packageBinding); + } + + for (int i = 1, length = constantPoolName.length - 1; i < length; i++) { + PackageBinding parent = packageBinding; + if ((packageBinding = parent.getPackage0(constantPoolName[i])) == null || packageBinding == TheNotFoundPackage) { + packageBinding = new PackageBinding(CharOperation.subarray(constantPoolName, 0, i + 1), parent, this); + parent.addPackage(packageBinding); + } + } + return packageBinding; +} +/* Used to guarantee array type identity. +*/ + +ArrayBinding createArrayType(TypeBinding type, int dimensionCount) { + if (type instanceof LocalTypeBinding) // cache local type arrays with the local type itself + return ((LocalTypeBinding) type).createArrayType(dimensionCount); + + // find the array binding cache for this dimension + int dimIndex = dimensionCount - 1; + int length = uniqueArrayBindings.length; + ArrayBinding[] arrayBindings; + if (dimIndex < length) { + if ((arrayBindings = uniqueArrayBindings[dimIndex]) == null) + uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10]; + } else { + System.arraycopy( + uniqueArrayBindings, 0, + uniqueArrayBindings = new ArrayBinding[dimensionCount][], 0, + length); + uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10]; + } + + // find the cached array binding for this leaf component type (if any) + int index = -1; + length = arrayBindings.length; + while (++index < length) { + ArrayBinding currentBinding = arrayBindings[index]; + if (currentBinding == null) // no matching array, but space left + return arrayBindings[index] = new ArrayBinding(type, dimensionCount); + if (currentBinding.leafComponentType == type) + return currentBinding; + } + + // no matching array, no space left + System.arraycopy( + arrayBindings, 0, + (arrayBindings = new ArrayBinding[length * 2]), 0, + length); + uniqueArrayBindings[dimIndex] = arrayBindings; + return arrayBindings[length] = new ArrayBinding(type, dimensionCount); +} +public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding) { + return createBinaryTypeFrom(binaryType, packageBinding, true); +} +public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding, boolean needFieldsAndMethods) { + BinaryTypeBinding binaryBinding = new BinaryTypeBinding(packageBinding, binaryType, this); + + // resolve any array bindings which reference the unresolvedType + ReferenceBinding cachedType = packageBinding.getType0(binaryBinding.compoundName[binaryBinding.compoundName.length - 1]); + if (cachedType != null) { + if (cachedType.isBinaryBinding()) // sanity check before the cast... at this point the cache should ONLY contain unresolved types + return (BinaryTypeBinding) cachedType; + + UnresolvedReferenceBinding unresolvedType = (UnresolvedReferenceBinding) cachedType; + unresolvedType.resolvedType = binaryBinding; + updateArrayCache(unresolvedType, binaryBinding); + } + + packageBinding.addType(binaryBinding); + binaryBinding.cachePartsFrom(binaryType, needFieldsAndMethods); + return binaryBinding; +} +/* Used to create packages from the package statement. +*/ + +PackageBinding createPackage(char[][] compoundName) { + PackageBinding packageBinding = getPackage0(compoundName[0]); + if (packageBinding == null || packageBinding == TheNotFoundPackage) { + packageBinding = new PackageBinding(compoundName[0], this); + knownPackages.put(compoundName[0], packageBinding); + } + + for (int i = 1, length = compoundName.length; i < length; i++) { + // check to see if it collides with a known type... + // this case can only happen if the package does not exist as a directory in the file system + // otherwise when the source type was defined, the correct error would have been reported + // unless its an unresolved type which is referenced from an inconsistent class file + ReferenceBinding type = packageBinding.getType0(compoundName[i]); + if (type != null && type != TheNotFoundType && !(type instanceof UnresolvedReferenceBinding)) + return null; + + PackageBinding parent = packageBinding; + if ((packageBinding = parent.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage) { + // if the package is unknown, check to see if a type exists which would collide with the new package + // catches the case of a package statement of: package java.lang.Object; + // since the package can be added after a set of source files have already been compiled, we need + // whenever a package statement is encountered + if (nameEnvironment.findType(compoundName[i], parent.compoundName) != null) + return null; + + packageBinding = new PackageBinding(CharOperation.subarray(compoundName, 0, i + 1), parent, this); + parent.addPackage(packageBinding); + } + } + return packageBinding; +} +/* Answer the type for the compoundName if it exists in the cache. +* Answer theNotFoundType if it could not be resolved the first time +* it was looked up, otherwise answer null. +* +* NOTE: Do not use for nested types... the answer is NOT the same for a.b.C or a.b.C.D.E +* assuming C is a type in both cases. In the a.b.C.D.E case, null is the answer. +*/ + +public ReferenceBinding getCachedType(char[][] compoundName) { + if (compoundName.length == 1) { + if (defaultPackage == null) + return null; + return defaultPackage.getType0(compoundName[0]); + } + + PackageBinding packageBinding = getPackage0(compoundName[0]); + if (packageBinding == null || packageBinding == TheNotFoundPackage) + return null; + + for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++) + if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage) + return null; + return packageBinding.getType0(compoundName[compoundName.length - 1]); +} +/* Answer the top level package named name if it exists in the cache. +* Answer theNotFoundPackage if it could not be resolved the first time +* it was looked up, otherwise answer null. +* +* NOTE: Senders must convert theNotFoundPackage into a real problem +* package if its to returned. +*/ + +PackageBinding getPackage0(char[] name) { + return knownPackages.get(name); +} +/* Answer the top level package named name. +* Ask the oracle for the package if its not in the cache. +* Answer null if the package cannot be found. +*/ + +PackageBinding getTopLevelPackage(char[] name) { + PackageBinding packageBinding = getPackage0(name); + if (packageBinding != null) { + if (packageBinding == TheNotFoundPackage) + return null; + else + return packageBinding; + } + + if (nameEnvironment.isPackage(null, name)) { + knownPackages.put(name, packageBinding = new PackageBinding(name, this)); + return packageBinding; + } + + knownPackages.put(name, TheNotFoundPackage); // saves asking the oracle next time + return null; +} +/* Answer the type corresponding to the compoundName. +* Ask the oracle for the type if its not in the cache. +* Answer null if the type cannot be found... likely a fatal error. +*/ + +public ReferenceBinding getType(char[][] compoundName) { + ReferenceBinding referenceBinding; + + if (compoundName.length == 1) { + if (defaultPackage == null) + return null; + + if ((referenceBinding = defaultPackage.getType0(compoundName[0])) == null) { + PackageBinding packageBinding = getPackage0(compoundName[0]); + if (packageBinding != null && packageBinding != TheNotFoundPackage) + return null; // collides with a known package... should not call this method in such a case + referenceBinding = askForType(defaultPackage, compoundName[0]); + } + } else { + PackageBinding packageBinding = getPackage0(compoundName[0]); + if (packageBinding == TheNotFoundPackage) + return null; + + if (packageBinding != null) { + for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++) { + if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null) + break; + if (packageBinding == TheNotFoundPackage) + return null; + } + } + + if (packageBinding == null) + referenceBinding = askForType(compoundName); + else if ((referenceBinding = packageBinding.getType0(compoundName[compoundName.length - 1])) == null) + referenceBinding = askForType(packageBinding, compoundName[compoundName.length - 1]); + } + + if (referenceBinding == null || referenceBinding == TheNotFoundType) + return null; + if (referenceBinding instanceof UnresolvedReferenceBinding) + referenceBinding = ((UnresolvedReferenceBinding) referenceBinding).resolve(this); + + // compoundName refers to a nested type incorrectly (for example, package1.A$B) + if (referenceBinding.isNestedType()) + return new ProblemReferenceBinding(compoundName, InternalNameProvided); + else + return referenceBinding; +} +/* Answer the type corresponding to the name from the binary file. +* Does not ask the oracle for the type if its not found in the cache... instead an +* unresolved type is returned which must be resolved before used. +* +* NOTE: Does NOT answer base types nor array types! +* +* NOTE: Aborts compilation if the class file cannot be found. +*/ + +ReferenceBinding getTypeFromConstantPoolName(char[] signature, int start, int end) { + if (end == -1) + end = signature.length; + + char[][] compoundName = CharOperation.splitOn('/', signature, start, end); + ReferenceBinding binding = getCachedType(compoundName); + if (binding == null) { + PackageBinding packageBinding = computePackageFrom(compoundName); + binding = new UnresolvedReferenceBinding(compoundName, packageBinding); + packageBinding.addType(binding); + } else if (binding == TheNotFoundType) { + problemReporter.isClassPathCorrect(compoundName, null); + return null; // will not get here since the above error aborts the compilation + } + return binding; +} +/* Answer the type corresponding to the signature from the binary file. +* Does not ask the oracle for the type if its not found in the cache... instead an +* unresolved type is returned which must be resolved before used. +* +* NOTE: Does answer base types & array types. +* +* NOTE: Aborts compilation if the class file cannot be found. +*/ + +TypeBinding getTypeFromSignature(char[] signature, int start, int end) { + int dimension = 0; + while (signature[start] == '[') { + start++; + dimension++; + } + if (end == -1) + end = signature.length - 1; + + // Just switch on signature[start] - the L case is the else + TypeBinding binding = null; + if (start == end) { + switch (signature[start]) { + case 'I' : + binding = IntBinding; + break; + case 'Z' : + binding = BooleanBinding; + break; + case 'V' : + binding = VoidBinding; + break; + case 'C' : + binding = CharBinding; + break; + case 'D' : + binding = DoubleBinding; + break; + case 'B' : + binding = ByteBinding; + break; + case 'F' : + binding = FloatBinding; + break; + case 'J' : + binding = LongBinding; + break; + case 'S' : + binding = ShortBinding; + break; + default : + throw new Error(Util.bind("error.undefinedBaseType",String.valueOf(signature[start]))); //$NON-NLS-1$ + } + } else { + binding = getTypeFromConstantPoolName(signature, start + 1, end); + } + + if (dimension == 0) + return binding; + else + return createArrayType(binding, dimension); +} +/* Ask the oracle if a package exists named name in the package named compoundName. +*/ + +boolean isPackage(char[][] compoundName, char[] name) { + if (compoundName == null || compoundName.length == 0) + return nameEnvironment.isPackage(null, name); + else + return nameEnvironment.isPackage(compoundName, name); +} +// The method verifier is lazily initialized to guarantee the receiver, the compiler & the oracle are ready. + +public MethodVerifier methodVerifier() { + if (verifier == null) + verifier = new MethodVerifier(this); + return verifier; +} +public void reset() { + this.defaultPackage = new PackageBinding(this); // assume the default package always exists + this.defaultImports = null; + this.knownPackages = new HashtableOfPackage(); + + this.verifier = null; + for (int i = this.uniqueArrayBindings.length; --i >= 0;) + this.uniqueArrayBindings[i] = null; + this.uniqueArrayBindings[0] = new ArrayBinding[50]; // start off the most common 1 dimension array @ 50 + + for (int i = this.units.length; --i >= 0;) + this.units[i] = null; + this.lastUnitIndex = -1; + this.lastCompletedUnitIndex = -1; + + // name environment has a longer life cycle, and must be reset in + // the code which created it. +} +void updateArrayCache(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType) { + nextDimension : for (int i = 0, length = uniqueArrayBindings.length; i < length; i++) { + ArrayBinding[] arrayBindings = uniqueArrayBindings[i]; + if (arrayBindings != null) { + for (int j = 0, max = arrayBindings.length; j < max; j++) { + ArrayBinding currentBinding = arrayBindings[j]; + if (currentBinding == null) + continue nextDimension; + if (currentBinding.leafComponentType == unresolvedType) { + currentBinding.leafComponentType = resolvedType; + continue nextDimension; + } + } + } + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MemberTypeBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MemberTypeBinding.java new file mode 100644 index 0000000..1d3d67f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MemberTypeBinding.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; + +public final class MemberTypeBinding extends NestedTypeBinding { +public MemberTypeBinding(char[][] compoundName, ClassScope scope, SourceTypeBinding enclosingType) { + super(compoundName, scope, enclosingType); + this.tagBits |= MemberTypeMask; +} +void checkSyntheticArgsAndFields() { + if (this.isStatic()) return; + if (this.isInterface()) return; + this.addSyntheticArgumentAndField(this.enclosingType); +} +/* Answer the receiver's constant pool name. +* +* NOTE: This method should only be used during/after code gen. +*/ + +public char[] constantPoolName() /* java/lang/Object */ { + if (constantPoolName != null) + return constantPoolName; + + return constantPoolName = CharOperation.concat(enclosingType().constantPoolName(), sourceName, '$'); +} +public String toString() { + return "Member type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MethodBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MethodBinding.java new file mode 100644 index 0000000..85c5afa --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MethodBinding.java @@ -0,0 +1,520 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration; + +public class MethodBinding extends Binding implements BaseTypes, TypeConstants { + public int modifiers; + public char[] selector; + public TypeBinding returnType; + public TypeBinding[] parameters; + public ReferenceBinding[] thrownExceptions; + public ReferenceBinding declaringClass; + + char[] signature; + +protected MethodBinding() { +} +public MethodBinding(int modifiers, char[] selector, TypeBinding returnType, TypeBinding[] args, ReferenceBinding[] exceptions, ReferenceBinding declaringClass) { + this.modifiers = modifiers; + this.selector = selector; + this.returnType = returnType; + this.parameters = (args == null || args.length == 0) ? NoParameters : args; + this.thrownExceptions = (exceptions == null || exceptions.length == 0) ? NoExceptions : exceptions; + this.declaringClass = declaringClass; + + // propagate the strictfp & deprecated modifiers + if (this.declaringClass != null) { +// if (this.declaringClass.isStrictfp()) +// if (!(isNative() || isAbstract())) +// this.modifiers |= AccStrictfp; + if (this.declaringClass.isViewedAsDeprecated() && !isDeprecated()) + this.modifiers |= AccDeprecatedImplicitly; + } +} +public MethodBinding(int modifiers, TypeBinding[] args, ReferenceBinding[] exceptions, ReferenceBinding declaringClass) { + this(modifiers, ConstructorDeclaration.ConstantPoolName, VoidBinding, args, exceptions, declaringClass); +} +// special API used to change method declaring class for runtime visibility check +public MethodBinding(MethodBinding initialMethodBinding, ReferenceBinding declaringClass) { + this.modifiers = initialMethodBinding.modifiers; + this.selector = initialMethodBinding.selector; + this.returnType = initialMethodBinding.returnType; + this.parameters = initialMethodBinding.parameters; + this.thrownExceptions = initialMethodBinding.thrownExceptions; + this.declaringClass = declaringClass; +} +/* Answer true if the argument types & the receiver's parameters are equal +*/ + +public final boolean areParametersEqual(MethodBinding method) { + TypeBinding[] args = method.parameters; + if (parameters == args) + return true; + + int length = parameters.length; + if (length != args.length) + return false; + + for (int i = 0; i < length; i++) + if (parameters[i] != args[i]) + return false; + return true; +} +/* API +* Answer the receiver's binding type from Binding.BindingID. +*/ + +public final int bindingType() { + return METHOD; +} +/* Answer true if the receiver is visible to the type provided by the scope. +* InvocationSite implements isSuperAccess() to provide additional information +* if the receiver is protected. +* +* NOTE: This method should ONLY be sent if the receiver is a constructor. +* +* NOTE: Cannot invoke this method with a compilation unit scope. +*/ + +public final boolean canBeSeenBy(InvocationSite invocationSite, Scope scope) { + if (isPublic()) return true; + + SourceTypeBinding invocationType = scope.enclosingSourceType(); + if (invocationType == declaringClass) return true; + + if (isProtected()) { + // answer true if the receiver is in the same package as the invocationType + if (invocationType.fPackage == declaringClass.fPackage) return true; + return invocationSite.isSuperAccess(); + } + + if (isPrivate()) { + // answer true if the invocationType and the declaringClass have a common enclosingType + // already know they are not the identical type + ReferenceBinding outerInvocationType = invocationType; + ReferenceBinding temp = outerInvocationType.enclosingType(); + while (temp != null) { + outerInvocationType = temp; + temp = temp.enclosingType(); + } + + ReferenceBinding outerDeclaringClass = declaringClass; + temp = outerDeclaringClass.enclosingType(); + while (temp != null) { + outerDeclaringClass = temp; + temp = temp.enclosingType(); + } + return outerInvocationType == outerDeclaringClass; + } + + // isDefault() + return invocationType.fPackage == declaringClass.fPackage; +} +/* Answer true if the receiver is visible to the type provided by the scope. +* InvocationSite implements isSuperAccess() to provide additional information +* if the receiver is protected. +* +* NOTE: Cannot invoke this method with a compilation unit scope. +*/ +public final boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) { + if (isPublic()) return true; + + SourceTypeBinding invocationType = scope.enclosingSourceType(); + if (invocationType == declaringClass && invocationType == receiverType) return true; + + if (isProtected()) { + // answer true if the invocationType is the declaringClass or they are in the same package + // OR the invocationType is a subclass of the declaringClass + // AND the receiverType is the invocationType or its subclass + // OR the method is a static method accessed directly through a type + // OR previous assertions are true for one of the enclosing type + if (invocationType == declaringClass) return true; + if (invocationType.fPackage == declaringClass.fPackage) return true; + + ReferenceBinding currentType = invocationType; + int depth = 0; + do { + if (declaringClass.isSuperclassOf(currentType)) { + if (invocationSite.isSuperAccess()){ + return true; + } + // receiverType can be an array binding in one case... see if you can change it + if (receiverType instanceof ArrayBinding){ + return false; + } + if (isStatic()){ + return true; // see 1FMEPDL - return invocationSite.isTypeAccess(); + } + if (currentType == receiverType || currentType.isSuperclassOf((ReferenceBinding) receiverType)){ + if (depth > 0) invocationSite.setDepth(depth); + return true; + } + } + depth++; + currentType = currentType.enclosingType(); + } while (currentType != null); + return false; + } + + if (isPrivate()) { + // answer true if the receiverType is the declaringClass + // AND the invocationType and the declaringClass have a common enclosingType + if (receiverType != declaringClass) return false; + + if (invocationType != declaringClass) { + ReferenceBinding outerInvocationType = invocationType; + ReferenceBinding temp = outerInvocationType.enclosingType(); + while (temp != null) { + outerInvocationType = temp; + temp = temp.enclosingType(); + } + + ReferenceBinding outerDeclaringClass = declaringClass; + temp = outerDeclaringClass.enclosingType(); + while (temp != null) { + outerDeclaringClass = temp; + temp = temp.enclosingType(); + } + if (outerInvocationType != outerDeclaringClass) return false; + } + return true; + } + + // isDefault() + if (invocationType.fPackage != declaringClass.fPackage) return false; + + // receiverType can be an array binding in one case... see if you can change it + if (receiverType instanceof ArrayBinding) + return false; + ReferenceBinding type = (ReferenceBinding) receiverType; + PackageBinding declaringPackage = declaringClass.fPackage; + do { + if (declaringClass == type) return true; + if (declaringPackage != type.fPackage) return false; + } while ((type = type.superclass()) != null); + return false; +} + +/* Answer the receiver's constant pool name. +* +* for constructors +* for clinit methods +* or the source name of the method +*/ +public final char[] constantPoolName() { + return selector; +} +public final int getAccessFlags() { + return modifiers & AccJustFlag; +} + +/* Answer true if the receiver is an abstract method +*/ +public final boolean isAbstract() { + return (modifiers & AccAbstract) != 0; +} + +/* Answer true if the receiver is a constructor +*/ +public final boolean isConstructor() { + return selector == ConstructorDeclaration.ConstantPoolName; +} +protected boolean isConstructorRelated() { + return isConstructor(); +} + +/* Answer true if the receiver has default visibility +*/ +public final boolean isDefault() { + return !isPublic() && !isProtected() && !isPrivate(); +} + +/* Answer true if the receiver is a system generated default abstract method +*/ +public final boolean isDefaultAbstract() { + return (modifiers & AccDefaultAbstract) != 0; +} + +/* Answer true if the receiver is a deprecated method +*/ +public final boolean isDeprecated() { + return (modifiers & AccDeprecated) != 0; +} + +/* Answer true if the receiver is final and cannot be overridden +*/ +public final boolean isFinal() { + return (modifiers & AccFinal) != 0; +} + +/* Answer true if the receiver is implementing another method + * in other words, it is overriding and concrete, and overriden method is abstract + * Only set for source methods +*/ +public final boolean isImplementing() { + return (modifiers & AccImplementing) != 0; +} + +/* Answer true if the receiver is a native method +*/ +//public final boolean isNative() { +// return (modifiers & AccNative) != 0; +//} + +/* Answer true if the receiver is overriding another method + * Only set for source methods +*/ +public final boolean isOverriding() { + return (modifiers & AccOverriding) != 0; +} +/* + * Answer true if the receiver is a "public static void main(String[])" method + */ +public final boolean isMain() { + if (this.selector.length == 4 && CharOperation.equals(this.selector, MAIN) + && ((this.modifiers & (AccPublic | AccStatic)) != 0) + && VoidBinding == this.returnType + && this.parameters.length == 1) { + TypeBinding paramType = this.parameters[0]; + if (paramType.dimensions() == 1 && paramType.leafComponentType().id == TypeIds.T_JavaLangString) { + return true; + } + } + return false; +} +/* Answer true if the receiver has private visibility +*/ +public final boolean isPrivate() { + return (modifiers & AccPrivate) != 0; +} + +/* Answer true if the receiver has private visibility and is used locally +*/ +public final boolean isPrivateUsed() { + return (modifiers & AccPrivateUsed) != 0; +} + +/* Answer true if the receiver has protected visibility +*/ +public final boolean isProtected() { + return (modifiers & AccProtected) != 0; +} + +/* Answer true if the receiver has public visibility +*/ +public final boolean isPublic() { + return (modifiers & AccPublic) != 0; +} + +/* Answer true if the receiver got requested to clear the private modifier + * during private access emulation. + */ +public final boolean isRequiredToClearPrivateModifier() { + return (modifiers & AccClearPrivateModifier) != 0; +} + +/* Answer true if the receiver is a static method +*/ +public final boolean isStatic() { + return (modifiers & AccStatic) != 0; +} + +/* Answer true if all float operations must adher to IEEE 754 float/double rules +*/ +//public final boolean isStrictfp() { +// return (modifiers & AccStrictfp) != 0; +//} + +/* Answer true if the receiver is a synchronized method +*/ +//public final boolean isSynchronized() { +// return (modifiers & AccSynchronized) != 0; +//} + +/* Answer true if the receiver has public visibility +*/ +//public final boolean isSynthetic() { +// return (modifiers & AccSynthetic) != 0; +//} + +/* Answer true if the receiver's declaring type is deprecated (or any of its enclosing types) +*/ +public final boolean isViewedAsDeprecated() { + return (modifiers & AccDeprecated) != 0 || + (modifiers & AccDeprecatedImplicitly) != 0; +} + +public char[] readableName() /* foo(int, Thread) */ { + StringBuffer buffer = new StringBuffer(parameters.length + 1 * 20); + if (isConstructor()) + buffer.append(declaringClass.sourceName()); + else + buffer.append(selector); + buffer.append('('); + if (parameters != NoParameters) { + for (int i = 0, length = parameters.length; i < length; i++) { + if (i > 0) + buffer.append(", "); //$NON-NLS-1$ + buffer.append(parameters[i].sourceName()); + } + } + buffer.append(')'); + return buffer.toString().toCharArray(); +} + +/** + * @see org.eclipse.jdt.internal.compiler.lookup.Binding#shortReadableName() + */ +public char[] shortReadableName() { + StringBuffer buffer = new StringBuffer(parameters.length + 1 * 20); + if (isConstructor()) + buffer.append(declaringClass.shortReadableName()); + else + buffer.append(selector); + buffer.append('('); + if (parameters != NoParameters) { + for (int i = 0, length = parameters.length; i < length; i++) { + if (i > 0) + buffer.append(", "); //$NON-NLS-1$ + buffer.append(parameters[i].shortReadableName()); + } + } + buffer.append(')'); + return buffer.toString().toCharArray(); +} + +protected final void selector(char[] selector) { + this.selector = selector; + this.signature = null; +} + +/* Answer the receiver's signature. +* +* NOTE: This method should only be used during/after code gen. +* The signature is cached so if the signature of the return type or any parameter +* type changes, the cached state is invalid. +*/ +public final char[] signature() /* (ILjava/lang/Thread;)Ljava/lang/Object; */ { + if (signature != null) + return signature; + + StringBuffer buffer = new StringBuffer(parameters.length + 1 * 20); + buffer.append('('); + + TypeBinding[] targetParameters = this.parameters; + boolean considerSynthetics = isConstructorRelated() && declaringClass.isNestedType(); + if (considerSynthetics) { + + // take into account the synthetic argument type signatures as well + ReferenceBinding[] syntheticArgumentTypes = declaringClass.syntheticEnclosingInstanceTypes(); + int count = syntheticArgumentTypes == null ? 0 : syntheticArgumentTypes.length; + for (int i = 0; i < count; i++) { + buffer.append(syntheticArgumentTypes[i].signature()); + } + + if (this instanceof SyntheticAccessMethodBinding) { + targetParameters = ((SyntheticAccessMethodBinding)this).targetMethod.parameters; + } + } + + if (targetParameters != NoParameters) { + for (int i = 0; i < targetParameters.length; i++) { + buffer.append(targetParameters[i].signature()); + } + } + if (considerSynthetics) { + SyntheticArgumentBinding[] syntheticOuterArguments = declaringClass.syntheticOuterLocalVariables(); + int count = syntheticOuterArguments == null ? 0 : syntheticOuterArguments.length; + for (int i = 0; i < count; i++) { + buffer.append(syntheticOuterArguments[i].type.signature()); + } + // move the extra padding arguments of the synthetic constructor invocation to the end + for (int i = targetParameters.length, extraLength = parameters.length; i < extraLength; i++) { + buffer.append(parameters[i].signature()); + } + } + buffer.append(')'); + buffer.append(returnType.signature()); + return signature = buffer.toString().toCharArray(); +} +public final int sourceEnd() { + AbstractMethodDeclaration method = sourceMethod(); + if (method == null) + return 0; + else + return method.sourceEnd; +} +AbstractMethodDeclaration sourceMethod() { + SourceTypeBinding sourceType; + try { + sourceType = (SourceTypeBinding) declaringClass; + } catch (ClassCastException e) { + return null; + } + + AbstractMethodDeclaration[] methods = sourceType.scope.referenceContext.methods; + for (int i = methods.length; --i >= 0;) + if (this == methods[i].binding) + return methods[i]; + return null; +} +public final int sourceStart() { + AbstractMethodDeclaration method = sourceMethod(); + if (method == null) + return 0; + else + return method.sourceStart; +} +/* During private access emulation, the binding can be requested to loose its + * private visibility when the class file is dumped. + */ + +public final void tagForClearingPrivateModifier() { + modifiers |= AccClearPrivateModifier; +} +public String toString() { + String s = (returnType != null) ? returnType.debugName() : "NULL TYPE"; //$NON-NLS-1$ + s += " "; //$NON-NLS-1$ + s += (selector != null) ? new String(selector) : "UNNAMED METHOD"; //$NON-NLS-1$ + + s += "("; //$NON-NLS-1$ + if (parameters != null) { + if (parameters != NoParameters) { + for (int i = 0, length = parameters.length; i < length; i++) { + if (i > 0) + s += ", "; //$NON-NLS-1$ + s += (parameters[i] != null) ? parameters[i].debugName() : "NULL TYPE"; //$NON-NLS-1$ + } + } + } else { + s += "NULL PARAMETERS"; //$NON-NLS-1$ + } + s += ") "; //$NON-NLS-1$ + + if (thrownExceptions != null) { + if (thrownExceptions != NoExceptions) { + s += "throws "; //$NON-NLS-1$ + for (int i = 0, length = thrownExceptions.length; i < length; i++) { + if (i > 0) + s += ", "; //$NON-NLS-1$ + s += (thrownExceptions[i] != null) ? thrownExceptions[i].debugName() : "NULL TYPE"; //$NON-NLS-1$ + } + } + } else { + s += "NULL THROWN EXCEPTIONS"; //$NON-NLS-1$ + } + return s; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MethodScope.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MethodScope.java new file mode 100644 index 0000000..c454db2 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MethodScope.java @@ -0,0 +1,471 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.UnconditionalFlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; +import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; +import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedNameReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.SingleNameReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; + +/** + * Particular block scope used for methods, constructors or clinits, representing + * its outermost blockscope. Note also that such a scope will be provided to enclose + * field initializers subscopes as well. + */ +public class MethodScope extends BlockScope { + + public ReferenceContext referenceContext; + public boolean isStatic; // method modifier or initializer one + + //fields used during name resolution + public static final int NotInFieldDecl = -1; //must be a negative value + public boolean isConstructorCall = false; + public int fieldDeclarationIndex = NotInFieldDecl; + + // flow analysis + public int analysisIndex; // for setting flow-analysis id + public boolean isPropagatingInnerClassEmulation; + + // for local variables table attributes + public int lastIndex = 0; + public long[] definiteInits = new long[4]; + public long[][] extraDefiniteInits = new long[4][]; + + // inner-emulation + public SyntheticArgumentBinding[] extraSyntheticArguments; + + public MethodScope(ClassScope parent, ReferenceContext context, boolean isStatic) { + + super(METHOD_SCOPE, parent); + locals = new LocalVariableBinding[5]; + this.referenceContext = context; + this.isStatic = isStatic; + this.startIndex = 0; + } + + /* Spec : 8.4.3 & 9.4 + */ + private void checkAndSetModifiersForConstructor(MethodBinding methodBinding) { + + int modifiers = methodBinding.modifiers; + if ((modifiers & AccAlternateModifierProblem) != 0) + problemReporter().duplicateModifierForMethod( + methodBinding.declaringClass, + (AbstractMethodDeclaration) referenceContext); + + if (((ConstructorDeclaration) referenceContext).isDefaultConstructor) { + if (methodBinding.declaringClass.isPublic()) + modifiers |= AccPublic; + else if (methodBinding.declaringClass.isProtected()) + modifiers |= AccProtected; + } + + // after this point, tests on the 16 bits reserved. + int realModifiers = modifiers & AccJustFlag; + + // check for abnormal modifiers + int unexpectedModifiers = + ~(AccPublic | AccPrivate | AccProtected);// | AccStrictfp); + if ((realModifiers & unexpectedModifiers) != 0) + problemReporter().illegalModifierForMethod( + methodBinding.declaringClass, + (AbstractMethodDeclaration) referenceContext); +// else if ( +// (((AbstractMethodDeclaration) referenceContext).modifiers & AccStrictfp) != 0) +// // must check the parse node explicitly +// problemReporter().illegalModifierForMethod( +// methodBinding.declaringClass, +// (AbstractMethodDeclaration) referenceContext); + + // check for incompatible modifiers in the visibility bits, isolate the visibility bits + int accessorBits = realModifiers & (AccPublic | AccProtected | AccPrivate); + if ((accessorBits & (accessorBits - 1)) != 0) { + problemReporter().illegalVisibilityModifierCombinationForMethod( + methodBinding.declaringClass, + (AbstractMethodDeclaration) referenceContext); + + // need to keep the less restrictive + if ((accessorBits & AccPublic) != 0) { + if ((accessorBits & AccProtected) != 0) + modifiers ^= AccProtected; + if ((accessorBits & AccPrivate) != 0) + modifiers ^= AccPrivate; + } + if ((accessorBits & AccProtected) != 0) + if ((accessorBits & AccPrivate) != 0) + modifiers ^= AccPrivate; + } + + // if the receiver's declaring class is a private nested type, then make sure the receiver is not private (causes problems for inner type emulation) + if (methodBinding.declaringClass.isPrivate()) + if ((modifiers & AccPrivate) != 0) + modifiers ^= AccPrivate; + + methodBinding.modifiers = modifiers; + } + + /* Spec : 8.4.3 & 9.4 + */ + private void checkAndSetModifiersForMethod(MethodBinding methodBinding) { + + int modifiers = methodBinding.modifiers; + if ((modifiers & AccAlternateModifierProblem) != 0) + problemReporter().duplicateModifierForMethod( + methodBinding.declaringClass, + (AbstractMethodDeclaration) referenceContext); + + // after this point, tests on the 16 bits reserved. + int realModifiers = modifiers & AccJustFlag; + + // set the requested modifiers for a method in an interface + if (methodBinding.declaringClass.isInterface()) { + if ((realModifiers & ~(AccPublic | AccAbstract)) != 0) + problemReporter().illegalModifierForInterfaceMethod( + methodBinding.declaringClass, + (AbstractMethodDeclaration) referenceContext); + return; + } + + // check for abnormal modifiers + int unexpectedModifiers = + ~( + AccPublic + | AccPrivate + | AccProtected + | AccAbstract + | AccStatic + | AccFinal); +// | AccSynchronized +// | AccNative +// | AccStrictfp); + if ((realModifiers & unexpectedModifiers) != 0) + problemReporter().illegalModifierForMethod( + methodBinding.declaringClass, + (AbstractMethodDeclaration) referenceContext); + + // check for incompatible modifiers in the visibility bits, isolate the visibility bits + int accessorBits = realModifiers & (AccPublic | AccProtected | AccPrivate); + if ((accessorBits & (accessorBits - 1)) != 0) { + problemReporter().illegalVisibilityModifierCombinationForMethod( + methodBinding.declaringClass, + (AbstractMethodDeclaration) referenceContext); + + // need to keep the less restrictive + if ((accessorBits & AccPublic) != 0) { + if ((accessorBits & AccProtected) != 0) + modifiers ^= AccProtected; + if ((accessorBits & AccPrivate) != 0) + modifiers ^= AccPrivate; + } + if ((accessorBits & AccProtected) != 0) + if ((accessorBits & AccPrivate) != 0) + modifiers ^= AccPrivate; + } + + // check for modifiers incompatible with abstract modifier + if ((modifiers & AccAbstract) != 0) { + int incompatibleWithAbstract = + AccPrivate | AccStatic | AccFinal;// | AccSynchronized | AccNative | AccStrictfp; + if ((modifiers & incompatibleWithAbstract) != 0) + problemReporter().illegalAbstractModifierCombinationForMethod( + methodBinding.declaringClass, + (AbstractMethodDeclaration) referenceContext); + if (!methodBinding.declaringClass.isAbstract()) + problemReporter().abstractMethodInAbstractClass( + (SourceTypeBinding) methodBinding.declaringClass, + (AbstractMethodDeclaration) referenceContext); + } + + /* DISABLED for backward compatibility with javac (if enabled should also mark private methods as final) + // methods from a final class are final : 8.4.3.3 + if (methodBinding.declaringClass.isFinal()) + modifiers |= AccFinal; + */ + // native methods cannot also be tagged as strictfp +// if ((modifiers & AccNative) != 0 && (modifiers & AccStrictfp) != 0) +// problemReporter().nativeMethodsCannotBeStrictfp( +// methodBinding.declaringClass, +// (AbstractMethodDeclaration) referenceContext); + + // static members are only authorized in a static member or top level type + if (((realModifiers & AccStatic) != 0) + && methodBinding.declaringClass.isNestedType() + && !methodBinding.declaringClass.isStatic()) + problemReporter().unexpectedStaticModifierForMethod( + methodBinding.declaringClass, + (AbstractMethodDeclaration) referenceContext); + + methodBinding.modifiers = modifiers; + } + + /* Compute variable positions in scopes given an initial position offset + * ignoring unused local variables. + * + * Deal with arguments here, locals and subscopes are processed in BlockScope method + */ +// public void computeLocalVariablePositions(int initOffset, CodeStream codeStream) { +// +// boolean isReportingUnusedArgument = false; +// +// if (referenceContext instanceof AbstractMethodDeclaration) { +// AbstractMethodDeclaration methodDecl = (AbstractMethodDeclaration)referenceContext; +// MethodBinding method = methodDecl.binding; +// CompilerOptions options = compilationUnitScope().environment.options; +// if (!(method.isAbstract() +// || (method.isImplementing() && !options.reportUnusedParameterWhenImplementingAbstract) +// || (method.isOverriding() && !method.isImplementing() && !options.reportUnusedParameterWhenOverridingConcrete) +// || method.isMain())) { +// isReportingUnusedArgument = true; +// } +// } +// this.offset = initOffset; +// this.maxOffset = initOffset; +// +// // manage arguments +// int ilocal = 0, maxLocals = this.localIndex; +// while (ilocal < maxLocals) { +// LocalVariableBinding local = locals[ilocal]; +// if (local == null || !local.isArgument) break; // done with arguments +// +// // do not report fake used variable +// if (isReportingUnusedArgument +// && local.useFlag == LocalVariableBinding.UNUSED +// && ((local.declaration.bits & AstNode.IsLocalDeclarationReachableMASK) != 0)) { // declaration is reachable +// this.problemReporter().unusedArgument(local.declaration); +// } +// +// // record user-defined argument for attribute generation +// codeStream.record(local); +// +// // assign variable position +// local.resolvedPosition = this.offset; +// +// if ((local.type == LongBinding) || (local.type == DoubleBinding)) { +// this.offset += 2; +// } else { +// this.offset++; +// } +// // check for too many arguments/local variables +// if (this.offset > 0xFF) { // no more than 255 words of arguments +// this.problemReporter().noMoreAvailableSpaceForArgument(local, local.declaration); +// } +// ilocal++; +// } +// +// // sneak in extra argument before other local variables +// if (extraSyntheticArguments != null) { +// for (int iarg = 0, maxArguments = extraSyntheticArguments.length; iarg < maxArguments; iarg++){ +// SyntheticArgumentBinding argument = extraSyntheticArguments[iarg]; +// argument.resolvedPosition = this.offset; +// if ((argument.type == LongBinding) || (argument.type == DoubleBinding)){ +// this.offset += 2; +// } else { +// this.offset++; +// } +// if (this.offset > 0xFF) { // no more than 255 words of arguments +// this.problemReporter().noMoreAvailableSpaceForArgument(argument, (AstNode)this.referenceContext); +// } +// } +// } +// this.computeLocalVariablePositions(ilocal, this.offset, codeStream); +// } + + /* Error management: + * keep null for all the errors that prevent the method to be created + * otherwise return a correct method binding (but without the element + * that caused the problem) : ie : Incorrect thrown exception + */ + MethodBinding createMethod(AbstractMethodDeclaration method) { + + // is necessary to ensure error reporting + this.referenceContext = method; + method.scope = this; + SourceTypeBinding declaringClass = referenceType().binding; + int modifiers = method.modifiers | AccUnresolved; + if (method.isConstructor()) { + method.binding = new MethodBinding(modifiers, null, null, declaringClass); + checkAndSetModifiersForConstructor(method.binding); + } else { + if (declaringClass.isInterface()) + modifiers |= AccPublic | AccAbstract; + method.binding = + new MethodBinding(modifiers, method.selector, null, null, null, declaringClass); + checkAndSetModifiersForMethod(method.binding); + } + + this.isStatic = method.binding.isStatic(); + return method.binding; + } + + /* Overridden to detect the error case inside an explicit constructor call: + + class X { + int i; + X myX; + X(X x) { + this(i, myX.i, x.i); // same for super calls... only the first 2 field accesses are errors + } + } + */ + public FieldBinding findField( + TypeBinding receiverType, + char[] fieldName, + InvocationSite invocationSite) { + + FieldBinding field = super.findField(receiverType, fieldName, invocationSite); + if (field == null) + return null; + if (!field.isValidBinding()) + return field; // answer the error field + if (field.isStatic()) + return field; // static fields are always accessible + + if (!isConstructorCall || receiverType != enclosingSourceType()) + return field; + + if (invocationSite instanceof SingleNameReference) + return new ProblemFieldBinding( + field.declaringClass, + fieldName, + NonStaticReferenceInConstructorInvocation); + if (invocationSite instanceof QualifiedNameReference) { + // look to see if the field is the first binding + QualifiedNameReference name = (QualifiedNameReference) invocationSite; + if (name.binding == null) + // only true when the field is the fieldbinding at the beginning of name's tokens + return new ProblemFieldBinding( + field.declaringClass, + fieldName, + NonStaticReferenceInConstructorInvocation); + } + return field; + } + + public boolean isInsideInitializer() { + + return (referenceContext instanceof TypeDeclaration); + } + + public boolean isInsideInitializerOrConstructor() { + + return (referenceContext instanceof TypeDeclaration) + || (referenceContext instanceof ConstructorDeclaration); + } + + /* Answer the problem reporter to use for raising new problems. + * + * Note that as a side-effect, this updates the current reference context + * (unit, type or method) in case the problem handler decides it is necessary + * to abort. + */ + public ProblemReporter problemReporter() { + + MethodScope outerMethodScope; + if ((outerMethodScope = outerMostMethodScope()) == this) { + ProblemReporter problemReporter = referenceCompilationUnit().problemReporter; + problemReporter.referenceContext = referenceContext; + return problemReporter; + } else { + return outerMethodScope.problemReporter(); + } + } + + public final int recordInitializationStates(FlowInfo flowInfo) { + + if (!flowInfo.isReachable()) return -1; + + UnconditionalFlowInfo unconditionalFlowInfo = flowInfo.unconditionalInits(); + long[] extraInits = unconditionalFlowInfo.extraDefiniteInits; + long inits = unconditionalFlowInfo.definiteInits; + checkNextEntry : for (int i = lastIndex; --i >= 0;) { + if (definiteInits[i] == inits) { + long[] otherInits = extraDefiniteInits[i]; + if ((extraInits != null) && (otherInits != null)) { + if (extraInits.length == otherInits.length) { + int j, max; + for (j = 0, max = extraInits.length; j < max; j++) { + if (extraInits[j] != otherInits[j]) { + continue checkNextEntry; + } + } + return i; + } + } else { + if ((extraInits == null) && (otherInits == null)) { + return i; + } + } + } + } + + // add a new entry + if (definiteInits.length == lastIndex) { + // need a resize + System.arraycopy( + definiteInits, + 0, + (definiteInits = new long[lastIndex + 20]), + 0, + lastIndex); + System.arraycopy( + extraDefiniteInits, + 0, + (extraDefiniteInits = new long[lastIndex + 20][]), + 0, + lastIndex); + } + definiteInits[lastIndex] = inits; + if (extraInits != null) { + extraDefiniteInits[lastIndex] = new long[extraInits.length]; + System.arraycopy( + extraInits, + 0, + extraDefiniteInits[lastIndex], + 0, + extraInits.length); + } + return lastIndex++; + } + + /* Answer the reference type of this scope. + * + * It is the nearest enclosing type of this scope. + */ + public TypeDeclaration referenceType() { + + return (TypeDeclaration) ((ClassScope) parent).referenceContext; + } + + String basicToString(int tab) { + + String newLine = "\n"; //$NON-NLS-1$ + for (int i = tab; --i >= 0;) + newLine += "\t"; //$NON-NLS-1$ + + String s = newLine + "--- Method Scope ---"; //$NON-NLS-1$ + newLine += "\t"; //$NON-NLS-1$ + s += newLine + "locals:"; //$NON-NLS-1$ + for (int i = 0; i < localIndex; i++) + s += newLine + "\t" + locals[i].toString(); //$NON-NLS-1$ + s += newLine + "startIndex = " + startIndex; //$NON-NLS-1$ + s += newLine + "isConstructorCall = " + isConstructorCall; //$NON-NLS-1$ + s += newLine + "fieldDeclarationIndex = " + fieldDeclarationIndex; //$NON-NLS-1$ + s += newLine + "referenceContext = " + referenceContext; //$NON-NLS-1$ + return s; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MethodVerifier.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MethodVerifier.java new file mode 100644 index 0000000..75f862c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MethodVerifier.java @@ -0,0 +1,459 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; +import net.sourceforge.phpdt.internal.compiler.util.HashtableOfObject; +import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; + +public final class MethodVerifier implements TagBits, TypeConstants { + SourceTypeBinding type; + HashtableOfObject inheritedMethods; + HashtableOfObject currentMethods; + ReferenceBinding runtimeException; + ReferenceBinding errorException; + LookupEnvironment environment; +/* +Binding creation is responsible for reporting all problems with types: + - all modifier problems (duplicates & multiple visibility modifiers + incompatible combinations - abstract/final) + - plus invalid modifiers given the context (the verifier did not do this before) + - qualified name collisions between a type and a package (types in default packages are excluded) + - all type hierarchy problems: + - cycles in the superclass or superinterface hierarchy + - an ambiguous, invisible or missing superclass or superinterface + - extending a final class + - extending an interface instead of a class + - implementing a class instead of an interface + - implementing the same interface more than once (ie. duplicate interfaces) + - with nested types: + - shadowing an enclosing type's source name + - defining a static class or interface inside a non-static nested class + - defining an interface as a local type (local types can only be classes) +*/ +public MethodVerifier(LookupEnvironment environment) { + this.type = null; // Initialized with the public method verify(SourceTypeBinding) + this.inheritedMethods = null; + this.currentMethods = null; + this.runtimeException = null; + this.errorException = null; + this.environment = environment; +} +private void checkAgainstInheritedMethods(MethodBinding currentMethod, MethodBinding[] methods, int length) { + currentMethod.modifiers |= CompilerModifiers.AccOverriding; + for (int i = length; --i >= 0;) { + MethodBinding inheritedMethod = methods[i]; + if (!currentMethod.isAbstract() && inheritedMethod.isAbstract()) + currentMethod.modifiers |= CompilerModifiers.AccImplementing; + + if (currentMethod.returnType != inheritedMethod.returnType) { + this.problemReporter(currentMethod).incompatibleReturnType(currentMethod, inheritedMethod); + } else if (currentMethod.isStatic() != inheritedMethod.isStatic()) { // Cannot override a static method or hide an instance method + this.problemReporter(currentMethod).staticAndInstanceConflict(currentMethod, inheritedMethod); + } else { + if (currentMethod.thrownExceptions != NoExceptions) + this.checkExceptions(currentMethod, inheritedMethod); + if (inheritedMethod.isFinal()) + this.problemReporter(currentMethod).finalMethodCannotBeOverridden(currentMethod, inheritedMethod); + if (!this.isAsVisible(currentMethod, inheritedMethod)) + this.problemReporter(currentMethod).visibilityConflict(currentMethod, inheritedMethod); +// if (inheritedMethod.isViewedAsDeprecated()) +// if (!currentMethod.isViewedAsDeprecated() || environment.options.reportDeprecationInsideDeprecatedCode) +// this.problemReporter(currentMethod).overridesDeprecatedMethod(currentMethod, inheritedMethod); + } + } +} +/* +"8.4.4" +Verify that newExceptions are all included in inheritedExceptions. +Assumes all exceptions are valid and throwable. +Unchecked exceptions (compatible with runtime & error) are ignored (see the spec on pg. 203). +*/ +private void checkExceptions(MethodBinding newMethod, MethodBinding inheritedMethod) { + ReferenceBinding[] newExceptions = newMethod.thrownExceptions; + ReferenceBinding[] inheritedExceptions = inheritedMethod.thrownExceptions; + for (int i = newExceptions.length; --i >= 0;) { + ReferenceBinding newException = newExceptions[i]; + int j = inheritedExceptions.length; + while (--j > -1 && !this.isSameClassOrSubclassOf(newException, inheritedExceptions[j])); + if (j == -1) + if (!(newException.isCompatibleWith(this.runtimeException()) || newException.isCompatibleWith(this.errorException()))) + this.problemReporter(newMethod).incompatibleExceptionInThrowsClause(this.type, newMethod, inheritedMethod, newException); + } +} +private void checkInheritedMethods(MethodBinding[] methods, int length) { + TypeBinding returnType = methods[0].returnType; + int index = length; + while (--index > 0 && returnType == methods[index].returnType); + if (index > 0) { // All inherited methods do NOT have the same vmSignature + this.problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(this.type, methods, length); + return; + } + + MethodBinding concreteMethod = null; + if (!type.isInterface()) { // ignore concrete methods for interfaces + for (int i = length; --i >= 0;) { // Remember that only one of the methods can be non-abstract + if (!methods[i].isAbstract()) { + concreteMethod = methods[i]; + break; + } + } + } + if (concreteMethod == null) { + if (this.type.isClass() && !this.type.isAbstract()) { + for (int i = length; --i >= 0;) + if (!mustImplementAbstractMethod(methods[i])) return; // have already reported problem against the concrete superclass + + TypeDeclaration typeDeclaration = this.type.scope.referenceContext; + if (typeDeclaration != null) { + MethodDeclaration missingAbstractMethod = typeDeclaration.addMissingAbstractMethodFor(methods[0]); + missingAbstractMethod.scope.problemReporter().abstractMethodMustBeImplemented(this.type, methods[0]); + } else { + this.problemReporter().abstractMethodMustBeImplemented(this.type, methods[0]); + } + } + return; + } + + MethodBinding[] abstractMethods = new MethodBinding[length - 1]; + index = 0; + for (int i = length; --i >= 0;) + if (methods[i] != concreteMethod) + abstractMethods[index++] = methods[i]; + + // Remember that interfaces can only define public instance methods + if (concreteMethod.isStatic()) + // Cannot inherit a static method which is specified as an instance method by an interface + this.problemReporter().staticInheritedMethodConflicts(type, concreteMethod, abstractMethods); + if (!concreteMethod.isPublic()) + // Cannot reduce visibility of a public method specified by an interface + this.problemReporter().inheritedMethodReducesVisibility(type, concreteMethod, abstractMethods); + if (concreteMethod.thrownExceptions != NoExceptions) + for (int i = abstractMethods.length; --i >= 0;) + this.checkExceptions(concreteMethod, abstractMethods[i]); +} +/* +For each inherited method identifier (message pattern - vm signature minus the return type) + if current method exists + if current's vm signature does not match an inherited signature then complain + else compare current's exceptions & visibility against each inherited method + else + if inherited methods = 1 + if inherited is abstract && type is NOT an interface or abstract, complain + else + if vm signatures do not match complain + else + find the concrete implementation amongst the abstract methods (can only be 1) + if one exists then + it must be a public instance method + compare concrete's exceptions against each abstract method + else + complain about missing implementation only if type is NOT an interface or abstract +*/ +private void checkMethods() { + boolean mustImplementAbstractMethods = this.type.isClass() && !this.type.isAbstract(); + char[][] methodSelectors = this.inheritedMethods.keyTable; + for (int s = methodSelectors.length; --s >= 0;) { + if (methodSelectors[s] != null) { + MethodBinding[] current = (MethodBinding[]) this.currentMethods.get(methodSelectors[s]); + MethodBinding[] inherited = (MethodBinding[]) this.inheritedMethods.valueTable[s]; + + int index = -1; + MethodBinding[] matchingInherited = new MethodBinding[inherited.length]; + if (current != null) { + for (int i = 0, length1 = current.length; i < length1; i++) { + while (index >= 0) matchingInherited[index--] = null; // clear the previous contents of the matching methods + MethodBinding currentMethod = current[i]; + for (int j = 0, length2 = inherited.length; j < length2; j++) { + if (inherited[j] != null && currentMethod.areParametersEqual(inherited[j])) { + matchingInherited[++index] = inherited[j]; + inherited[j] = null; // do not want to find it again + } + } + if (index >= 0) + this.checkAgainstInheritedMethods(currentMethod, matchingInherited, index + 1); // pass in the length of matching + } + } + for (int i = 0, length = inherited.length; i < length; i++) { + while (index >= 0) matchingInherited[index--] = null; // clear the previous contents of the matching methods + if (inherited[i] != null) { + matchingInherited[++index] = inherited[i]; + for (int j = i + 1; j < length; j++) { + if (inherited[j] != null && inherited[i].areParametersEqual(inherited[j])) { + matchingInherited[++index] = inherited[j]; + inherited[j] = null; // do not want to find it again + } + } + } + if (index > 0) { + this.checkInheritedMethods(matchingInherited, index + 1); // pass in the length of matching + } else if (mustImplementAbstractMethods && index == 0 && matchingInherited[0].isAbstract()) { + if (mustImplementAbstractMethod(matchingInherited[0])) { + TypeDeclaration typeDeclaration = this.type.scope.referenceContext; + if (typeDeclaration != null) { + MethodDeclaration missingAbstractMethod = typeDeclaration.addMissingAbstractMethodFor(matchingInherited[0]); + missingAbstractMethod.scope.problemReporter().abstractMethodMustBeImplemented(this.type, matchingInherited[0]); + } else { + this.problemReporter().abstractMethodMustBeImplemented(this.type, matchingInherited[0]); + } + } + } + } + } + } +} +private void checkPackagePrivateAbstractMethod(MethodBinding abstractMethod) { + ReferenceBinding superType = this.type.superclass(); + char[] selector = abstractMethod.selector; + do { + if (!superType.isValidBinding()) return; + if (!superType.isAbstract()) return; // closer non abstract super type will be flagged instead + + MethodBinding[] methods = superType.getMethods(selector); + nextMethod : for (int m = methods.length; --m >= 0;) { + MethodBinding method = methods[m]; + if (method.returnType != abstractMethod.returnType || !method.areParametersEqual(abstractMethod)) + continue nextMethod; + if (method.isPrivate() || method.isConstructor() || method.isDefaultAbstract()) + continue nextMethod; + if (superType.fPackage == abstractMethod.declaringClass.fPackage) return; // found concrete implementation of abstract method in same package + } + } while ((superType = superType.superclass()) != abstractMethod.declaringClass); + + // non visible abstract methods cannot be overridden so the type must be defined abstract + this.problemReporter().abstractMethodCannotBeOverridden(this.type, abstractMethod); +} +/* +Binding creation is responsible for reporting: + - all modifier problems (duplicates & multiple visibility modifiers + incompatible combinations) + - plus invalid modifiers given the context... examples: + - interface methods can only be public + - abstract methods can only be defined by abstract classes + - collisions... 2 methods with identical vmSelectors + - multiple methods with the same message pattern but different return types + - ambiguous, invisible or missing return/argument/exception types + - check the type of any array is not void + - check that each exception type is Throwable or a subclass of it +*/ +private void computeInheritedMethods() { + this.inheritedMethods = new HashtableOfObject(51); // maps method selectors to an array of methods... must search to match paramaters & return type + ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][]; + int lastPosition = 0; + interfacesToVisit[lastPosition] = type.superInterfaces(); + + ReferenceBinding superType = this.type.isClass() + ? this.type.superclass() + : this.type.scope.getJavaLangObject(); // check interface methods against Object + MethodBinding[] nonVisibleDefaultMethods = null; + int nonVisibleCount = 0; + + while (superType != null) { + if (superType.isValidBinding()) { + ReferenceBinding[] itsInterfaces = superType.superInterfaces(); + if (itsInterfaces != NoSuperInterfaces) { + if (++lastPosition == interfacesToVisit.length) + System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition); + interfacesToVisit[lastPosition] = itsInterfaces; + } + + MethodBinding[] methods = superType.methods(); + nextMethod : for (int m = methods.length; --m >= 0;) { + MethodBinding method = methods[m]; + if (!(method.isPrivate() || method.isConstructor() || method.isDefaultAbstract())) { // look at all methods which are NOT private or constructors or default abstract + MethodBinding[] existingMethods = (MethodBinding[]) this.inheritedMethods.get(method.selector); + if (existingMethods != null) { + for (int i = 0, length = existingMethods.length; i < length; i++) { + if (method.returnType == existingMethods[i].returnType && method.areParametersEqual(existingMethods[i])) { + if (method.isDefault() && method.isAbstract() && method.declaringClass.fPackage != type.fPackage) + checkPackagePrivateAbstractMethod(method); + continue nextMethod; + } + } + } + if (nonVisibleDefaultMethods != null) + for (int i = 0; i < nonVisibleCount; i++) + if (method.returnType == nonVisibleDefaultMethods[i].returnType + && CharOperation.equals(method.selector, nonVisibleDefaultMethods[i].selector) + && method.areParametersEqual(nonVisibleDefaultMethods[i])) + continue nextMethod; + + if (!(method.isDefault() && method.declaringClass.fPackage != type.fPackage)) { // ignore methods which have default visibility and are NOT defined in another package + if (existingMethods == null) + existingMethods = new MethodBinding[1]; + else + System.arraycopy(existingMethods, 0, + (existingMethods = new MethodBinding[existingMethods.length + 1]), 0, existingMethods.length - 1); + existingMethods[existingMethods.length - 1] = method; + this.inheritedMethods.put(method.selector, existingMethods); + } else { + if (nonVisibleDefaultMethods == null) + nonVisibleDefaultMethods = new MethodBinding[10]; + else if (nonVisibleCount == nonVisibleDefaultMethods.length) + System.arraycopy(nonVisibleDefaultMethods, 0, + (nonVisibleDefaultMethods = new MethodBinding[nonVisibleCount * 2]), 0, nonVisibleCount); + nonVisibleDefaultMethods[nonVisibleCount++] = method; + + if (method.isAbstract() && !this.type.isAbstract()) // non visible abstract methods cannot be overridden so the type must be defined abstract + this.problemReporter().abstractMethodCannotBeOverridden(this.type, method); + + MethodBinding[] current = (MethodBinding[]) this.currentMethods.get(method.selector); + if (current != null) { // non visible methods cannot be overridden so a warning is issued + foundMatch : for (int i = 0, length = current.length; i < length; i++) { + if (method.returnType == current[i].returnType && method.areParametersEqual(current[i])) { + this.problemReporter().overridesPackageDefaultMethod(current[i], method); + break foundMatch; + } + } + } + } + } + } + superType = superType.superclass(); + } + } + + for (int i = 0; i <= lastPosition; i++) { + ReferenceBinding[] interfaces = interfacesToVisit[i]; + if (interfaces==null) { + interfaces = new ReferenceBinding[0]; + } + for (int j = 0, length = interfaces.length; j < length; j++) { + superType = interfaces[j]; + if ((superType.tagBits & InterfaceVisited) == 0) { + superType.tagBits |= InterfaceVisited; + if (superType.isValidBinding()) { + ReferenceBinding[] itsInterfaces = superType.superInterfaces(); + if (itsInterfaces != NoSuperInterfaces) { + if (++lastPosition == interfacesToVisit.length) + System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition); + interfacesToVisit[lastPosition] = itsInterfaces; + } + + MethodBinding[] methods = superType.methods(); + for (int m = methods.length; --m >= 0;) { // Interface methods are all abstract public + MethodBinding method = methods[m]; + MethodBinding[] existingMethods = (MethodBinding[]) this.inheritedMethods.get(method.selector); + if (existingMethods == null) + existingMethods = new MethodBinding[1]; + else + System.arraycopy(existingMethods, 0, + (existingMethods = new MethodBinding[existingMethods.length + 1]), 0, existingMethods.length - 1); + existingMethods[existingMethods.length - 1] = method; + this.inheritedMethods.put(method.selector, existingMethods); + } + } + } + } + } + + // bit reinitialization + for (int i = 0; i <= lastPosition; i++) { + ReferenceBinding[] interfaces = interfacesToVisit[i]; + if (interfaces==null) { + interfaces = new ReferenceBinding[0]; + } + for (int j = 0, length = interfaces.length; j < length; j++) + interfaces[j].tagBits &= ~InterfaceVisited; + } +} +private void computeMethods() { + MethodBinding[] methods = type.methods(); + if (methods==null) { + methods = new MethodBinding[0]; + } + int size = methods.length; + this.currentMethods = new HashtableOfObject(size == 0 ? 1 : size); // maps method selectors to an array of methods... must search to match paramaters & return type + for (int m = size; --m >= 0;) { + MethodBinding method = methods[m]; + if (!(method.isConstructor() || method.isDefaultAbstract())) { // keep all methods which are NOT constructors or default abstract + MethodBinding[] existingMethods = (MethodBinding[]) this.currentMethods.get(method.selector); + if (existingMethods == null) + existingMethods = new MethodBinding[1]; + else + System.arraycopy(existingMethods, 0, + (existingMethods = new MethodBinding[existingMethods.length + 1]), 0, existingMethods.length - 1); + existingMethods[existingMethods.length - 1] = method; + this.currentMethods.put(method.selector, existingMethods); + } + } +} +private ReferenceBinding errorException() { + if (errorException == null) + this.errorException = this.type.scope.getJavaLangError(); + return errorException; +} +private boolean isAsVisible(MethodBinding newMethod, MethodBinding inheritedMethod) { + if (inheritedMethod.modifiers == newMethod.modifiers) return true; + + if (newMethod.isPublic()) return true; // Covers everything + if (inheritedMethod.isPublic()) return false; + + if (newMethod.isProtected()) return true; + if (inheritedMethod.isProtected()) return false; + + return !newMethod.isPrivate(); // The inheritedMethod cannot be private since it would not be visible +} +private boolean isSameClassOrSubclassOf(ReferenceBinding testClass, ReferenceBinding superclass) { + do { + if (testClass == superclass) return true; + } while ((testClass = testClass.superclass()) != null); + return false; +} +private boolean mustImplementAbstractMethod(MethodBinding abstractMethod) { + // if the type's superclass is an abstract class, then all abstract methods must be implemented + // otherwise, skip it if the type's superclass must implement any of the inherited methods + ReferenceBinding superclass = this.type.superclass(); + ReferenceBinding declaringClass = abstractMethod.declaringClass; + if (declaringClass.isClass()) { + while (superclass.isAbstract() && superclass != declaringClass) + superclass = superclass.superclass(); // find the first concrete superclass or the abstract declaringClass + } else { + if (this.type.implementsInterface(declaringClass, false)) { + if (this.type.isAbstract()) return false; // leave it for the subclasses + if (!superclass.implementsInterface(declaringClass, true)) // only if a superclass does not also implement the interface + return true; + } + while (superclass.isAbstract() && !superclass.implementsInterface(declaringClass, false)) + superclass = superclass.superclass(); // find the first concrete superclass or the superclass which implements the interface + } + return superclass.isAbstract(); // if it is a concrete class then we have already reported problem against it +} +private ProblemReporter problemReporter() { + return this.type.scope.problemReporter(); +} +private ProblemReporter problemReporter(MethodBinding currentMethod) { + ProblemReporter reporter = problemReporter(); + if (currentMethod.declaringClass == type) // only report against the currentMethod if its implemented by the type + reporter.referenceContext = currentMethod.sourceMethod(); + return reporter; +} +private ReferenceBinding runtimeException() { + if (runtimeException == null) + this.runtimeException = this.type.scope.getJavaLangRuntimeException(); + return runtimeException; +} +public void verify(SourceTypeBinding type) { + this.type = type; + this.computeMethods(); + this.computeInheritedMethods(); + this.checkMethods(); +} +public String toString() { + StringBuffer buffer = new StringBuffer(10); + buffer.append("MethodVerifier for type: "); //$NON-NLS-1$ + buffer.append(type.readableName()); + buffer.append('\n'); + buffer.append("\t-inherited methods: "); //$NON-NLS-1$ + buffer.append(this.inheritedMethods); + return buffer.toString(); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/NestedTypeBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/NestedTypeBinding.java new file mode 100644 index 0000000..2b95fd2 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/NestedTypeBinding.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +public class NestedTypeBinding extends SourceTypeBinding { + + public SourceTypeBinding enclosingType; + + public SyntheticArgumentBinding[] enclosingInstances; + public SyntheticArgumentBinding[] outerLocalVariables; + public int enclosingInstancesSlotSize; // amount of slots used by synthetic enclosing instances + public int outerLocalVariablesSlotSize; // amount of slots used by synthetic outer local variables + + public NestedTypeBinding(char[][] typeName, ClassScope scope, SourceTypeBinding enclosingType) { + super(typeName, enclosingType.fPackage, scope); + this.tagBits |= IsNestedType; + this.enclosingType = enclosingType; + } + + /* Add a new synthetic argument for . + * Answer the new argument or the existing argument if one already existed. + */ + public SyntheticArgumentBinding addSyntheticArgument(LocalVariableBinding actualOuterLocalVariable) { + SyntheticArgumentBinding synthLocal = null; + + if (outerLocalVariables == null) { + synthLocal = new SyntheticArgumentBinding(actualOuterLocalVariable); + outerLocalVariables = new SyntheticArgumentBinding[] {synthLocal}; + } else { + int size = outerLocalVariables.length; + int newArgIndex = size; + for (int i = size; --i >= 0;) { // must search backwards + if (outerLocalVariables[i].actualOuterLocalVariable == actualOuterLocalVariable) + return outerLocalVariables[i]; // already exists + if (outerLocalVariables[i].id > actualOuterLocalVariable.id) + newArgIndex = i; + } + SyntheticArgumentBinding[] synthLocals = new SyntheticArgumentBinding[size + 1]; + System.arraycopy(outerLocalVariables, 0, synthLocals, 0, newArgIndex); + synthLocals[newArgIndex] = synthLocal = new SyntheticArgumentBinding(actualOuterLocalVariable); + System.arraycopy(outerLocalVariables, newArgIndex, synthLocals, newArgIndex + 1, size - newArgIndex); + outerLocalVariables = synthLocals; + } + //System.out.println("Adding synth arg for local var: " + new String(actualOuterLocalVariable.name) + " to: " + new String(this.readableName())); + if (scope.referenceCompilationUnit().isPropagatingInnerClassEmulation) + this.updateInnerEmulationDependents(); + return synthLocal; + } + + /* Add a new synthetic argument for . + * Answer the new argument or the existing argument if one already existed. + */ + public SyntheticArgumentBinding addSyntheticArgument(ReferenceBinding enclosingType) { + SyntheticArgumentBinding synthLocal = null; + if (enclosingInstances == null) { + synthLocal = new SyntheticArgumentBinding(enclosingType); + enclosingInstances = new SyntheticArgumentBinding[] {synthLocal}; + } else { + int size = enclosingInstances.length; + int newArgIndex = size; + for (int i = size; --i >= 0;) { + if (enclosingInstances[i].type == enclosingType) + return enclosingInstances[i]; // already exists + if (this.enclosingType() == enclosingType) + newArgIndex = 0; + } + SyntheticArgumentBinding[] newInstances = new SyntheticArgumentBinding[size + 1]; + System.arraycopy(enclosingInstances, 0, newInstances, newArgIndex == 0 ? 1 : 0, size); + newInstances[newArgIndex] = synthLocal = new SyntheticArgumentBinding(enclosingType); + enclosingInstances = newInstances; + } + //System.out.println("Adding synth arg for enclosing type: " + new String(enclosingType.readableName()) + " to: " + new String(this.readableName())); + if (scope.referenceCompilationUnit().isPropagatingInnerClassEmulation) + this.updateInnerEmulationDependents(); + return synthLocal; + } + + /* Add a new synthetic argument and field for . + * Answer the new argument or the existing argument if one already existed. + */ + public SyntheticArgumentBinding addSyntheticArgumentAndField(LocalVariableBinding actualOuterLocalVariable) { + SyntheticArgumentBinding synthLocal = addSyntheticArgument(actualOuterLocalVariable); + if (synthLocal == null) return null; + + if (synthLocal.matchingField == null) + synthLocal.matchingField = addSyntheticField(actualOuterLocalVariable); + return synthLocal; + } + + /* Add a new synthetic argument and field for . + * Answer the new argument or the existing argument if one already existed. + */ + public SyntheticArgumentBinding addSyntheticArgumentAndField(ReferenceBinding enclosingType) { + SyntheticArgumentBinding synthLocal = addSyntheticArgument(enclosingType); + if (synthLocal == null) return null; + + if (synthLocal.matchingField == null) + synthLocal.matchingField = addSyntheticField(enclosingType); + return synthLocal; + } + + /** + * Compute the resolved positions for all the synthetic arguments + */ + final public void computeSyntheticArgumentSlotSizes() { + + int slotSize = 0; + // insert enclosing instances first, followed by the outerLocals + SyntheticArgumentBinding[] enclosingInstances = this.syntheticEnclosingInstances(); + int enclosingInstancesCount = enclosingInstances == null ? 0 : enclosingInstances.length; + for (int i = 0; i < enclosingInstancesCount; i++){ + SyntheticArgumentBinding argument = enclosingInstances[i]; + // position the enclosing instance synthetic arg + argument.resolvedPosition = slotSize + 1; // shift by 1 to leave room for aload0==this + if (slotSize + 1 > 0xFF) { // no more than 255 words of arguments + this.scope.problemReporter().noMoreAvailableSpaceForArgument(argument, this.scope.referenceType()); + } + if ((argument.type == LongBinding) || (argument.type == DoubleBinding)){ + slotSize += 2; + } else { + slotSize ++; + } + } + this.enclosingInstancesSlotSize = slotSize; + + slotSize = 0; // reset, outer local are not positionned yet, since will be appended to user arguments + SyntheticArgumentBinding[] outerLocals = this.syntheticOuterLocalVariables(); + int outerLocalsCount = outerLocals == null ? 0 : outerLocals.length; + for (int i = 0; i < outerLocalsCount; i++){ + SyntheticArgumentBinding argument = outerLocals[i]; + // do NOT position the outerlocal synthetic arg yet, since will be appended to user arguments + if ((argument.type == LongBinding) || (argument.type == DoubleBinding)){ + slotSize += 2; + } else { + slotSize ++; + } + } + this.outerLocalVariablesSlotSize = slotSize; + } + + /* Answer the receiver's enclosing type... null if the receiver is a top level type. + */ + public ReferenceBinding enclosingType() { + + return enclosingType; + } + + /* Answer the synthetic argument for or null if one does not exist. + */ + public SyntheticArgumentBinding getSyntheticArgument(LocalVariableBinding actualOuterLocalVariable) { + + if (outerLocalVariables == null) return null; // is null if no outer local variables are known + + for (int i = outerLocalVariables.length; --i >= 0;) + if (outerLocalVariables[i].actualOuterLocalVariable == actualOuterLocalVariable) + return outerLocalVariables[i]; + return null; + } + + public SyntheticArgumentBinding[] syntheticEnclosingInstances() { + return enclosingInstances; // is null if no enclosing instances are required + } + + public ReferenceBinding[] syntheticEnclosingInstanceTypes() { + if (enclosingInstances == null) + return null; + + int length = enclosingInstances.length; + ReferenceBinding types[] = new ReferenceBinding[length]; + for (int i = 0; i < length; i++) + types[i] = (ReferenceBinding) enclosingInstances[i].type; + return types; + } + + public SyntheticArgumentBinding[] syntheticOuterLocalVariables() { + + return outerLocalVariables; // is null if no outer locals are required + } + + /* + * Trigger the dependency mechanism forcing the innerclass emulation + * to be propagated to all dependent source types. + */ + public void updateInnerEmulationDependents() { + // nothing to do in general, only local types are doing anything + } + + /* Answer the synthetic argument for or null if one does not exist. + */ + public SyntheticArgumentBinding getSyntheticArgument(ReferenceBinding targetEnclosingType, boolean onlyExactMatch) { + + if (enclosingInstances == null) return null; // is null if no enclosing instances are known + + // exact match + for (int i = enclosingInstances.length; --i >= 0;) + if (enclosingInstances[i].type == targetEnclosingType) + if (enclosingInstances[i].actualOuterLocalVariable == null) + return enclosingInstances[i]; + + // type compatibility : to handle cases such as + // class T { class M{}} + // class S extends T { class N extends M {}} --> need to use S as a default enclosing instance for the super constructor call in N(). + if (!onlyExactMatch){ + for (int i = enclosingInstances.length; --i >= 0;) + if (enclosingInstances[i].actualOuterLocalVariable == null) + if (targetEnclosingType.isSuperclassOf((ReferenceBinding) enclosingInstances[i].type)) + return enclosingInstances[i]; + } + return null; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/PackageBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/PackageBinding.java new file mode 100644 index 0000000..f94c98b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/PackageBinding.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.util.HashtableOfPackage; +import net.sourceforge.phpdt.internal.compiler.util.HashtableOfType; + +public class PackageBinding extends Binding implements TypeConstants { + public char[][] compoundName; + PackageBinding parent; + LookupEnvironment environment; + HashtableOfType knownTypes; + HashtableOfPackage knownPackages; +protected PackageBinding() { +} +public PackageBinding(char[][] compoundName, PackageBinding parent, LookupEnvironment environment) { + this.compoundName = compoundName; + this.parent = parent; + this.environment = environment; + this.knownTypes = null; // initialized if used... class counts can be very large 300-600 + this.knownPackages = new HashtableOfPackage(3); // sub-package counts are typically 0-3 +} +public PackageBinding(char[] topLevelPackageName, LookupEnvironment environment) { + this(new char[][] {topLevelPackageName}, null, environment); +} +/* Create the default package. +*/ + +public PackageBinding(LookupEnvironment environment) { + this(CharOperation.NO_CHAR_CHAR, null, environment); +} +private void addNotFoundPackage(char[] simpleName) { + knownPackages.put(simpleName, LookupEnvironment.TheNotFoundPackage); +} +private void addNotFoundType(char[] simpleName) { + if (knownTypes == null) + knownTypes = new HashtableOfType(25); + knownTypes.put(simpleName, LookupEnvironment.TheNotFoundType); +} +void addPackage(PackageBinding element) { + knownPackages.put(element.compoundName[element.compoundName.length - 1], element); +} +void addType(ReferenceBinding element) { + if (knownTypes == null) + knownTypes = new HashtableOfType(25); + knownTypes.put(element.compoundName[element.compoundName.length - 1], element); +} +/* API +* Answer the receiver's binding type from Binding.BindingID. +*/ + +public final int bindingType() { + return PACKAGE; +} +private PackageBinding findPackage(char[] name) { + if (!environment.isPackage(this.compoundName, name)) + return null; + + char[][] compoundName = CharOperation.arrayConcat(this.compoundName, name); + PackageBinding newPackageBinding = new PackageBinding(compoundName, this, environment); + addPackage(newPackageBinding); + return newPackageBinding; +} +/* Answer the subpackage named name; ask the oracle for the package if its not in the cache. +* Answer null if it could not be resolved. +* +* NOTE: This should only be used when we know there is NOT a type with the same name. +*/ + +PackageBinding getPackage(char[] name) { + PackageBinding binding = getPackage0(name); + if (binding != null) { + if (binding == LookupEnvironment.TheNotFoundPackage) + return null; + else + return binding; + } + if ((binding = findPackage(name)) != null) + return binding; + + // not found so remember a problem package binding in the cache for future lookups + addNotFoundPackage(name); + return null; +} +/* Answer the subpackage named name if it exists in the cache. +* Answer theNotFoundPackage if it could not be resolved the first time +* it was looked up, otherwise answer null. +* +* NOTE: Senders must convert theNotFoundPackage into a real problem +* package if its to returned. +*/ + +PackageBinding getPackage0(char[] name) { + return knownPackages.get(name); +} +/* Answer the type named name; ask the oracle for the type if its not in the cache. +* Answer a NotVisible problem type if the type is not visible from the invocationPackage. +* Answer null if it could not be resolved. +* +* NOTE: This should only be used by source types/scopes which know there is NOT a +* package with the same name. +*/ + +ReferenceBinding getType(char[] name) { + ReferenceBinding binding = getType0(name); + if (binding == null) { + if ((binding = environment.askForType(this, name)) == null) { + // not found so remember a problem type binding in the cache for future lookups + addNotFoundType(name); + return null; + } + } + + if (binding == LookupEnvironment.TheNotFoundType) + return null; + if (binding instanceof UnresolvedReferenceBinding) + binding = ((UnresolvedReferenceBinding) binding).resolve(environment); + if (binding.isNestedType()) + return new ProblemReferenceBinding(name, InternalNameProvided); + return binding; +} +/* Answer the type named name if it exists in the cache. +* Answer theNotFoundType if it could not be resolved the first time +* it was looked up, otherwise answer null. +* +* NOTE: Senders must convert theNotFoundType into a real problem +* reference type if its to returned. +*/ + +ReferenceBinding getType0(char[] name) { + if (knownTypes == null) + return null; + return knownTypes.get(name); +} +/* Answer the package or type named name; ask the oracle if it is not in the cache. +* Answer null if it could not be resolved. +* +* When collisions exist between a type name & a package name, answer the package. +* Treat the type as if it does not exist... a problem was already reported when the type was defined. +* +* NOTE: no visibility checks are performed. +* THIS SHOULD ONLY BE USED BY SOURCE TYPES/SCOPES. +*/ + +public Binding getTypeOrPackage(char[] name) { + PackageBinding packageBinding = getPackage0(name); + if (packageBinding != null && packageBinding != LookupEnvironment.TheNotFoundPackage) + return packageBinding; + + ReferenceBinding typeBinding = getType0(name); + if (typeBinding != null && typeBinding != LookupEnvironment.TheNotFoundType) { + if (typeBinding instanceof UnresolvedReferenceBinding) + typeBinding = ((UnresolvedReferenceBinding) typeBinding).resolve(environment); + if (typeBinding.isNestedType()) + return new ProblemReferenceBinding(name, InternalNameProvided); + return typeBinding; + } + + // always look for the name as a sub-package if its not a known type + if (packageBinding == null && (packageBinding = findPackage(name)) != null) + return packageBinding; + if (typeBinding == null) { + // if no package was found, find the type named name relative to the receiver + if ((typeBinding = environment.askForType(this, name)) != null) { + if (typeBinding.isNestedType()) + return new ProblemReferenceBinding(name, InternalNameProvided); + return typeBinding; + } + + // Since name could not be found, add problem bindings + // to the collections so it will be reported as an error next time. + addNotFoundPackage(name); + addNotFoundType(name); + } else { + if (packageBinding == LookupEnvironment.TheNotFoundPackage) + packageBinding = null; + if (typeBinding == LookupEnvironment.TheNotFoundType) + typeBinding = null; + } + + if (packageBinding != null) + return packageBinding; + else + return typeBinding; +} +public char[] readableName() /*java.lang*/ { + return CharOperation.concatWith(compoundName, '.'); +} +public String toString() { + if (compoundName == CharOperation.NO_CHAR_CHAR) + return "The Default Package"; //$NON-NLS-1$ + else + return "package " + ((compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED"); //$NON-NLS-1$ //$NON-NLS-2$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemBinding.java new file mode 100644 index 0000000..a560f9f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemBinding.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; + +public class ProblemBinding extends Binding { + public char[] name; + public ReferenceBinding searchType; + private int problemId; +// NOTE: must only answer the subset of the name related to the problem + +public ProblemBinding(char[][] compoundName, int problemId) { + this(CharOperation.concatWith(compoundName, '.'), problemId); +} +// NOTE: must only answer the subset of the name related to the problem + +public ProblemBinding(char[][] compoundName, ReferenceBinding searchType, int problemId) { + this(CharOperation.concatWith(compoundName, '.'), searchType, problemId); +} +ProblemBinding(char[] name, int problemId) { + this.name = name; + this.problemId = problemId; +} +ProblemBinding(char[] name, ReferenceBinding searchType, int problemId) { + this(name, problemId); + this.searchType = searchType; +} +/* API +* Answer the receiver's binding type from Binding.BindingID. +*/ + +public final int bindingType() { + return VARIABLE | TYPE; +} +/* API +* Answer the problem id associated with the receiver. +* NoError if the receiver is a valid binding. +*/ + +public final int problemId() { + return problemId; +} +public char[] readableName() { + return name; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemFieldBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemFieldBinding.java new file mode 100644 index 0000000..21365f4 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemFieldBinding.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; + +public class ProblemFieldBinding extends FieldBinding { + private int problemId; +// NOTE: must only answer the subset of the name related to the problem + +public ProblemFieldBinding(ReferenceBinding declaringClass, char[][] compoundName, int problemId) { + this(declaringClass, CharOperation.concatWith(compoundName, '.'), problemId); +} +public ProblemFieldBinding(ReferenceBinding declaringClass, char[] name, int problemId) { + this.declaringClass = declaringClass; + this.name = name; + this.problemId = problemId; +} +/* API +* Answer the problem id associated with the receiver. +* NoError if the receiver is a valid binding. +*/ + +public final int problemId() { + return problemId; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemMethodBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemMethodBinding.java new file mode 100644 index 0000000..19840fc --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemMethodBinding.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +public class ProblemMethodBinding extends MethodBinding { + private int problemId; + public MethodBinding closestMatch; +public ProblemMethodBinding(char[] selector, TypeBinding[] args, int problemId) { + this.selector = selector; + this.parameters = (args == null || args.length == 0) ? NoParameters : args; + this.problemId = problemId; +} +public ProblemMethodBinding(char[] selector, TypeBinding[] args, ReferenceBinding declaringClass, int problemId) { + this.selector = selector; + this.parameters = (args == null || args.length == 0) ? NoParameters : args; + this.declaringClass = declaringClass; + this.problemId = problemId; +} +public ProblemMethodBinding(MethodBinding closestMatch, char[] selector, TypeBinding[] args, int problemId) { + this(selector, args, problemId); + this.closestMatch = closestMatch; + if (closestMatch != null) this.declaringClass = closestMatch.declaringClass; +} +/* API +* Answer the problem id associated with the receiver. +* NoError if the receiver is a valid binding. +*/ + +public final int problemId() { + return problemId; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemPackageBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemPackageBinding.java new file mode 100644 index 0000000..ca3570d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemPackageBinding.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +public class ProblemPackageBinding extends PackageBinding { + private int problemId; +// NOTE: must only answer the subset of the name related to the problem + +ProblemPackageBinding(char[][] compoundName, int problemId) { + this.compoundName = compoundName; + this.problemId = problemId; +} +ProblemPackageBinding(char[] name, int problemId) { + this(new char[][] {name}, problemId); +} +/* API +* Answer the problem id associated with the receiver. +* NoError if the receiver is a valid binding. +*/ + +public final int problemId() { + return problemId; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemReasons.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemReasons.java index fd83b60..dd05fd9 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemReasons.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemReasons.java @@ -11,12 +11,13 @@ package net.sourceforge.phpdt.internal.compiler.lookup; public interface ProblemReasons { - final int NoError = 0; - final int NotFound = 1; - final int NotVisible = 2; - final int Ambiguous = 3; - final int InternalNameProvided = 4; // used if an internal name is used in source - final int InheritedNameHidesEnclosingName = 5; - final int NonStaticReferenceInConstructorInvocation = 6; - final int NonStaticReferenceInStaticContext = 7; + final int NoError = 0; + final int NotFound = 1; + final int NotVisible = 2; + final int Ambiguous = 3; + final int InternalNameProvided = 4; // used if an internal name is used in source + final int InheritedNameHidesEnclosingName = 5; + final int NonStaticReferenceInConstructorInvocation = 6; + final int NonStaticReferenceInStaticContext = 7; + final int ReceiverTypeNotVisible = 8; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemReferenceBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemReferenceBinding.java new file mode 100644 index 0000000..5283ad3 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ProblemReferenceBinding.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +public class ProblemReferenceBinding extends ReferenceBinding { + public Binding original; + private int problemId; +// NOTE: must only answer the subset of the name related to the problem + +public ProblemReferenceBinding(char[][] compoundName, int problemId) { + this(compoundName, null, problemId); +} +public ProblemReferenceBinding(char[] name, int problemId) { + this(new char[][] {name}, null, problemId); +} + +public ProblemReferenceBinding(char[][] compoundName, Binding original, int problemId) { + this.compoundName = compoundName; + this.original = original; + this.problemId = problemId; +} +public ProblemReferenceBinding(char[] name, Binding original, int problemId) { + this(new char[][] {name}, original, problemId); +} +/* API +* Answer the problem id associated with the receiver. +* NoError if the receiver is a valid binding. +*/ + +public final int problemId() { + return problemId; +} + +/** + * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#shortReadableName() + */ +public char[] shortReadableName() { + return readableName(); +} + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ReferenceBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ReferenceBinding.java new file mode 100644 index 0000000..81faa08 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/ReferenceBinding.java @@ -0,0 +1,609 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.env.IDependent; + +/* +Not all fields defined by this type (& its subclasses) are initialized when it is created. +Some are initialized only when needed. + +Accessors have been provided for some public fields so all TypeBindings have the same API... +but access public fields directly whenever possible. +Non-public fields have accessors which should be used everywhere you expect the field to be initialized. + +null is NOT a valid value for a non-public field... it just means the field is not initialized. +*/ + +abstract public class ReferenceBinding extends TypeBinding implements IDependent { + public char[][] compoundName; + public char[] sourceName; + public int modifiers; + public PackageBinding fPackage; + + char[] fileName; + char[] constantPoolName; + char[] signature; + +public FieldBinding[] availableFields() { + return fields(); +} + +public MethodBinding[] availableMethods() { + return methods(); +} +/* Answer true if the receiver can be instantiated +*/ + +public boolean canBeInstantiated() { + return !(isAbstract() || isInterface()); +} +/* Answer true if the receiver is visible to the invocationPackage. +*/ + +public final boolean canBeSeenBy(PackageBinding invocationPackage) { + if (isPublic()) return true; + if (isPrivate()) return false; + + // isProtected() or isDefault() + return invocationPackage == fPackage; +} +/* Answer true if the receiver is visible to the receiverType and the invocationType. +*/ + +public final boolean canBeSeenBy(ReferenceBinding receiverType, SourceTypeBinding invocationType) { + if (isPublic()) return true; + + if (invocationType == this && invocationType == receiverType) return true; + + if (isProtected()) { + + // answer true if the invocationType is the declaringClass or they are in the same package + // OR the invocationType is a subclass of the declaringClass + // AND the invocationType is the invocationType or its subclass + // OR the type is a static method accessed directly through a type + // OR previous assertions are true for one of the enclosing type + if (invocationType == this) return true; + if (invocationType.fPackage == fPackage) return true; + + ReferenceBinding currentType = invocationType; + ReferenceBinding declaringClass = enclosingType(); // protected types always have an enclosing one + if (declaringClass == null) return false; // could be null if incorrect top-level protected type + //int depth = 0; + do { + if (declaringClass == invocationType) return true; + if (declaringClass.isSuperclassOf(currentType)) return true; + //depth++; + currentType = currentType.enclosingType(); + } while (currentType != null); + return false; + } + + if (isPrivate()) { + // answer true if the receiverType is the receiver or its enclosingType + // AND the invocationType and the receiver have a common enclosingType + if (!(receiverType == this || receiverType == enclosingType())) return false; + + if (invocationType != this) { + ReferenceBinding outerInvocationType = invocationType; + ReferenceBinding temp = outerInvocationType.enclosingType(); + while (temp != null) { + outerInvocationType = temp; + temp = temp.enclosingType(); + } + + ReferenceBinding outerDeclaringClass = this; + temp = outerDeclaringClass.enclosingType(); + while (temp != null) { + outerDeclaringClass = temp; + temp = temp.enclosingType(); + } + if (outerInvocationType != outerDeclaringClass) return false; + } + return true; + } + + // isDefault() + if (invocationType.fPackage != fPackage) return false; + + ReferenceBinding type = receiverType; + ReferenceBinding declaringClass = enclosingType() == null ? this : enclosingType(); + do { + if (declaringClass == type) return true; + if (fPackage != type.fPackage) return false; + } while ((type = type.superclass()) != null); + return false; +} +/* + * Answer true if the receiver is visible to the type provided by the scope. + */ + +public final boolean canBeSeenBy(Scope scope) { + + if (isPublic()) return true; + + if (scope.kind == Scope.COMPILATION_UNIT_SCOPE){ + return this.canBeSeenBy(((CompilationUnitScope)scope).fPackage); + } + + SourceTypeBinding invocationType = scope.enclosingSourceType(); + if (invocationType == this) return true; + + if (isProtected()) { + // answer true if the invocationType is the declaringClass or they are in the same package + // OR the invocationType is a subclass of the declaringClass + // AND the invocationType is the invocationType or its subclass + // OR the type is a static method accessed directly through a type + // OR previous assertions are true for one of the enclosing type + if (invocationType.fPackage == fPackage) return true; + + ReferenceBinding currentType = invocationType; + ReferenceBinding declaringClass = enclosingType(); // protected types always have an enclosing one + if (declaringClass == null) return false; // could be null if incorrect top-level protected type + // int depth = 0; + do { + if (declaringClass == invocationType) return true; + if (declaringClass.isSuperclassOf(currentType)) return true; + // depth++; + currentType = currentType.enclosingType(); + } while (currentType != null); + return false; + } + if (isPrivate()) { + // answer true if the receiver and the invocationType have a common enclosingType + // already know they are not the identical type + ReferenceBinding outerInvocationType = invocationType; + ReferenceBinding temp = outerInvocationType.enclosingType(); + while (temp != null) { + outerInvocationType = temp; + temp = temp.enclosingType(); + } + + ReferenceBinding outerDeclaringClass = this; + temp = outerDeclaringClass.enclosingType(); + while (temp != null) { + outerDeclaringClass = temp; + temp = temp.enclosingType(); + } + return outerInvocationType == outerDeclaringClass; + } + + // isDefault() + return invocationType.fPackage == fPackage; +} +public void computeId() { + if (compoundName.length != 3) { + if (compoundName.length == 4 && CharOperation.equals(JAVA_LANG_REFLECT_CONSTRUCTOR, compoundName)) { + id = T_JavaLangReflectConstructor; + return; + } + return; // all other types are in java.*.* + } + + if (!CharOperation.equals(JAVA, compoundName[0])) + return; // assumes we only look up types in java + + if (!CharOperation.equals(LANG, compoundName[1])) { + if (CharOperation.equals(JAVA_IO_PRINTSTREAM, compoundName)) { + id = T_JavaIoPrintStream; + return; + } + return; // all other types are in java.lang + } + + if (CharOperation.equals(JAVA_LANG_OBJECT, compoundName)) { + id = T_JavaLangObject; + return; + } + if (CharOperation.equals(JAVA_LANG_STRING, compoundName)) { + id = T_JavaLangString; + return; + } + + // well-known exception types + if (CharOperation.equals(JAVA_LANG_THROWABLE, compoundName)) { + id = T_JavaLangThrowable; + return; + } + if (CharOperation.equals(JAVA_LANG_ERROR, compoundName)) { + id = T_JavaLangError; + return; + } + if (CharOperation.equals(JAVA_LANG_EXCEPTION, compoundName)) { + id = T_JavaLangException; + return; + } + if (CharOperation.equals(JAVA_LANG_CLASSNOTFOUNDEXCEPTION, compoundName)) { + id = T_JavaLangClassNotFoundException; + return; + } + if (CharOperation.equals(JAVA_LANG_NOCLASSDEFERROR, compoundName)) { + id = T_JavaLangNoClassDefError; + return; + } + + // other well-known types + if (CharOperation.equals(JAVA_LANG_CLASS, compoundName)) { + id = T_JavaLangClass; + return; + } + if (CharOperation.equals(JAVA_LANG_STRINGBUFFER, compoundName)) { + id = T_JavaLangStringBuffer; + return; + } + if (CharOperation.equals(JAVA_LANG_SYSTEM, compoundName)) { + id = T_JavaLangSystem; + return; + } + + if (CharOperation.equals(JAVA_LANG_INTEGER, compoundName)) { + id = T_JavaLangInteger; + return; + } + + if (CharOperation.equals(JAVA_LANG_BYTE, compoundName)) { + id = T_JavaLangByte; + return; + } + + if (CharOperation.equals(JAVA_LANG_CHARACTER, compoundName)) { + id = T_JavaLangCharacter; + return; + } + + if (CharOperation.equals(JAVA_LANG_FLOAT, compoundName)) { + id = T_JavaLangFloat; + return; + } + + if (CharOperation.equals(JAVA_LANG_DOUBLE, compoundName)) { + id = T_JavaLangDouble; + return; + } + + if (CharOperation.equals(JAVA_LANG_BOOLEAN, compoundName)) { + id = T_JavaLangBoolean; + return; + } + + if (CharOperation.equals(JAVA_LANG_SHORT, compoundName)) { + id = T_JavaLangShort; + return; + } + + if (CharOperation.equals(JAVA_LANG_LONG, compoundName)) { + id = T_JavaLangLong; + return; + } + + if (CharOperation.equals(JAVA_LANG_VOID, compoundName)) { + id = T_JavaLangVoid; + return; + } + + if (CharOperation.equals(JAVA_LANG_ASSERTIONERROR, compoundName)) { + id = T_JavaLangAssertionError; + return; + } +} +/* Answer the receiver's constant pool name. +* +* NOTE: This method should only be used during/after code gen. +*/ + +public char[] constantPoolName() /* java/lang/Object */ { + if (constantPoolName != null) return constantPoolName; + return constantPoolName = CharOperation.concatWith(compoundName, '/'); +} +String debugName() { + return (compoundName != null) ? new String(readableName()) : "UNNAMED TYPE"; //$NON-NLS-1$ +} +public final int depth() { + int depth = 0; + ReferenceBinding current = this; + while ((current = current.enclosingType()) != null) + depth++; + return depth; +} +/* Answer the receiver's enclosing type... null if the receiver is a top level type. +*/ + +public ReferenceBinding enclosingType() { + return null; +} +public final ReferenceBinding enclosingTypeAt(int relativeDepth) { + ReferenceBinding current = this; + while (relativeDepth-- > 0 && current != null) + current = current.enclosingType(); + return current; +} +public int fieldCount() { + return fields().length; +} +public FieldBinding[] fields() { + return NoFields; +} +public final int getAccessFlags() { + return modifiers & AccJustFlag; +} +public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) { + return null; +} +public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes) { + return null; +} +public FieldBinding getField(char[] fieldName) { + return null; +} +/** + * Answer the file name which defines the type. + * + * The path part (optional) must be separated from the actual + * file proper name by a java.io.File.separator. + * + * The proper file name includes the suffix extension (e.g. ".java") + * + * e.g. "c:/com/ibm/compiler/java/api/Compiler.java" + */ + +public char[] getFileName() { + return fileName; +} +public ReferenceBinding getMemberType(char[] typeName) { + ReferenceBinding[] memberTypes = memberTypes(); + for (int i = memberTypes.length; --i >= 0;) + if (CharOperation.equals(memberTypes[i].sourceName, typeName)) + return memberTypes[i]; + return null; +} +public MethodBinding[] getMethods(char[] selector) { + return NoMethods; +} +public PackageBinding getPackage() { + return fPackage; +} +/* Answer true if the receiver implements anInterface or is identical to anInterface. +* If searchHierarchy is true, then also search the receiver's superclasses. +* +* NOTE: Assume that anInterface is an interface. +*/ + +public boolean implementsInterface(ReferenceBinding anInterface, boolean searchHierarchy) { + if (this == anInterface) + return true; + + ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][]; + int lastPosition = -1; + ReferenceBinding currentType = this; + do { + ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); + if (itsInterfaces != NoSuperInterfaces) { + if (++lastPosition == interfacesToVisit.length) + System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition); + interfacesToVisit[lastPosition] = itsInterfaces; + } + } while (searchHierarchy && (currentType = currentType.superclass()) != null); + + for (int i = 0; i <= lastPosition; i++) { + ReferenceBinding[] interfaces = interfacesToVisit[i]; + for (int j = 0, length = interfaces.length; j < length; j++) { + if ((currentType = interfaces[j]) == anInterface) + return true; + + ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); + if (itsInterfaces != NoSuperInterfaces) { + if (++lastPosition == interfacesToVisit.length) + System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition); + interfacesToVisit[lastPosition] = itsInterfaces; + } + } + } + return false; +} +// Internal method... assume its only sent to classes NOT interfaces + +boolean implementsMethod(MethodBinding method) { + ReferenceBinding type = this; + while (type != null) { + MethodBinding[] methods = type.getMethods(method.selector); + for (int i = methods.length; --i >= 0;) + if (methods[i].areParametersEqual(method)) + return true; + type = type.superclass(); + } + return false; +} +/* Answer true if the receiver is an abstract type +*/ + +public final boolean isAbstract() { + return (modifiers & AccAbstract) != 0; +} +public final boolean isAnonymousType() { + return (tagBits & IsAnonymousType) != 0; +} +public final boolean isBinaryBinding() { + return (tagBits & IsBinaryBinding) != 0; +} +public final boolean isClass() { + return (modifiers & AccInterface) == 0; +} +/* Answer true if the receiver type can be assigned to the argument type (right) +*/ + +public boolean isCompatibleWith(TypeBinding right) { + if (right == this) + return true; + if (right.id == T_Object) + return true; + if (!(right instanceof ReferenceBinding)) + return false; + + ReferenceBinding referenceBinding = (ReferenceBinding) right; + if (referenceBinding.isInterface()) + return implementsInterface(referenceBinding, true); + if (isInterface()) // Explicit conversion from an interface to a class is not allowed + return false; + return referenceBinding.isSuperclassOf(this); +} +/* Answer true if the receiver has default visibility +*/ + +public final boolean isDefault() { + return (modifiers & (AccPublic | AccProtected | AccPrivate)) == 0; +} +/* Answer true if the receiver is a deprecated type +*/ + +public final boolean isDeprecated() { + return (modifiers & AccDeprecated) != 0; +} +/* Answer true if the receiver is final and cannot be subclassed +*/ + +public final boolean isFinal() { + return (modifiers & AccFinal) != 0; +} +public final boolean isInterface() { + return (modifiers & AccInterface) != 0; +} +public final boolean isLocalType() { + return (tagBits & IsLocalType) != 0; +} +public final boolean isMemberType() { + return (tagBits & IsMemberType) != 0; +} +public final boolean isNestedType() { + return (tagBits & IsNestedType) != 0; +} +/* Answer true if the receiver has private visibility +*/ + +public final boolean isPrivate() { + return (modifiers & AccPrivate) != 0; +} +/* Answer true if the receiver has private visibility and is used locally +*/ + +public final boolean isPrivateUsed() { + return (modifiers & AccPrivateUsed) != 0; +} +/* Answer true if the receiver has protected visibility +*/ + +public final boolean isProtected() { + return (modifiers & AccProtected) != 0; +} +/* Answer true if the receiver has public visibility +*/ + +public final boolean isPublic() { + return (modifiers & AccPublic) != 0; +} +/* Answer true if the receiver is a static member type (or toplevel) + */ + +public final boolean isStatic() { + return (modifiers & (AccStatic | AccInterface)) != 0 || + (tagBits & IsNestedType) == 0; +} +/* Answer true if all float operations must adher to IEEE 754 float/double rules +*/ + +//public final boolean isStrictfp() { +// return (modifiers & AccStrictfp) != 0; +//} +/* Answer true if the receiver is in the superclass hierarchy of aType +* +* NOTE: Object.isSuperclassOf(Object) -> false +*/ + +public boolean isSuperclassOf(ReferenceBinding type) { + do { + if (this == (type = type.superclass())) return true; + } while (type != null); + + return false; +} +/* Answer true if the receiver is deprecated (or any of its enclosing types) +*/ + +public final boolean isViewedAsDeprecated() { + return (modifiers & AccDeprecated) != 0 || + (modifiers & AccDeprecatedImplicitly) != 0; +} +public ReferenceBinding[] memberTypes() { + return NoMemberTypes; +} +public MethodBinding[] methods() { + return NoMethods; +} +/** +* Answer the source name for the type. +* In the case of member types, as the qualified name from its top level type. +* For example, for a member type N defined inside M & A: "A.M.N". +*/ + +public char[] qualifiedSourceName() { + if (isMemberType()) { + return CharOperation.concat(enclosingType().qualifiedSourceName(), sourceName(), '.'); + } else { + return sourceName(); + } +} +public char[] readableName() /*java.lang.Object*/ { + if (isMemberType()) + return CharOperation.concat(enclosingType().readableName(), sourceName, '.'); + else + return CharOperation.concatWith(compoundName, '.'); +} + +public char[] shortReadableName() /*Object*/ { + if (isMemberType()) + return CharOperation.concat(enclosingType().shortReadableName(), sourceName, '.'); + else + return sourceName; +} + +/* Answer the receiver's signature. +* +* NOTE: This method should only be used during/after code gen. +*/ + +public char[] signature() /* Ljava/lang/Object; */ { + if (signature != null) + return signature; + + return signature = CharOperation.concat('L', constantPoolName(), ';'); +} +public char[] sourceName() { + return sourceName; +} +public ReferenceBinding superclass() { + return null; +} +public ReferenceBinding[] superInterfaces() { + return NoSuperInterfaces; +} +public ReferenceBinding[] syntheticEnclosingInstanceTypes() { + if (isStatic()) return null; + + ReferenceBinding enclosingType = enclosingType(); + if (enclosingType == null) + return null; + else + return new ReferenceBinding[] {enclosingType}; +} +public SyntheticArgumentBinding[] syntheticOuterLocalVariables() { + return null; // is null if no enclosing instances are required +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/Scope.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/Scope.java new file mode 100644 index 0000000..7678e2a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/Scope.java @@ -0,0 +1,1415 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; +import net.sourceforge.phpdt.internal.compiler.util.ObjectVector; +import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; + +public abstract class Scope + implements + BaseTypes, + BindingIds, + CompilerModifiers, + ProblemReasons, + TagBits, + TypeConstants, + TypeIds { + + public Scope parent; + public int kind; + + public final static int BLOCK_SCOPE = 1; + public final static int METHOD_SCOPE = 2; + public final static int CLASS_SCOPE = 3; + public final static int COMPILATION_UNIT_SCOPE = 4; + protected Scope(int kind, Scope parent) { + this.kind = kind; + this.parent = parent; + } + + public abstract ProblemReporter problemReporter(); + + // Internal use only + protected final boolean areParametersAssignable(TypeBinding[] parameters, TypeBinding[] arguments) { + if (parameters == arguments) + return true; + + int length = parameters.length; + if (length != arguments.length) + return false; + + for (int i = 0; i < length; i++) + if (parameters[i] != arguments[i]) + if (!arguments[i].isCompatibleWith(parameters[i])) + return false; + return true; + } + + /* Answer an int describing the relationship between the given types. + * + * NotRelated + * EqualOrMoreSpecific : left is compatible with right + * MoreGeneric : right is compatible with left + */ + public static int compareTypes(TypeBinding left, TypeBinding right) { + if (left.isCompatibleWith(right)) + return EqualOrMoreSpecific; + if (right.isCompatibleWith(left)) + return MoreGeneric; + return NotRelated; + } + + /* Answer an int describing the relationship between the given type and unchecked exceptions. + * + * NotRelated + * EqualOrMoreSpecific : type is known for sure to be an unchecked exception type + * MoreGeneric : type is a supertype of an actual unchecked exception type + */ + public int compareUncheckedException(ReferenceBinding type) { + int comparison = compareTypes(type, getJavaLangRuntimeException()); + if (comparison != 0) return comparison; + return compareTypes(type, getJavaLangError()); + } + + public final CompilationUnitScope compilationUnitScope() { + Scope lastScope = null; + Scope scope = this; + do { + lastScope = scope; + scope = scope.parent; + } while (scope != null); + return (CompilationUnitScope) lastScope; + } + + public ArrayBinding createArray(TypeBinding type, int dimension) { + if (type.isValidBinding()) + return environment().createArrayType(type, dimension); + else + return new ArrayBinding(type, dimension); + } + + public final ClassScope enclosingClassScope() { + Scope scope = this; + while ((scope = scope.parent) != null) { + if (scope instanceof ClassScope) return (ClassScope)scope; + } + return null; // may answer null if no type around + } + + public final MethodScope enclosingMethodScope() { + Scope scope = this; + while ((scope = scope.parent) != null) { + if (scope instanceof MethodScope) return (MethodScope)scope; + } + return null; // may answer null if no method around + } + + /* Answer the receiver's enclosing source type. + */ + public final SourceTypeBinding enclosingSourceType() { + Scope scope = this; + do { + if (scope instanceof ClassScope) + return ((ClassScope) scope).referenceContext.binding; + scope = scope.parent; + } while (scope != null); + return null; + } + public final LookupEnvironment environment() { + Scope scope, unitScope = this; + while ((scope = unitScope.parent) != null) + unitScope = scope; + return ((CompilationUnitScope) unitScope).environment; + } + + // Internal use only + public ReferenceBinding findDirectMemberType(char[] typeName, ReferenceBinding enclosingType) { + if ((enclosingType.tagBits & HasNoMemberTypes) != 0) + return null; // know it has no member types (nor inherited member types) + + SourceTypeBinding enclosingSourceType = enclosingSourceType(); + compilationUnitScope().recordReference(enclosingType.compoundName, typeName); + ReferenceBinding memberType = enclosingType.getMemberType(typeName); + if (memberType != null) { + compilationUnitScope().recordTypeReference(memberType); // to record supertypes + if (enclosingSourceType == null + ? memberType.canBeSeenBy(getCurrentPackage()) + : memberType.canBeSeenBy(enclosingType, enclosingSourceType)) + return memberType; + else + return new ProblemReferenceBinding(typeName, memberType, NotVisible); + } + return null; + } + + // Internal use only + public MethodBinding findExactMethod( + ReferenceBinding receiverType, + char[] selector, + TypeBinding[] argumentTypes, + InvocationSite invocationSite) { + + compilationUnitScope().recordTypeReference(receiverType); + compilationUnitScope().recordTypeReferences(argumentTypes); + MethodBinding exactMethod = receiverType.getExactMethod(selector, argumentTypes); + if (exactMethod != null) { + compilationUnitScope().recordTypeReferences(exactMethod.thrownExceptions); + if (receiverType.isInterface() || exactMethod.canBeSeenBy(receiverType, invocationSite, this)) + return exactMethod; + } + return null; + } + + // Internal use only + /* Answer the field binding that corresponds to fieldName. + Start the lookup at the receiverType. + InvocationSite implements + isSuperAccess(); this is used to determine if the discovered field is visible. + Only fields defined by the receiverType or its supertypes are answered; + a field of an enclosing type will not be found using this API. + + If no visible field is discovered, null is answered. + */ + public FieldBinding findField(TypeBinding receiverType, char[] fieldName, InvocationSite invocationSite) { + if (receiverType.isBaseType()) return null; + if (receiverType.isArrayType()) { + TypeBinding leafType = receiverType.leafComponentType(); + if (leafType instanceof ReferenceBinding) { + if (!((ReferenceBinding) leafType).canBeSeenBy(this)) + return new ProblemFieldBinding((ReferenceBinding)leafType, fieldName, ReceiverTypeNotVisible); + } + if (CharOperation.equals(fieldName, LENGTH)) + return ArrayBinding.LengthField; + return null; + } + + compilationUnitScope().recordTypeReference(receiverType); + + ReferenceBinding currentType = (ReferenceBinding) receiverType; + if (!currentType.canBeSeenBy(this)) + return new ProblemFieldBinding(currentType, fieldName, ReceiverTypeNotVisible); + + FieldBinding field = currentType.getField(fieldName); + if (field != null) { + if (field.canBeSeenBy(currentType, invocationSite, this)) + return field; + else + return new ProblemFieldBinding(field.declaringClass, fieldName, NotVisible); + } + // collect all superinterfaces of receiverType until the field is found in a supertype + ReferenceBinding[][] interfacesToVisit = null; + int lastPosition = -1; + FieldBinding visibleField = null; + boolean keepLooking = true; + boolean notVisible = false; + // we could hold onto the not visible field for extra error reporting + while (keepLooking) { + ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); + if (itsInterfaces != NoSuperInterfaces) { + if (interfacesToVisit == null) + interfacesToVisit = new ReferenceBinding[5][]; + if (++lastPosition == interfacesToVisit.length) + System.arraycopy( + interfacesToVisit, + 0, + interfacesToVisit = new ReferenceBinding[lastPosition * 2][], + 0, + lastPosition); + interfacesToVisit[lastPosition] = itsInterfaces; + } + if ((currentType = currentType.superclass()) == null) + break; + + if ((field = currentType.getField(fieldName)) != null) { + keepLooking = false; + if (field.canBeSeenBy(receiverType, invocationSite, this)) { + if (visibleField == null) + visibleField = field; + else + return new ProblemFieldBinding(visibleField.declaringClass, fieldName, Ambiguous); + } else { + notVisible = true; + } + } + } + + // walk all visible interfaces to find ambiguous references + if (interfacesToVisit != null) { + ProblemFieldBinding ambiguous = null; + done : for (int i = 0; i <= lastPosition; i++) { + ReferenceBinding[] interfaces = interfacesToVisit[i]; + for (int j = 0, length = interfaces.length; j < length; j++) { + ReferenceBinding anInterface = interfaces[j]; + if ((anInterface.tagBits & InterfaceVisited) == 0) { + // if interface as not already been visited + anInterface.tagBits |= InterfaceVisited; + if ((field = anInterface.getField(fieldName)) != null) { + if (visibleField == null) { + visibleField = field; + } else { + ambiguous = new ProblemFieldBinding(visibleField.declaringClass, fieldName, Ambiguous); + break done; + } + } else { + ReferenceBinding[] itsInterfaces = anInterface.superInterfaces(); + if (itsInterfaces != NoSuperInterfaces) { + if (++lastPosition == interfacesToVisit.length) + System.arraycopy( + interfacesToVisit, + 0, + interfacesToVisit = new ReferenceBinding[lastPosition * 2][], + 0, + lastPosition); + interfacesToVisit[lastPosition] = itsInterfaces; + } + } + } + } + } + + // bit reinitialization + for (int i = 0; i <= lastPosition; i++) { + ReferenceBinding[] interfaces = interfacesToVisit[i]; + for (int j = 0, length = interfaces.length; j < length; j++) + interfaces[j].tagBits &= ~InterfaceVisited; + } + if (ambiguous != null) + return ambiguous; + } + + if (visibleField != null) + return visibleField; + if (notVisible) + return new ProblemFieldBinding(currentType, fieldName, NotVisible); + return null; + } + + // Internal use only + public ReferenceBinding findMemberType(char[] typeName, ReferenceBinding enclosingType) { + if ((enclosingType.tagBits & HasNoMemberTypes) != 0) + return null; // know it has no member types (nor inherited member types) + + SourceTypeBinding enclosingSourceType = enclosingSourceType(); + PackageBinding currentPackage = getCurrentPackage(); + compilationUnitScope().recordReference(enclosingType.compoundName, typeName); + ReferenceBinding memberType = enclosingType.getMemberType(typeName); + if (memberType != null) { + compilationUnitScope().recordTypeReference(memberType); // to record supertypes + if (enclosingSourceType == null + ? memberType.canBeSeenBy(currentPackage) + : memberType.canBeSeenBy(enclosingType, enclosingSourceType)) + return memberType; + else + return new ProblemReferenceBinding(typeName, memberType, NotVisible); + } + + // collect all superinterfaces of receiverType until the memberType is found in a supertype + ReferenceBinding currentType = enclosingType; + ReferenceBinding[][] interfacesToVisit = null; + int lastPosition = -1; + ReferenceBinding visibleMemberType = null; + boolean keepLooking = true; + ReferenceBinding notVisible = null; + // we could hold onto the not visible field for extra error reporting + while (keepLooking) { + ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); + if (itsInterfaces != NoSuperInterfaces) { + if (interfacesToVisit == null) + interfacesToVisit = new ReferenceBinding[5][]; + if (++lastPosition == interfacesToVisit.length) + System.arraycopy( + interfacesToVisit, + 0, + interfacesToVisit = new ReferenceBinding[lastPosition * 2][], + 0, + lastPosition); + interfacesToVisit[lastPosition] = itsInterfaces; + } + if ((currentType = currentType.superclass()) == null) + break; + + compilationUnitScope().recordReference(currentType.compoundName, typeName); + if ((memberType = currentType.getMemberType(typeName)) != null) { + compilationUnitScope().recordTypeReference(memberType); // to record supertypes + keepLooking = false; + if (enclosingSourceType == null + ? memberType.canBeSeenBy(currentPackage) + : memberType.canBeSeenBy(enclosingType, enclosingSourceType)) { + if (visibleMemberType == null) + visibleMemberType = memberType; + else + return new ProblemReferenceBinding(typeName, Ambiguous); + } else { + notVisible = memberType; + } + } + } + // walk all visible interfaces to find ambiguous references + if (interfacesToVisit != null) { + ProblemReferenceBinding ambiguous = null; + done : for (int i = 0; i <= lastPosition; i++) { + ReferenceBinding[] interfaces = interfacesToVisit[i]; + for (int j = 0, length = interfaces.length; j < length; j++) { + ReferenceBinding anInterface = interfaces[j]; + if ((anInterface.tagBits & InterfaceVisited) == 0) { + // if interface as not already been visited + anInterface.tagBits |= InterfaceVisited; + compilationUnitScope().recordReference(anInterface.compoundName, typeName); + if ((memberType = anInterface.getMemberType(typeName)) != null) { + compilationUnitScope().recordTypeReference(memberType); // to record supertypes + if (visibleMemberType == null) { + visibleMemberType = memberType; + } else { + ambiguous = new ProblemReferenceBinding(typeName, Ambiguous); + break done; + } + } else { + ReferenceBinding[] itsInterfaces = anInterface.superInterfaces(); + if (itsInterfaces != NoSuperInterfaces) { + if (++lastPosition == interfacesToVisit.length) + System.arraycopy( + interfacesToVisit, + 0, + interfacesToVisit = new ReferenceBinding[lastPosition * 2][], + 0, + lastPosition); + interfacesToVisit[lastPosition] = itsInterfaces; + } + } + } + } + } + + // bit reinitialization + for (int i = 0; i <= lastPosition; i++) { + ReferenceBinding[] interfaces = interfacesToVisit[i]; + for (int j = 0, length = interfaces.length; j < length; j++) + interfaces[j].tagBits &= ~InterfaceVisited; + } + if (ambiguous != null) + return ambiguous; + } + if (visibleMemberType != null) + return visibleMemberType; + if (notVisible != null) + return new ProblemReferenceBinding(typeName, notVisible, NotVisible); + return null; + } + + // Internal use only + public MethodBinding findMethod( + ReferenceBinding receiverType, + char[] selector, + TypeBinding[] argumentTypes, + InvocationSite invocationSite) { + + ReferenceBinding currentType = receiverType; + MethodBinding matchingMethod = null; + ObjectVector found = new ObjectVector(); + + compilationUnitScope().recordTypeReference(receiverType); + compilationUnitScope().recordTypeReferences(argumentTypes); + + if (currentType.isInterface()) { + MethodBinding[] currentMethods = currentType.getMethods(selector); + int currentLength = currentMethods.length; + if (currentLength == 1) { + matchingMethod = currentMethods[0]; + } else if (currentLength > 1) { + found.addAll(currentMethods); + } + matchingMethod = findMethodInSuperInterfaces(currentType, selector, found, matchingMethod); + currentType = getJavaLangObject(); + } + +// boolean isCompliant14 = compilationUnitScope().environment.options.complianceLevel >= CompilerOptions.JDK1_4; + // superclass lookup + ReferenceBinding classHierarchyStart = currentType; + while (currentType != null) { + MethodBinding[] currentMethods = currentType.getMethods(selector); + int currentLength = currentMethods.length; + + /* + * if 1.4 compliant, must filter out redundant protected methods from superclasses + */ +// if (isCompliant14){ +// nextMethod: for (int i = 0; i < currentLength; i++){ +// MethodBinding currentMethod = currentMethods[i]; +// // protected method need to be checked only - default access is already dealt with in #canBeSeen implementation +// // when checking that p.C -> q.B -> p.A cannot see default access members from A through B. +// if ((currentMethod.modifiers & AccProtected) == 0) continue nextMethod; +// if (matchingMethod != null){ +// if (currentMethod.areParametersEqual(matchingMethod)){ +// currentLength--; +// currentMethods[i] = null; // discard this match +// continue nextMethod; +// } +// } else { +// for (int j = 0, max = found.size; j < max; j++) { +// if (((MethodBinding)found.elementAt(j)).areParametersEqual(currentMethod)){ +// currentLength--; +// currentMethods[i] = null; +// continue nextMethod; +// } +// } +// } +// } +// } + + if (currentLength == 1 && matchingMethod == null && found.size == 0) { + matchingMethod = currentMethods[0]; + } else if (currentLength > 0) { + if (matchingMethod != null) { + found.add(matchingMethod); + matchingMethod = null; + } + // append currentMethods, filtering out null entries + int maxMethod = currentMethods.length; + if (maxMethod == currentLength) { // no method was eliminated for 1.4 compliance (see above) + found.addAll(currentMethods); + } else { + for (int i = 0, max = currentMethods.length; i < max; i++) { + MethodBinding currentMethod = currentMethods[i]; + if (currentMethod != null) found.add(currentMethod); + } + } + } + currentType = currentType.superclass(); + } + + int foundSize = found.size; + if (foundSize == 0) { + if (matchingMethod != null && areParametersAssignable(matchingMethod.parameters, argumentTypes)) { + // (if no default abstract) must explicitly look for one instead, which could be a better match + if (!matchingMethod.canBeSeenBy(receiverType, invocationSite, this)) { + // ignore matching method (to be consistent with multiple matches, none visible (matching method is then null) + MethodBinding interfaceMethod = findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, null, found); + if (interfaceMethod != null) return interfaceMethod; + } + return matchingMethod; + } + return findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, matchingMethod, found); + } + + MethodBinding[] candidates = new MethodBinding[foundSize]; + int candidatesCount = 0; + // argument type compatibility check + for (int i = 0; i < foundSize; i++) { + MethodBinding methodBinding = (MethodBinding) found.elementAt(i); + if (areParametersAssignable(methodBinding.parameters, argumentTypes)) + candidates[candidatesCount++] = methodBinding; + } + if (candidatesCount == 1) { + compilationUnitScope().recordTypeReferences(candidates[0].thrownExceptions); + return candidates[0]; // have not checked visibility + } + if (candidatesCount == 0) { // try to find a close match when the parameter order is wrong or missing some parameters + MethodBinding interfaceMethod = + findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, matchingMethod, found); + if (interfaceMethod != null) return interfaceMethod; + + int argLength = argumentTypes.length; + foundSize = found.size; + nextMethod : for (int i = 0; i < foundSize; i++) { + MethodBinding methodBinding = (MethodBinding) found.elementAt(i); + TypeBinding[] params = methodBinding.parameters; + int paramLength = params.length; + nextArg: for (int a = 0; a < argLength; a++) { + TypeBinding arg = argumentTypes[a]; + for (int p = 0; p < paramLength; p++) + if (params[p] == arg) + continue nextArg; + continue nextMethod; + } + return methodBinding; + } + return (MethodBinding) found.elementAt(0); // no good match so just use the first one found + } + + // visibility check + int visiblesCount = 0; + for (int i = 0; i < candidatesCount; i++) { + MethodBinding methodBinding = candidates[i]; + if (methodBinding.canBeSeenBy(receiverType, invocationSite, this)) { + if (visiblesCount != i) { + candidates[i] = null; + candidates[visiblesCount] = methodBinding; + } + visiblesCount++; + } + } + if (visiblesCount == 1) { + compilationUnitScope().recordTypeReferences(candidates[0].thrownExceptions); + return candidates[0]; + } + if (visiblesCount == 0) { + MethodBinding interfaceMethod = + findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, matchingMethod, found); + if (interfaceMethod != null) return interfaceMethod; + return new ProblemMethodBinding(candidates[0], candidates[0].selector, candidates[0].parameters, NotVisible); + } + if (candidates[0].declaringClass.isClass()) { + return mostSpecificClassMethodBinding(candidates, visiblesCount); + } else { + return mostSpecificInterfaceMethodBinding(candidates, visiblesCount); + } + } + + // abstract method lookup lookup (since maybe missing default abstract methods) + public MethodBinding findDefaultAbstractMethod( + ReferenceBinding receiverType, + char[] selector, + TypeBinding[] argumentTypes, + InvocationSite invocationSite, + ReferenceBinding classHierarchyStart, + MethodBinding matchingMethod, + ObjectVector found) { + + int startFoundSize = found.size; + ReferenceBinding currentType = classHierarchyStart; + while (currentType != null) { + matchingMethod = findMethodInSuperInterfaces(currentType, selector, found, matchingMethod); + currentType = currentType.superclass(); + } + int foundSize = found.size; + if (foundSize == startFoundSize) return matchingMethod; // maybe null + + MethodBinding[] candidates = new MethodBinding[foundSize - startFoundSize]; + int candidatesCount = 0; + // argument type compatibility check + for (int i = startFoundSize; i < foundSize; i++) { + MethodBinding methodBinding = (MethodBinding) found.elementAt(i); + if (areParametersAssignable(methodBinding.parameters, argumentTypes)) + candidates[candidatesCount++] = methodBinding; + } + if (candidatesCount == 1) { + compilationUnitScope().recordTypeReferences(candidates[0].thrownExceptions); + return candidates[0]; + } + if (candidatesCount == 0) { // try to find a close match when the parameter order is wrong or missing some parameters + int argLength = argumentTypes.length; + nextMethod : for (int i = 0; i < foundSize; i++) { + MethodBinding methodBinding = (MethodBinding) found.elementAt(i); + TypeBinding[] params = methodBinding.parameters; + int paramLength = params.length; + nextArg: for (int a = 0; a < argLength; a++) { + TypeBinding arg = argumentTypes[a]; + for (int p = 0; p < paramLength; p++) + if (params[p] == arg) + continue nextArg; + continue nextMethod; + } + return methodBinding; + } + return (MethodBinding) found.elementAt(0); // no good match so just use the first one found + } + // no need to check for visibility - interface methods are public + return mostSpecificInterfaceMethodBinding(candidates, candidatesCount); + } + + public MethodBinding findMethodInSuperInterfaces( + ReferenceBinding currentType, + char[] selector, + ObjectVector found, + MethodBinding matchingMethod) { + + ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); + if (itsInterfaces != NoSuperInterfaces) { + ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][]; + int lastPosition = -1; + if (++lastPosition == interfacesToVisit.length) + System.arraycopy( + interfacesToVisit, 0, + interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, + lastPosition); + interfacesToVisit[lastPosition] = itsInterfaces; + + for (int i = 0; i <= lastPosition; i++) { + ReferenceBinding[] interfaces = interfacesToVisit[i]; + for (int j = 0, length = interfaces.length; j < length; j++) { + currentType = interfaces[j]; + if ((currentType.tagBits & InterfaceVisited) == 0) { + // if interface as not already been visited + currentType.tagBits |= InterfaceVisited; + + MethodBinding[] currentMethods = currentType.getMethods(selector); + int currentLength = currentMethods.length; + if (currentLength == 1 && matchingMethod == null && found.size == 0) { + matchingMethod = currentMethods[0]; + } else if (currentLength > 0) { + if (matchingMethod != null) { + found.add(matchingMethod); + matchingMethod = null; + } + found.addAll(currentMethods); + } + itsInterfaces = currentType.superInterfaces(); + if (itsInterfaces != NoSuperInterfaces) { + if (++lastPosition == interfacesToVisit.length) + System.arraycopy( + interfacesToVisit, 0, + interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, + lastPosition); + interfacesToVisit[lastPosition] = itsInterfaces; + } + } + } + } + + // bit reinitialization + for (int i = 0; i <= lastPosition; i++) { + ReferenceBinding[] interfaces = interfacesToVisit[i]; + for (int j = 0, length = interfaces.length; j < length; j++) + interfaces[j].tagBits &= ~InterfaceVisited; + } + } + return matchingMethod; + } + + // Internal use only + public MethodBinding findMethodForArray( + ArrayBinding receiverType, + char[] selector, + TypeBinding[] argumentTypes, + InvocationSite invocationSite) { + + TypeBinding leafType = receiverType.leafComponentType(); + if (leafType instanceof ReferenceBinding) { + if (!((ReferenceBinding) leafType).canBeSeenBy(this)) + return new ProblemMethodBinding(selector, MethodBinding.NoParameters, (ReferenceBinding)leafType, ReceiverTypeNotVisible); + } + + ReferenceBinding object = getJavaLangObject(); + MethodBinding methodBinding = object.getExactMethod(selector, argumentTypes); + if (methodBinding != null) { + // handle the method clone() specially... cannot be protected or throw exceptions + if (argumentTypes == NoParameters && CharOperation.equals(selector, CLONE)) + return new MethodBinding( + (methodBinding.modifiers ^ AccProtected) | AccPublic, + CLONE, + methodBinding.returnType, + argumentTypes, + null, + object); + if (methodBinding.canBeSeenBy(receiverType, invocationSite, this)) + return methodBinding; + } + // answers closest approximation, may not check argumentTypes or visibility + methodBinding = findMethod(object, selector, argumentTypes, invocationSite); + if (methodBinding == null) + return new ProblemMethodBinding(selector, argumentTypes, NotFound); + if (methodBinding.isValidBinding()) { + if (!areParametersAssignable(methodBinding.parameters, argumentTypes)) + return new ProblemMethodBinding( + methodBinding, + selector, + argumentTypes, + NotFound); + if (!methodBinding.canBeSeenBy(receiverType, invocationSite, this)) + return new ProblemMethodBinding( + methodBinding, + selector, + methodBinding.parameters, + NotVisible); + } + return methodBinding; + } + + // Internal use only + public ReferenceBinding findType( + char[] typeName, + PackageBinding declarationPackage, + PackageBinding invocationPackage) { + + compilationUnitScope().recordReference(declarationPackage.compoundName, typeName); + ReferenceBinding typeBinding = declarationPackage.getType(typeName); + if (typeBinding == null) + return null; + + if (typeBinding.isValidBinding()) { + if (declarationPackage != invocationPackage && !typeBinding.canBeSeenBy(invocationPackage)) + return new ProblemReferenceBinding(typeName, typeBinding, NotVisible); + } + return typeBinding; + } + + public TypeBinding getBaseType(char[] name) { + // list should be optimized (with most often used first) + int length = name.length; + if (length > 2 && length < 8) { + switch (name[0]) { + case 'i' : + if (length == 3 && name[1] == 'n' && name[2] == 't') + return IntBinding; + break; + case 'v' : + if (length == 4 && name[1] == 'o' && name[2] == 'i' && name[3] == 'd') + return VoidBinding; + break; + case 'b' : + if (length == 7 + && name[1] == 'o' + && name[2] == 'o' + && name[3] == 'l' + && name[4] == 'e' + && name[5] == 'a' + && name[6] == 'n') + return BooleanBinding; + if (length == 4 && name[1] == 'y' && name[2] == 't' && name[3] == 'e') + return ByteBinding; + break; + case 'c' : + if (length == 4 && name[1] == 'h' && name[2] == 'a' && name[3] == 'r') + return CharBinding; + break; + case 'd' : + if (length == 6 + && name[1] == 'o' + && name[2] == 'u' + && name[3] == 'b' + && name[4] == 'l' + && name[5] == 'e') + return DoubleBinding; + break; + case 'f' : + if (length == 5 + && name[1] == 'l' + && name[2] == 'o' + && name[3] == 'a' + && name[4] == 't') + return FloatBinding; + break; + case 'l' : + if (length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g') + return LongBinding; + break; + case 's' : + if (length == 5 + && name[1] == 'h' + && name[2] == 'o' + && name[3] == 'r' + && name[4] == 't') + return ShortBinding; + } + } + return null; + } + + public final PackageBinding getCurrentPackage() { + Scope scope, unitScope = this; + while ((scope = unitScope.parent) != null) + unitScope = scope; + return ((CompilationUnitScope) unitScope).fPackage; + } + + public final ReferenceBinding getJavaIoSerializable() { + compilationUnitScope().recordQualifiedReference(JAVA_IO_SERIALIZABLE); + ReferenceBinding type = environment().getType(JAVA_IO_SERIALIZABLE); + if (type != null) return type; + + problemReporter().isClassPathCorrect(JAVA_IO_SERIALIZABLE, referenceCompilationUnit()); + return null; // will not get here since the above error aborts the compilation + } + + public final ReferenceBinding getJavaLangClass() { + compilationUnitScope().recordQualifiedReference(JAVA_LANG_CLASS); + ReferenceBinding type = environment().getType(JAVA_LANG_CLASS); + if (type != null) return type; + + problemReporter().isClassPathCorrect(JAVA_LANG_CLASS, referenceCompilationUnit()); + return null; // will not get here since the above error aborts the compilation + } + + public final ReferenceBinding getJavaLangCloneable() { + compilationUnitScope().recordQualifiedReference(JAVA_LANG_CLONEABLE); + ReferenceBinding type = environment().getType(JAVA_LANG_CLONEABLE); + if (type != null) return type; + + problemReporter().isClassPathCorrect(JAVA_LANG_CLONEABLE, referenceCompilationUnit()); + return null; // will not get here since the above error aborts the compilation + } + + public final ReferenceBinding getJavaLangError() { + compilationUnitScope().recordQualifiedReference(JAVA_LANG_ERROR); + ReferenceBinding type = environment().getType(JAVA_LANG_ERROR); + if (type != null) return type; + + problemReporter().isClassPathCorrect(JAVA_LANG_ERROR, referenceCompilationUnit()); + return null; // will not get here since the above error aborts the compilation + } + + public final ReferenceBinding getJavaLangAssertionError() { + compilationUnitScope().recordQualifiedReference(JAVA_LANG_ASSERTIONERROR); + ReferenceBinding type = environment().getType(JAVA_LANG_ASSERTIONERROR); + if (type != null) return type; + problemReporter().isClassPathCorrect(JAVA_LANG_ASSERTIONERROR, referenceCompilationUnit()); + return null; // will not get here since the above error aborts the compilation + } + + public final ReferenceBinding getJavaLangObject() { + compilationUnitScope().recordQualifiedReference(JAVA_LANG_OBJECT); + ReferenceBinding type = environment().getType(JAVA_LANG_OBJECT); + if (type != null) return type; + + problemReporter().isClassPathCorrect(JAVA_LANG_OBJECT, referenceCompilationUnit()); + return null; // will not get here since the above error aborts the compilation + } + + public final ReferenceBinding getJavaLangRuntimeException() { + compilationUnitScope().recordQualifiedReference(JAVA_LANG_RUNTIMEEXCEPTION); + ReferenceBinding type = environment().getType(JAVA_LANG_RUNTIMEEXCEPTION); + if (type != null) return type; + + problemReporter().isClassPathCorrect(JAVA_LANG_RUNTIMEEXCEPTION, referenceCompilationUnit()); + return null; // will not get here since the above error aborts the compilation + } + + public final ReferenceBinding getJavaLangString() { + compilationUnitScope().recordQualifiedReference(JAVA_LANG_STRING); + ReferenceBinding type = environment().getType(JAVA_LANG_STRING); + if (type != null) return type; + + problemReporter().isClassPathCorrect(JAVA_LANG_STRING, referenceCompilationUnit()); + return null; // will not get here since the above error aborts the compilation + } + + public final ReferenceBinding getJavaLangThrowable() { + compilationUnitScope().recordQualifiedReference(JAVA_LANG_THROWABLE); + ReferenceBinding type = environment().getType(JAVA_LANG_THROWABLE); + if (type != null) return type; + + problemReporter().isClassPathCorrect(JAVA_LANG_THROWABLE, referenceCompilationUnit()); + return null; // will not get here since the above error aborts the compilation + } + + /* Answer the type binding corresponding to the typeName argument, relative to the enclosingType. + */ + public final ReferenceBinding getMemberType(char[] typeName, ReferenceBinding enclosingType) { + ReferenceBinding memberType = findMemberType(typeName, enclosingType); + if (memberType != null) return memberType; + return new ProblemReferenceBinding(typeName, NotFound); + } + + /* Answer the type binding corresponding to the compoundName. + * + * NOTE: If a problem binding is returned, senders should extract the compound name + * from the binding & not assume the problem applies to the entire compoundName. + */ + public final TypeBinding getType(char[][] compoundName) { + int typeNameLength = compoundName.length; + if (typeNameLength == 1) { + // Would like to remove this test and require senders to specially handle base types + TypeBinding binding = getBaseType(compoundName[0]); + if (binding != null) return binding; + } + + compilationUnitScope().recordQualifiedReference(compoundName); + Binding binding = + getTypeOrPackage(compoundName[0], typeNameLength == 1 ? TYPE : TYPE | PACKAGE); + if (binding == null) + return new ProblemReferenceBinding(compoundName[0], NotFound); + if (!binding.isValidBinding()) + return (ReferenceBinding) binding; + + int currentIndex = 1; + boolean checkVisibility = false; + if (binding instanceof PackageBinding) { + PackageBinding packageBinding = (PackageBinding) binding; + while (currentIndex < typeNameLength) { + binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]); // does not check visibility + if (binding == null) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + NotFound); + if (!binding.isValidBinding()) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + binding.problemId()); + if (!(binding instanceof PackageBinding)) + break; + packageBinding = (PackageBinding) binding; + } + if (binding instanceof PackageBinding) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + NotFound); + checkVisibility = true; + } + + // binding is now a ReferenceBinding + ReferenceBinding typeBinding = (ReferenceBinding) binding; + compilationUnitScope().recordTypeReference(typeBinding); // to record supertypes + if (checkVisibility) // handles the fall through case + if (!typeBinding.canBeSeenBy(this)) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + typeBinding, + NotVisible); + + while (currentIndex < typeNameLength) { + typeBinding = getMemberType(compoundName[currentIndex++], typeBinding); + if (!typeBinding.isValidBinding()) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + typeBinding.problemId()); + } + return typeBinding; + } + + /* Answer the type binding that corresponds the given name, starting the lookup in the receiver. + * The name provided is a simple source name (e.g., "Object" , "Point", ...) + */ + // The return type of this method could be ReferenceBinding if we did not answer base types. + // NOTE: We could support looking for Base Types last in the search, however any code using + // this feature would be extraordinarily slow. Therefore we don't do this + public final TypeBinding getType(char[] name) { + // Would like to remove this test and require senders to specially handle base types + TypeBinding binding = getBaseType(name); + if (binding != null) return binding; + return (ReferenceBinding) getTypeOrPackage(name, TYPE); + } + + // Added for code assist... NOT Public API + public final Binding getTypeOrPackage(char[][] compoundName) { + int nameLength = compoundName.length; + if (nameLength == 1) { + TypeBinding binding = getBaseType(compoundName[0]); + if (binding != null) return binding; + } + Binding binding = getTypeOrPackage(compoundName[0], TYPE | PACKAGE); + if (!binding.isValidBinding()) return binding; + + int currentIndex = 1; + boolean checkVisibility = false; + if (binding instanceof PackageBinding) { + PackageBinding packageBinding = (PackageBinding) binding; + + while (currentIndex < nameLength) { + binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]); + if (binding == null) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + NotFound); + if (!binding.isValidBinding()) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + binding.problemId()); + if (!(binding instanceof PackageBinding)) + break; + packageBinding = (PackageBinding) binding; + } + if (binding instanceof PackageBinding) return binding; + checkVisibility = true; + } + // binding is now a ReferenceBinding + ReferenceBinding typeBinding = (ReferenceBinding) binding; + if (checkVisibility) // handles the fall through case + if (!typeBinding.canBeSeenBy(this)) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + typeBinding, + NotVisible); + + while (currentIndex < nameLength) { + typeBinding = getMemberType(compoundName[currentIndex++], typeBinding); + // checks visibility + if (!typeBinding.isValidBinding()) + return new ProblemReferenceBinding( + CharOperation.subarray(compoundName, 0, currentIndex), + typeBinding.problemId()); + } + return typeBinding; + } + + /* Internal use only + */ + final Binding getTypeOrPackage(char[] name, int mask) { + Scope scope = this; + ReferenceBinding foundType = null; + if ((mask & TYPE) == 0) { + Scope next = scope; + while ((next = scope.parent) != null) + scope = next; + } else { + done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found + switch (scope.kind) { + case METHOD_SCOPE : + case BLOCK_SCOPE : + ReferenceBinding localType = ((BlockScope) scope).findLocalType(name); // looks in this scope only + if (localType != null) { + if (foundType != null && foundType != localType) + return new ProblemReferenceBinding(name, InheritedNameHidesEnclosingName); + return localType; + } + break; + case CLASS_SCOPE : + SourceTypeBinding sourceType = ((ClassScope) scope).referenceContext.binding; + // 6.5.5.1 - simple name favors member type over top-level type in same unit + ReferenceBinding memberType = findMemberType(name, sourceType); + if (memberType != null) { // skip it if we did not find anything + if (memberType.problemId() == Ambiguous) { + if (foundType == null || foundType.problemId() == NotVisible) + // supercedes any potential InheritedNameHidesEnclosingName problem + return memberType; + else + // make the user qualify the type, likely wants the first inherited type + return new ProblemReferenceBinding(name, InheritedNameHidesEnclosingName); + } +// if (memberType.isValidBinding()) { +// if (sourceType == memberType.enclosingType() +// || environment().options.complianceLevel >= CompilerOptions.JDK1_4) { +// // found a valid type in the 'immediate' scope (ie. not inherited) +// // OR in 1.4 mode (inherited shadows enclosing) +// if (foundType == null) +// return memberType; +// if (foundType.isValidBinding()) +// // if a valid type was found, complain when another is found in an 'immediate' enclosing type (ie. not inherited) +// if (foundType != memberType) +// return new ProblemReferenceBinding(name, InheritedNameHidesEnclosingName); +// } +// } + if (foundType == null || (foundType.problemId() == NotVisible && memberType.problemId() != NotVisible)) + // only remember the memberType if its the first one found or the previous one was not visible & memberType is... + foundType = memberType; + } + if (CharOperation.equals(sourceType.sourceName, name)) { + if (foundType != null && foundType != sourceType && foundType.problemId() != NotVisible) + return new ProblemReferenceBinding(name, InheritedNameHidesEnclosingName); + return sourceType; + } + break; + case COMPILATION_UNIT_SCOPE : + break done; + } + scope = scope.parent; + } + if (foundType != null && foundType.problemId() != NotVisible) + return foundType; + } + + // at this point the scope is a compilation unit scope + CompilationUnitScope unitScope = (CompilationUnitScope) scope; + PackageBinding currentPackage = unitScope.fPackage; + // ask for the imports + name + if ((mask & TYPE) != 0) { + // check single type imports. + ImportBinding[] imports = unitScope.imports; + if (imports != null) { + // copy the list, since single type imports are removed if they cannot be resolved + for (int i = 0, length = imports.length; i < length; i++) { + ImportBinding typeImport = imports[i]; + if (!typeImport.onDemand) { + if (CharOperation.equals(typeImport.compoundName[typeImport.compoundName.length - 1], name)) { + if (unitScope.resolveSingleTypeImport(typeImport) != null) { + ImportReference importReference = typeImport.reference; + if (importReference != null) importReference.used = true; + return typeImport.resolvedImport; // already know its visible + } + } + } + } + } + // check if the name is in the current package, skip it if its a sub-package + unitScope.recordReference(currentPackage.compoundName, name); + Binding binding = currentPackage.getTypeOrPackage(name); + if (binding instanceof ReferenceBinding) return binding; // type is always visible to its own package + + // check on demand imports + boolean foundInImport = false; + ReferenceBinding type = null; + if (imports != null) { + for (int i = 0, length = imports.length; i < length; i++) { + ImportBinding someImport = imports[i]; + if (someImport.onDemand) { + Binding resolvedImport = someImport.resolvedImport; + ReferenceBinding temp = resolvedImport instanceof PackageBinding + ? findType(name, (PackageBinding) resolvedImport, currentPackage) + : findDirectMemberType(name, (ReferenceBinding) resolvedImport); + if (temp != null && temp.isValidBinding()) { +// ImportReference importReference = someImport.reference; +// if (importReference != null) importReference.used = true; + if (foundInImport) + // Answer error binding -- import on demand conflict; name found in two import on demand packages. + return new ProblemReferenceBinding(name, Ambiguous); + type = temp; + foundInImport = true; + } + } + } + } + if (type != null) return type; + } + + unitScope.recordSimpleReference(name); + if ((mask & PACKAGE) != 0) { + PackageBinding packageBinding = unitScope.environment.getTopLevelPackage(name); + if (packageBinding != null) return packageBinding; + } + + // Answer error binding -- could not find name + if (foundType != null) return foundType; // problem type from above + return new ProblemReferenceBinding(name, NotFound); + } + + /* Answer whether the type is defined in the same compilation unit as the receiver + */ + public final boolean isDefinedInSameUnit(ReferenceBinding type) { + // find the outer most enclosing type + ReferenceBinding enclosingType = type; + while ((type = enclosingType.enclosingType()) != null) + enclosingType = type; + + // find the compilation unit scope + Scope scope, unitScope = this; + while ((scope = unitScope.parent) != null) + unitScope = scope; + + // test that the enclosingType is not part of the compilation unit + SourceTypeBinding[] topLevelTypes = + ((CompilationUnitScope) unitScope).topLevelTypes; + for (int i = topLevelTypes.length; --i >= 0;) + if (topLevelTypes[i] == enclosingType) + return true; + return false; + } + + /* Answer true if the scope is nested inside a given field declaration. + * Note: it works as long as the scope.fieldDeclarationIndex is reflecting the field being traversed + * e.g. during name resolution. + */ + public final boolean isDefinedInField(FieldBinding field) { + Scope scope = this; + do { + if (scope instanceof MethodScope) { + MethodScope methodScope = (MethodScope) scope; + ReferenceContext refContext = methodScope.referenceContext; + if (refContext instanceof TypeDeclaration + && ((TypeDeclaration)refContext).binding == field.declaringClass + && methodScope.fieldDeclarationIndex == field.id) { + return true; + } + } + scope = scope.parent; + } while (scope != null); + return false; + } + + /* Answer true if the scope is nested inside a given method declaration + */ + public final boolean isDefinedInMethod(MethodBinding method) { + Scope scope = this; + do { + if (scope instanceof MethodScope) { + ReferenceContext refContext = ((MethodScope) scope).referenceContext; + if (refContext instanceof AbstractMethodDeclaration + && ((AbstractMethodDeclaration)refContext).binding == method) { + return true; + } + } + scope = scope.parent; + } while (scope != null); + return false; + } + + /* Answer true if the scope is nested inside a given type declaration + */ + public final boolean isDefinedInType(ReferenceBinding type) { + Scope scope = this; + do { + if (scope instanceof ClassScope) + if (((ClassScope) scope).referenceContext.binding == type){ + return true; + } + scope = scope.parent; + } while (scope != null); + return false; + } + + public boolean isInsideDeprecatedCode(){ + switch(kind){ + case Scope.BLOCK_SCOPE : + case Scope.METHOD_SCOPE : + MethodScope methodScope = methodScope(); + if (!methodScope.isInsideInitializer()){ + // check method modifiers to see if deprecated + MethodBinding context = ((AbstractMethodDeclaration)methodScope.referenceContext).binding; + if (context != null && context.isViewedAsDeprecated()) { + return true; + } + } else { + SourceTypeBinding type = ((BlockScope)this).referenceType().binding; + + // inside field declaration ? check field modifier to see if deprecated + if (methodScope.fieldDeclarationIndex != MethodScope.NotInFieldDecl) { + for (int i = 0; i < type.fields.length; i++){ + if (type.fields[i].id == methodScope.fieldDeclarationIndex) { + // currently inside this field initialization + if (type.fields[i].isViewedAsDeprecated()){ + return true; + } + break; + } + } + } + if (type != null && type.isViewedAsDeprecated()) { + return true; + } + } + break; + case Scope.CLASS_SCOPE : + ReferenceBinding context = ((ClassScope)this).referenceType().binding; + if (context != null && context.isViewedAsDeprecated()) { + return true; + } + break; + } + return false; + } + + public final boolean isJavaIoSerializable(TypeBinding tb) { + return tb == getJavaIoSerializable(); + } + + public final boolean isJavaLangCloneable(TypeBinding tb) { + return tb == getJavaLangCloneable(); + } + + public final boolean isJavaLangObject(TypeBinding type) { + return type.id == T_JavaLangObject; + } + + public final MethodScope methodScope() { + Scope scope = this; + do { + if (scope instanceof MethodScope) + return (MethodScope) scope; + scope = scope.parent; + } while (scope != null); + return null; + } + + // Internal use only + /* All methods in visible are acceptable matches for the method in question... + * The methods defined by the receiver type appear before those defined by its + * superclass and so on. We want to find the one which matches best. + * + * Since the receiver type is a class, we know each method's declaring class is + * either the receiver type or one of its superclasses. It is an error if the best match + * is defined by a superclass, when a lesser match is defined by the receiver type + * or a closer superclass. + */ + protected final MethodBinding mostSpecificClassMethodBinding(MethodBinding[] visible, int visibleSize) { + + MethodBinding method = null; + MethodBinding previous = null; + + nextVisible : for (int i = 0; i < visibleSize; i++) { + method = visible[i]; + + if (previous != null && method.declaringClass != previous.declaringClass) + break; // cannot answer a method farther up the hierarchy than the first method found + previous = method; + for (int j = 0; j < visibleSize; j++) { + if (i == j) continue; + MethodBinding next = visible[j]; + if (!areParametersAssignable(next.parameters, method.parameters)) + continue nextVisible; + } + compilationUnitScope().recordTypeReferences(method.thrownExceptions); + return method; + } + return new ProblemMethodBinding(visible[0].selector, visible[0].parameters, Ambiguous); + } + + // Internal use only + /* All methods in visible are acceptable matches for the method in question... + * Since the receiver type is an interface, we ignore the possibility that 2 inherited + * but unrelated superinterfaces may define the same method in acceptable but + * not identical ways... we just take the best match that we find since any class which + * implements the receiver interface MUST implement all signatures for the method... + * in which case the best match is correct. + * + * NOTE: This is different than javac... in the following example, the message send of + * bar(X) in class Y is supposed to be ambiguous. But any class which implements the + * interface I MUST implement both signatures for bar. If this class was the receiver of + * the message send instead of the interface I, then no problem would be reported. + * + interface I1 { + void bar(J j); + } + interface I2 { + // void bar(J j); + void bar(Object o); + } + interface I extends I1, I2 {} + interface J {} + + class X implements J {} + + class Y extends X { + public void foo(I i, X x) { i.bar(x); } + } + */ + protected final MethodBinding mostSpecificInterfaceMethodBinding(MethodBinding[] visible, int visibleSize) { + MethodBinding method = null; + nextVisible : for (int i = 0; i < visibleSize; i++) { + method = visible[i]; + for (int j = 0; j < visibleSize; j++) { + if (i == j) continue; + MethodBinding next = visible[j]; + if (!areParametersAssignable(next.parameters, method.parameters)) + continue nextVisible; + } + compilationUnitScope().recordTypeReferences(method.thrownExceptions); + return method; + } + return new ProblemMethodBinding(visible[0].selector, visible[0].parameters, Ambiguous); + } + + public final ClassScope outerMostClassScope() { + ClassScope lastClassScope = null; + Scope scope = this; + do { + if (scope instanceof ClassScope) + lastClassScope = (ClassScope) scope; + scope = scope.parent; + } while (scope != null); + return lastClassScope; // may answer null if no class around + } + + public final MethodScope outerMostMethodScope() { + MethodScope lastMethodScope = null; + Scope scope = this; + do { + if (scope instanceof MethodScope) + lastMethodScope = (MethodScope) scope; + scope = scope.parent; + } while (scope != null); + return lastMethodScope; // may answer null if no method around + } + + public final CompilationUnitDeclaration referenceCompilationUnit() { + Scope scope, unitScope = this; + while ((scope = unitScope.parent) != null) + unitScope = scope; + return ((CompilationUnitScope) unitScope).referenceContext; + } + // start position in this scope - for ordering scopes vs. variables + int startIndex() { + return 0; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SourceTypeBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SourceTypeBinding.java new file mode 100644 index 0000000..13e8646 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SourceTypeBinding.java @@ -0,0 +1,1064 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import java.util.Enumeration; +import java.util.Hashtable; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; +import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.Argument; +import net.sourceforge.phpeclipse.internal.compiler.ast.AssertStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeReference; + + +public class SourceTypeBinding extends ReferenceBinding { + public ReferenceBinding superclass; + public ReferenceBinding[] superInterfaces; + public FieldBinding[] fields; + public MethodBinding[] methods; + public ReferenceBinding[] memberTypes; + + public ClassScope scope; + + // Synthetics are separated into 4 categories: methods, super methods, fields, class literals and changed declaring class bindings + public final static int METHOD = 0; + public final static int FIELD = 1; + public final static int CLASS_LITERAL = 2; + public final static int CHANGED_DECLARING_CLASS = 3; + + Hashtable[] synthetics; + +protected SourceTypeBinding() { +} +public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage, ClassScope scope) { + this.compoundName = compoundName; + this.fPackage = fPackage; + this.fileName = scope.referenceCompilationUnit().getFileName(); + this.modifiers = scope.referenceContext.modifiers; + this.sourceName = scope.referenceContext.name; + this.scope = scope; + + computeId(); +} +private void addDefaultAbstractMethod(MethodBinding abstractMethod) { + MethodBinding defaultAbstract = new MethodBinding( + abstractMethod.modifiers | AccDefaultAbstract, + abstractMethod.selector, + abstractMethod.returnType, + abstractMethod.parameters, + abstractMethod.thrownExceptions, + this); + + MethodBinding[] temp = new MethodBinding[methods.length + 1]; + System.arraycopy(methods, 0, temp, 0, methods.length); + temp[methods.length] = defaultAbstract; + methods = temp; +} +public void addDefaultAbstractMethods() { + if ((tagBits & KnowsDefaultAbstractMethods) != 0) return; + + tagBits |= KnowsDefaultAbstractMethods; + + if (isClass() && isAbstract()) { +// if (fPackage.environment.options.targetJDK >= CompilerOptions.JDK1_2) return; // no longer added for post 1.2 targets + + ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][]; + int lastPosition = 0; + interfacesToVisit[lastPosition] = superInterfaces(); + + for (int i = 0; i <= lastPosition; i++) { + ReferenceBinding[] interfaces = interfacesToVisit[i]; + for (int j = 0, length = interfaces.length; j < length; j++) { + ReferenceBinding superType = interfaces[j]; + if (superType.isValidBinding()) { + MethodBinding[] methods = superType.methods(); + for (int m = methods.length; --m >= 0;) { + MethodBinding method = methods[m]; + if (!implementsMethod(method)) + addDefaultAbstractMethod(method); + } + + ReferenceBinding[] itsInterfaces = superType.superInterfaces(); + if (itsInterfaces != NoSuperInterfaces) { + if (++lastPosition == interfacesToVisit.length) + System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition); + interfacesToVisit[lastPosition] = itsInterfaces; + } + } + } + } + } +} +/* Add a new synthetic field for . +* Answer the new field or the existing field if one already existed. +*/ + +public FieldBinding addSyntheticField(LocalVariableBinding actualOuterLocalVariable) { + if (synthetics == null) { + synthetics = new Hashtable[4]; + } + if (synthetics[FIELD] == null) { + synthetics[FIELD] = new Hashtable(5); + } + + FieldBinding synthField = (FieldBinding) synthetics[FIELD].get(actualOuterLocalVariable); + if (synthField == null) { + synthField = new SyntheticFieldBinding( + CharOperation.concat(SyntheticArgumentBinding.OuterLocalPrefix, actualOuterLocalVariable.name), + actualOuterLocalVariable.type, + AccPrivate | AccFinal ,//| AccSynthetic, + this, + Constant.NotAConstant, + synthetics[FIELD].size()); + synthetics[FIELD].put(actualOuterLocalVariable, synthField); + } + + // ensure there is not already such a field defined by the user + boolean needRecheck; + int index = 1; + do { + needRecheck = false; + FieldBinding existingField; + if ((existingField = this.getField(synthField.name)) != null) { + TypeDeclaration typeDecl = scope.referenceContext; + for (int i = 0, max = typeDecl.fields.length; i < max; i++) { + FieldDeclaration fieldDecl = typeDecl.fields[i]; + if (fieldDecl.binding == existingField) { + synthField.name = CharOperation.concat( + SyntheticArgumentBinding.OuterLocalPrefix, + actualOuterLocalVariable.name, + ("$" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$ + needRecheck = true; + break; + } + } + } + } while (needRecheck); + return synthField; +} +/* Add a new synthetic field for . +* Answer the new field or the existing field if one already existed. +*/ + +public FieldBinding addSyntheticField(ReferenceBinding enclosingType) { + + if (synthetics == null) { + synthetics = new Hashtable[4]; + } + if (synthetics[FIELD] == null) { + synthetics[FIELD] = new Hashtable(5); + } + + FieldBinding synthField = (FieldBinding) synthetics[FIELD].get(enclosingType); + if (synthField == null) { + synthField = new SyntheticFieldBinding( + CharOperation.concat( + SyntheticArgumentBinding.EnclosingInstancePrefix, + String.valueOf(enclosingType.depth()).toCharArray()), + enclosingType, + AccDefault | AccFinal,// | AccSynthetic, + this, + Constant.NotAConstant, + synthetics[FIELD].size()); + synthetics[FIELD].put(enclosingType, synthField); + } + // ensure there is not already such a field defined by the user + FieldBinding existingField; + if ((existingField = this.getField(synthField.name)) != null) { + TypeDeclaration typeDecl = scope.referenceContext; + for (int i = 0, max = typeDecl.fields.length; i < max; i++) { + FieldDeclaration fieldDecl = typeDecl.fields[i]; + if (fieldDecl.binding == existingField) { + scope.problemReporter().duplicateFieldInType(this, fieldDecl); + break; + } + } + } + return synthField; +} +/* Add a new synthetic field for a class literal access. +* Answer the new field or the existing field if one already existed. +*/ + +public FieldBinding addSyntheticField(TypeBinding targetType, BlockScope blockScope) { + + if (synthetics == null) { + synthetics = new Hashtable[4]; + } + if (synthetics[CLASS_LITERAL] == null) { + synthetics[CLASS_LITERAL] = new Hashtable(5); + } + + // use a different table than FIELDS, given there might be a collision between emulation of X.this$0 and X.class. + FieldBinding synthField = (FieldBinding) synthetics[CLASS_LITERAL].get(targetType); + if (synthField == null) { + synthField = new SyntheticFieldBinding( + ("class$" + synthetics[CLASS_LITERAL].size()).toCharArray(), //$NON-NLS-1$ + blockScope.getJavaLangClass(), + AccDefault | AccStatic,// | AccSynthetic, + this, + Constant.NotAConstant, + synthetics[CLASS_LITERAL].size()); + synthetics[CLASS_LITERAL].put(targetType, synthField); + } + // ensure there is not already such a field defined by the user + FieldBinding existingField; + if ((existingField = this.getField(synthField.name)) != null) { + TypeDeclaration typeDecl = blockScope.referenceType(); + for (int i = 0, max = typeDecl.fields.length; i < max; i++) { + FieldDeclaration fieldDecl = typeDecl.fields[i]; + if (fieldDecl.binding == existingField) { + blockScope.problemReporter().duplicateFieldInType(this, fieldDecl); + break; + } + } + } + return synthField; +} + +/* Add a new synthetic field for the emulation of the assert statement. +* Answer the new field or the existing field if one already existed. +*/ +public FieldBinding addSyntheticField(AssertStatement assertStatement, BlockScope blockScope) { + + if (synthetics == null) { + synthetics = new Hashtable[4]; + } + if (synthetics[FIELD] == null) { + synthetics[FIELD] = new Hashtable(5); + } + + FieldBinding synthField = (FieldBinding) synthetics[FIELD].get("assertionEmulation"); //$NON-NLS-1$ + if (synthField == null) { + synthField = new SyntheticFieldBinding( + "$assertionsDisabled".toCharArray(), //$NON-NLS-1$ + BooleanBinding, + AccDefault | AccStatic | AccFinal,//| AccSynthetic | AccFinal, + this, + Constant.NotAConstant, + synthetics[FIELD].size()); + synthetics[FIELD].put("assertionEmulation", synthField); //$NON-NLS-1$ + } + // ensure there is not already such a field defined by the user + // ensure there is not already such a field defined by the user + boolean needRecheck; + int index = 0; + do { + needRecheck = false; + FieldBinding existingField; + if ((existingField = this.getField(synthField.name)) != null) { + TypeDeclaration typeDecl = scope.referenceContext; + for (int i = 0, max = typeDecl.fields.length; i < max; i++) { + FieldDeclaration fieldDecl = typeDecl.fields[i]; + if (fieldDecl.binding == existingField) { + synthField.name = CharOperation.concat( + "$assertionsDisabled".toCharArray(), //$NON-NLS-1$ + ("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$ + needRecheck = true; + break; + } + } + } + } while (needRecheck); + return synthField; +} + +/* Add a new synthetic access method for read/write access to . + Answer the new method or the existing method if one already existed. +*/ + +public SyntheticAccessMethodBinding addSyntheticMethod(FieldBinding targetField, boolean isReadAccess) { + + if (synthetics == null) { + synthetics = new Hashtable[4]; + } + if (synthetics[METHOD] == null) { + synthetics[METHOD] = new Hashtable(5); + } + + SyntheticAccessMethodBinding accessMethod = null; + SyntheticAccessMethodBinding[] accessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD].get(targetField); + if (accessors == null) { + accessMethod = new SyntheticAccessMethodBinding(targetField, isReadAccess, this); + synthetics[METHOD].put(targetField, accessors = new SyntheticAccessMethodBinding[2]); + accessors[isReadAccess ? 0 : 1] = accessMethod; + } else { + if ((accessMethod = accessors[isReadAccess ? 0 : 1]) == null) { + accessMethod = new SyntheticAccessMethodBinding(targetField, isReadAccess, this); + accessors[isReadAccess ? 0 : 1] = accessMethod; + } + } + return accessMethod; +} +/* Add a new synthetic access method for access to . + * Must distinguish access method used for super access from others (need to use invokespecial bytecode) + Answer the new method or the existing method if one already existed. +*/ + +public SyntheticAccessMethodBinding addSyntheticMethod(MethodBinding targetMethod, boolean isSuperAccess) { + + if (synthetics == null) { + synthetics = new Hashtable[4]; + } + if (synthetics[METHOD] == null) { + synthetics[METHOD] = new Hashtable(5); + } + + SyntheticAccessMethodBinding accessMethod = null; + SyntheticAccessMethodBinding[] accessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD].get(targetMethod); + if (accessors == null) { + accessMethod = new SyntheticAccessMethodBinding(targetMethod, isSuperAccess, this); + synthetics[METHOD].put(targetMethod, accessors = new SyntheticAccessMethodBinding[2]); + accessors[isSuperAccess ? 0 : 1] = accessMethod; + } else { + if ((accessMethod = accessors[isSuperAccess ? 0 : 1]) == null) { + accessMethod = new SyntheticAccessMethodBinding(targetMethod, isSuperAccess, this); + accessors[isSuperAccess ? 0 : 1] = accessMethod; + } + } + return accessMethod; +} + +public FieldBinding[] availableFields() { + return fields(); +} +public MethodBinding[] availableMethods() { + return methods(); +} +void faultInTypesForFieldsAndMethods() { + fields(); + methods(); + + for (int i = 0, length = memberTypes.length; i < length; i++) + ((SourceTypeBinding) memberTypes[i]).faultInTypesForFieldsAndMethods(); +} +// NOTE: the type of each field of a source type is resolved when needed + +public FieldBinding[] fields() { + if (fields==null) { + fields = new FieldBinding[0]; + } + try { + int failed = 0; + for (int f = 0, max = fields.length; f < max; f++) { + if (resolveTypeFor(fields[f]) == null) { + fields[f] = null; + failed++; + } + } + if (failed > 0) { + int newSize = fields.length - failed; + if (newSize == 0) + return fields = NoFields; + + FieldBinding[] newFields = new FieldBinding[newSize]; + for (int i = 0, n = 0, max = fields.length; i < max; i++) + if (fields[i] != null) + newFields[n++] = fields[i]; + fields = newFields; + } + } catch(AbortCompilation e){ + // ensure null fields are removed + FieldBinding[] newFields = null; + int count = 0; + for (int i = 0, max = fields.length; i < max; i++){ + FieldBinding field = fields[i]; + if (field == null && newFields == null){ + System.arraycopy(fields, 0, newFields = new FieldBinding[max], 0, i); + } else if (newFields != null && field != null) { + newFields[count++] = field; + } + } + if (newFields != null){ + System.arraycopy(newFields, 0, fields = new FieldBinding[count], 0, count); + } + throw e; + } + return fields; +} +public MethodBinding[] getDefaultAbstractMethods() { + int count = 0; + for (int i = methods.length; --i >= 0;) + if (methods[i].isDefaultAbstract()) + count++; + if (count == 0) return NoMethods; + + MethodBinding[] result = new MethodBinding[count]; + count = 0; + for (int i = methods.length; --i >= 0;) + if (methods[i].isDefaultAbstract()) + result[count++] = methods[i]; + return result; +} +// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed + +public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) { + int argCount = argumentTypes.length; + + if ((modifiers & AccUnresolved) == 0) { // have resolved all arg types & return type of the methods + nextMethod : for (int m = methods.length; --m >= 0;) { + MethodBinding method = methods[m]; + if (method.selector == ConstructorDeclaration.ConstantPoolName && method.parameters.length == argCount) { + TypeBinding[] toMatch = method.parameters; + for (int p = 0; p < argCount; p++) + if (toMatch[p] != argumentTypes[p]) + continue nextMethod; + return method; + } + } + } else { + MethodBinding[] methods = getMethods(ConstructorDeclaration.ConstantPoolName); // takes care of duplicates & default abstract methods + nextMethod : for (int m = methods.length; --m >= 0;) { + MethodBinding method = methods[m]; + TypeBinding[] toMatch = method.parameters; + if (toMatch.length == argCount) { + for (int p = 0; p < argCount; p++) + if (toMatch[p] != argumentTypes[p]) + continue nextMethod; + return method; + } + } + } + return null; +} +// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed +// searches up the hierarchy as long as no potential (but not exact) match was found. + +public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes) { + int argCount = argumentTypes.length; + int selectorLength = selector.length; + boolean foundNothing = true; + + if ((modifiers & AccUnresolved) == 0) { // have resolved all arg types & return type of the methods + nextMethod : for (int m = methods.length; --m >= 0;) { + MethodBinding method = methods[m]; + if (method.selector.length == selectorLength && CharOperation.prefixEquals(method.selector, selector)) { + foundNothing = false; // inner type lookups must know that a method with this name exists + if (method.parameters.length == argCount) { + TypeBinding[] toMatch = method.parameters; + for (int p = 0; p < argCount; p++) + if (toMatch[p] != argumentTypes[p]) + continue nextMethod; + return method; + } + } + } + } else { + MethodBinding[] methods = getMethods(selector); // takes care of duplicates & default abstract methods + foundNothing = methods == NoMethods; + nextMethod : for (int m = methods.length; --m >= 0;) { + MethodBinding method = methods[m]; + TypeBinding[] toMatch = method.parameters; + if (toMatch.length == argCount) { + for (int p = 0; p < argCount; p++) + if (toMatch[p] != argumentTypes[p]) + continue nextMethod; + return method; + } + } + } + + if (foundNothing) { + if (isInterface()) { + if (superInterfaces.length == 1) + return superInterfaces[0].getExactMethod(selector, argumentTypes); + } else if (superclass != null) { + return superclass.getExactMethod(selector, argumentTypes); + } + } + return null; +} +// NOTE: the type of a field of a source type is resolved when needed + +public FieldBinding getField(char[] fieldName) { + int fieldLength = fieldName.length; + for (int f = fields.length; --f >= 0;) { + FieldBinding field = fields[f]; + if (field.name.length == fieldLength && CharOperation.prefixEquals(field.name, fieldName)) { + if (resolveTypeFor(field) != null) + return field; + + int newSize = fields.length - 1; + if (newSize == 0) { + fields = NoFields; + } else { + FieldBinding[] newFields = new FieldBinding[newSize]; + System.arraycopy(fields, 0, newFields, 0, f); + System.arraycopy(fields, f + 1, newFields, f, newSize - f); + fields = newFields; + } + return null; + } + } + return null; +} +// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed + +public MethodBinding[] getMethods(char[] selector) { + // handle forward references to potential default abstract methods + addDefaultAbstractMethods(); + + try{ + int count = 0; + int lastIndex = -1; + int selectorLength = selector.length; + if ((modifiers & AccUnresolved) == 0) { // have resolved all arg types & return type of the methods + for (int m = 0, length = methods.length; m < length; m++) { + MethodBinding method = methods[m]; + if (method.selector.length == selectorLength && CharOperation.prefixEquals(method.selector, selector)) { + count++; + lastIndex = m; + } + } + } else { + boolean foundProblem = false; + int failed = 0; + for (int m = 0, length = methods.length; m < length; m++) { + MethodBinding method = methods[m]; + if (method.selector.length == selectorLength && CharOperation.prefixEquals(method.selector, selector)) { + if (resolveTypesFor(method) == null) { + foundProblem = true; + methods[m] = null; // unable to resolve parameters + failed++; + } else if (method.returnType == null) { + foundProblem = true; + } else { + count++; + lastIndex = m; + } + } + } + + if (foundProblem || count > 1) { + for (int m = methods.length; --m >= 0;) { + MethodBinding method = methods[m]; + if (method != null && method.selector.length == selectorLength && CharOperation.prefixEquals(method.selector, selector)) { + AbstractMethodDeclaration methodDecl = null; + for (int i = 0; i < m; i++) { + MethodBinding method2 = methods[i]; + if (method2 != null && CharOperation.equals(method.selector, method2.selector)) { + if (method.areParametersEqual(method2)) { + if (methodDecl == null) { + methodDecl = method.sourceMethod(); // cannot be retrieved after binding is lost + scope.problemReporter().duplicateMethodInType(this, methodDecl); + methodDecl.binding = null; + methods[m] = null; + failed++; + } + scope.problemReporter().duplicateMethodInType(this, method2.sourceMethod()); + method2.sourceMethod().binding = null; + methods[i] = null; + failed++; + } + } + } + if (method.returnType == null && methodDecl == null) { // forget method with invalid return type... was kept to detect possible collisions + method.sourceMethod().binding = null; + methods[m] = null; + failed++; + } + } + } + + if (failed > 0) { + int newSize = methods.length - failed; + if (newSize == 0) + return methods = NoMethods; + + MethodBinding[] newMethods = new MethodBinding[newSize]; + for (int i = 0, n = 0, max = methods.length; i < max; i++) + if (methods[i] != null) + newMethods[n++] = methods[i]; + methods = newMethods; + return getMethods(selector); // try again now that the problem methods have been removed + } + } + } + if (count == 1) + return new MethodBinding[] {methods[lastIndex]}; + if (count > 1) { + MethodBinding[] result = new MethodBinding[count]; + count = 0; + for (int m = 0; m <= lastIndex; m++) { + MethodBinding method = methods[m]; + if (method.selector.length == selectorLength && CharOperation.prefixEquals(method.selector, selector)) + result[count++] = method; + } + return result; + } + } catch(AbortCompilation e){ + // ensure null methods are removed + MethodBinding[] newMethods = null; + int count = 0; + for (int i = 0, max = methods.length; i < max; i++){ + MethodBinding method = methods[i]; + if (method == null && newMethods == null){ + System.arraycopy(methods, 0, newMethods = new MethodBinding[max], 0, i); + } else if (newMethods != null && method != null) { + newMethods[count++] = method; + } + } + if (newMethods != null){ + System.arraycopy(newMethods, 0, methods = new MethodBinding[count], 0, count); + } + modifiers ^= AccUnresolved; + throw e; + } + return NoMethods; +} +/* Answer the synthetic field for +* or null if one does not exist. +*/ + +public FieldBinding getSyntheticField(LocalVariableBinding actualOuterLocalVariable) { + + if (synthetics == null || synthetics[FIELD] == null) return null; + return (FieldBinding) synthetics[FIELD].get(actualOuterLocalVariable); +} +public ReferenceBinding[] memberTypes() { + return memberTypes; +} +public FieldBinding getUpdatedFieldBinding(FieldBinding targetField, ReferenceBinding newDeclaringClass) { + + if (synthetics == null) { + synthetics = new Hashtable[4]; + } + if (synthetics[CHANGED_DECLARING_CLASS] == null) { + synthetics[CHANGED_DECLARING_CLASS] = new Hashtable(5); + } + + Hashtable fieldMap = (Hashtable) synthetics[CHANGED_DECLARING_CLASS].get(targetField); + if (fieldMap == null) { + fieldMap = new Hashtable(5); + synthetics[CHANGED_DECLARING_CLASS].put(targetField, fieldMap); + } + FieldBinding updatedField = (FieldBinding) fieldMap.get(newDeclaringClass); + if (updatedField == null){ + updatedField = new FieldBinding(targetField, newDeclaringClass); + fieldMap.put(newDeclaringClass, updatedField); + } + return updatedField; +} + +public MethodBinding getUpdatedMethodBinding(MethodBinding targetMethod, ReferenceBinding newDeclaringClass) { + + if (synthetics == null) { + synthetics = new Hashtable[4]; + } + if (synthetics[CHANGED_DECLARING_CLASS] == null) { + synthetics[CHANGED_DECLARING_CLASS] = new Hashtable(5); + } + + + Hashtable methodMap = (Hashtable) synthetics[CHANGED_DECLARING_CLASS].get(targetMethod); + if (methodMap == null) { + methodMap = new Hashtable(5); + synthetics[CHANGED_DECLARING_CLASS].put(targetMethod, methodMap); + } + MethodBinding updatedMethod = (MethodBinding) methodMap.get(newDeclaringClass); + if (updatedMethod == null){ + updatedMethod = new MethodBinding(targetMethod, newDeclaringClass); + methodMap.put(newDeclaringClass, updatedMethod); + } + return updatedMethod; +} + +// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed +public MethodBinding[] methods() { + try { + if ((modifiers & AccUnresolved) == 0) + return methods; + + int failed = 0; + for (int m = 0, max = methods.length; m < max; m++) { + if (resolveTypesFor(methods[m]) == null) { + methods[m] = null; // unable to resolve parameters + failed++; + } + } + + for (int m = methods.length; --m >= 0;) { + MethodBinding method = methods[m]; + if (method != null) { + AbstractMethodDeclaration methodDecl = null; + for (int i = 0; i < m; i++) { + MethodBinding method2 = methods[i]; + if (method2 != null && CharOperation.equals(method.selector, method2.selector)) { + if (method.areParametersEqual(method2)) { + if (methodDecl == null) { + methodDecl = method.sourceMethod(); // cannot be retrieved after binding is lost + scope.problemReporter().duplicateMethodInType(this, methodDecl); + methodDecl.binding = null; + methods[m] = null; + failed++; + } + scope.problemReporter().duplicateMethodInType(this, method2.sourceMethod()); + method2.sourceMethod().binding = null; + methods[i] = null; + failed++; + } + } + } + if (method.returnType == null && methodDecl == null) { // forget method with invalid return type... was kept to detect possible collisions + method.sourceMethod().binding = null; + methods[m] = null; + failed++; + } + } + } + + if (failed > 0) { + int newSize = methods.length - failed; + if (newSize == 0) { + methods = NoMethods; + } else { + MethodBinding[] newMethods = new MethodBinding[newSize]; + for (int m = 0, n = 0, max = methods.length; m < max; m++) + if (methods[m] != null) + newMethods[n++] = methods[m]; + methods = newMethods; + } + } + + // handle forward references to potential default abstract methods + addDefaultAbstractMethods(); + } catch(AbortCompilation e){ + // ensure null methods are removed + MethodBinding[] newMethods = null; + int count = 0; + for (int i = 0, max = methods.length; i < max; i++){ + MethodBinding method = methods[i]; + if (method == null && newMethods == null){ + System.arraycopy(methods, 0, newMethods = new MethodBinding[max], 0, i); + } else if (newMethods != null && method != null) { + newMethods[count++] = method; + } + } + if (newMethods != null){ + System.arraycopy(newMethods, 0, methods = new MethodBinding[count], 0, count); + } + modifiers ^= AccUnresolved; + throw e; + } + modifiers ^= AccUnresolved; + return methods; +} +private FieldBinding resolveTypeFor(FieldBinding field) { + if (field.type != null) + return field; + + FieldDeclaration[] fieldDecls = scope.referenceContext.fields; + for (int f = 0, length = fieldDecls.length; f < length; f++) { + if (fieldDecls[f].binding != field) + continue; + + field.type = fieldDecls[f].getTypeBinding(scope); + if (!field.type.isValidBinding()) { + scope.problemReporter().fieldTypeProblem(this, fieldDecls[f], field.type); + //scope.problemReporter().invalidType(fieldDecls[f].type, field.type); + fieldDecls[f].binding = null; + return null; + } + if (field.type == VoidBinding) { + scope.problemReporter().variableTypeCannotBeVoid(fieldDecls[f]); + fieldDecls[f].binding = null; + return null; + } + if (field.type.isArrayType() && ((ArrayBinding) field.type).leafComponentType == VoidBinding) { + scope.problemReporter().variableTypeCannotBeVoidArray(fieldDecls[f]); + fieldDecls[f].binding = null; + return null; + } + return field; + } + return null; // should never reach this point +} +private MethodBinding resolveTypesFor(MethodBinding method) { + if ((method.modifiers & AccUnresolved) == 0) + return method; + + AbstractMethodDeclaration methodDecl = method.sourceMethod(); + TypeReference[] exceptionTypes = methodDecl.thrownExceptions; + if (exceptionTypes != null) { + int size = exceptionTypes.length; + method.thrownExceptions = new ReferenceBinding[size]; + ReferenceBinding throwable = scope.getJavaLangThrowable(); + int count = 0; + ReferenceBinding resolvedExceptionType; + for (int i = 0; i < size; i++) { + resolvedExceptionType = (ReferenceBinding) exceptionTypes[i].getTypeBinding(scope); + if (!resolvedExceptionType.isValidBinding()) { + methodDecl.scope.problemReporter().exceptionTypeProblem(this, methodDecl, exceptionTypes[i], resolvedExceptionType); + //methodDecl.scope.problemReporter().invalidType(exceptionTypes[i], resolvedExceptionType); + continue; + } + if (throwable != resolvedExceptionType && !throwable.isSuperclassOf(resolvedExceptionType)) { + methodDecl.scope.problemReporter().cannotThrowType(this, methodDecl, exceptionTypes[i], resolvedExceptionType); + continue; + } + method.thrownExceptions[count++] = resolvedExceptionType; + } + if (count < size) + System.arraycopy(method.thrownExceptions, 0, method.thrownExceptions = new ReferenceBinding[count], 0, count); + } + + boolean foundArgProblem = false; + Argument[] arguments = methodDecl.arguments; + if (arguments != null) { + int size = arguments.length; + method.parameters = new TypeBinding[size]; + for (int i = 0; i < size; i++) { + Argument arg = arguments[i]; + method.parameters[i] = arg.type.getTypeBinding(scope); + if (!method.parameters[i].isValidBinding()) { + methodDecl.scope.problemReporter().argumentTypeProblem(this, methodDecl, arg, method.parameters[i]); + //methodDecl.scope.problemReporter().invalidType(arg, method.parameters[i]); + foundArgProblem = true; + } else if (method.parameters[i] == VoidBinding) { + methodDecl.scope.problemReporter().argumentTypeCannotBeVoid(this, methodDecl, arg); + foundArgProblem = true; + } else if (method.parameters[i].isArrayType() && ((ArrayBinding) method.parameters[i]).leafComponentType == VoidBinding) { + methodDecl.scope.problemReporter().argumentTypeCannotBeVoidArray(this, methodDecl, arg); + foundArgProblem = true; + } + } + } + + boolean foundReturnTypeProblem = false; + if (!method.isConstructor()) { + TypeReference returnType = ((MethodDeclaration) methodDecl).returnType; + if (returnType == null) { + methodDecl.scope.problemReporter().missingReturnType(methodDecl); + method.returnType = null; + foundReturnTypeProblem = true; + } else { + method.returnType = returnType.getTypeBinding(scope); + if (!method.returnType.isValidBinding()) { + methodDecl.scope.problemReporter().returnTypeProblem(this, (MethodDeclaration) methodDecl, method.returnType); + //methodDecl.scope.problemReporter().invalidType(returnType, method.returnType); + method.returnType = null; + foundReturnTypeProblem = true; + } else if (method.returnType.isArrayType() && ((ArrayBinding) method.returnType).leafComponentType == VoidBinding) { + methodDecl.scope.problemReporter().returnTypeCannotBeVoidArray(this, (MethodDeclaration) methodDecl); + method.returnType = null; + foundReturnTypeProblem = true; + } + } + } + if (foundArgProblem) { + methodDecl.binding = null; + return null; + } + if (foundReturnTypeProblem) + return method; // but its still unresolved with a null return type & is still connected to its method declaration + + method.modifiers ^= AccUnresolved; + return method; +} +public final int sourceEnd() { + return scope.referenceContext.sourceEnd; +} +public final int sourceStart() { + return scope.referenceContext.sourceStart; +} +public ReferenceBinding superclass() { + return superclass; +} +public ReferenceBinding[] superInterfaces() { + return superInterfaces; +} +public SyntheticAccessMethodBinding[] syntheticAccessMethods() { + + if (synthetics == null || synthetics[METHOD] == null || synthetics[METHOD].size() == 0) return null; + + // difficult to compute size up front because of the embedded arrays so assume there is only 1 + int index = 0; + SyntheticAccessMethodBinding[] bindings = new SyntheticAccessMethodBinding[1]; + Enumeration fieldsOrMethods = synthetics[METHOD].keys(); + while (fieldsOrMethods.hasMoreElements()) { + + Object fieldOrMethod = fieldsOrMethods.nextElement(); + + if (fieldOrMethod instanceof MethodBinding) { + + SyntheticAccessMethodBinding[] methodAccessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD].get(fieldOrMethod); + int numberOfAccessors = 0; + if (methodAccessors[0] != null) numberOfAccessors++; + if (methodAccessors[1] != null) numberOfAccessors++; + if (index + numberOfAccessors > bindings.length) + System.arraycopy(bindings, 0, (bindings = new SyntheticAccessMethodBinding[index + numberOfAccessors]), 0, index); + if (methodAccessors[0] != null) + bindings[index++] = methodAccessors[0]; // super access + if (methodAccessors[1] != null) + bindings[index++] = methodAccessors[1]; // normal access + + } else { + + SyntheticAccessMethodBinding[] fieldAccessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD].get(fieldOrMethod); + int numberOfAccessors = 0; + if (fieldAccessors[0] != null) numberOfAccessors++; + if (fieldAccessors[1] != null) numberOfAccessors++; + if (index + numberOfAccessors > bindings.length) + System.arraycopy(bindings, 0, (bindings = new SyntheticAccessMethodBinding[index + numberOfAccessors]), 0, index); + if (fieldAccessors[0] != null) + bindings[index++] = fieldAccessors[0]; // read access + if (fieldAccessors[1] != null) + bindings[index++] = fieldAccessors[1]; // write access + } + } + + // sort them in according to their own indexes + int length; + SyntheticAccessMethodBinding[] sortedBindings = new SyntheticAccessMethodBinding[length = bindings.length]; + for (int i = 0; i < length; i++){ + SyntheticAccessMethodBinding binding = bindings[i]; + sortedBindings[binding.index] = binding; + } + return sortedBindings; +} +/** + * Answer the collection of synthetic fields to append into the classfile + */ +public FieldBinding[] syntheticFields() { + + if (synthetics == null) return null; + + int fieldSize = synthetics[FIELD] == null ? 0 : synthetics[FIELD].size(); + int literalSize = synthetics[CLASS_LITERAL] == null ? 0 :synthetics[CLASS_LITERAL].size(); + int totalSize = fieldSize + literalSize; + if (totalSize == 0) return null; + FieldBinding[] bindings = new FieldBinding[totalSize]; + + // add innerclass synthetics + if (synthetics[FIELD] != null){ + Enumeration elements = synthetics[FIELD].elements(); + for (int i = 0; i < fieldSize; i++) { + SyntheticFieldBinding synthBinding = (SyntheticFieldBinding) elements.nextElement(); + bindings[synthBinding.index] = synthBinding; + } + } + // add class literal synthetics + if (synthetics[CLASS_LITERAL] != null){ + Enumeration elements = synthetics[CLASS_LITERAL].elements(); + for (int i = 0; i < literalSize; i++) { + SyntheticFieldBinding synthBinding = (SyntheticFieldBinding) elements.nextElement(); + bindings[fieldSize+synthBinding.index] = synthBinding; + } + } + return bindings; +} +public String toString() { + String s = "(id="+(id == NoId ? "NoId" : (""+id) ) +")\n"; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-4$ //$NON-NLS-1$ + + if (isDeprecated()) s += "deprecated "; //$NON-NLS-1$ + if (isPublic()) s += "public "; //$NON-NLS-1$ + if (isProtected()) s += "protected "; //$NON-NLS-1$ + if (isPrivate()) s += "private "; //$NON-NLS-1$ + if (isAbstract() && isClass()) s += "abstract "; //$NON-NLS-1$ + if (isStatic() && isNestedType()) s += "static "; //$NON-NLS-1$ + if (isFinal()) s += "final "; //$NON-NLS-1$ + + s += isInterface() ? "interface " : "class "; //$NON-NLS-1$ //$NON-NLS-2$ + s += (compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED TYPE"; //$NON-NLS-1$ + + s += "\n\textends "; //$NON-NLS-1$ + s += (superclass != null) ? superclass.debugName() : "NULL TYPE"; //$NON-NLS-1$ + + if (superInterfaces != null) { + if (superInterfaces != NoSuperInterfaces) { + s += "\n\timplements : "; //$NON-NLS-1$ + for (int i = 0, length = superInterfaces.length; i < length; i++) { + if (i > 0) + s += ", "; //$NON-NLS-1$ + s += (superInterfaces[i] != null) ? superInterfaces[i].debugName() : "NULL TYPE"; //$NON-NLS-1$ + } + } + } else { + s += "NULL SUPERINTERFACES"; //$NON-NLS-1$ + } + + if (enclosingType() != null) { + s += "\n\tenclosing type : "; //$NON-NLS-1$ + s += enclosingType().debugName(); + } + + if (fields != null) { + if (fields != NoFields) { + s += "\n/* fields */"; //$NON-NLS-1$ + for (int i = 0, length = fields.length; i < length; i++) + s += (fields[i] != null) ? "\n" + fields[i].toString() : "\nNULL FIELD"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } else { + s += "NULL FIELDS"; //$NON-NLS-1$ + } + + if (methods != null) { + if (methods != NoMethods) { + s += "\n/* methods */"; //$NON-NLS-1$ + for (int i = 0, length = methods.length; i < length; i++) + s += (methods[i] != null) ? "\n" + methods[i].toString() : "\nNULL METHOD"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } else { + s += "NULL METHODS"; //$NON-NLS-1$ + } + + if (memberTypes != null) { + if (memberTypes != NoMemberTypes) { + s += "\n/* members */"; //$NON-NLS-1$ + for (int i = 0, length = memberTypes.length; i < length; i++) + s += (memberTypes[i] != null) ? "\n" + memberTypes[i].toString() : "\nNULL TYPE"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } else { + s += "NULL MEMBER TYPES"; //$NON-NLS-1$ + } + + s += "\n\n\n"; //$NON-NLS-1$ + return s; +} +void verifyMethods(MethodVerifier verifier) { + verifier.verify(this); + + for (int i = memberTypes.length; --i >= 0;) + ((SourceTypeBinding) memberTypes[i]).verifyMethods(verifier); +} + +/* Answer the synthetic field for +* or null if one does not exist. +*/ + +public FieldBinding getSyntheticField(ReferenceBinding targetEnclosingType, boolean onlyExactMatch) { + + if (synthetics == null || synthetics[FIELD] == null) return null; + FieldBinding field = (FieldBinding) synthetics[FIELD].get(targetEnclosingType); + if (field != null) return field; + + // type compatibility : to handle cases such as + // class T { class M{}} + // class S extends T { class N extends M {}} --> need to use S as a default enclosing instance for the super constructor call in N(). + if (!onlyExactMatch){ + Enumeration enum = synthetics[FIELD].elements(); + while (enum.hasMoreElements()) { + field = (FieldBinding) enum.nextElement(); + if (CharOperation.prefixEquals(SyntheticArgumentBinding.EnclosingInstancePrefix, field.name) + && targetEnclosingType.isSuperclassOf((ReferenceBinding) field.type)) + return field; + } + } + return null; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SyntheticAccessMethodBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SyntheticAccessMethodBinding.java new file mode 100644 index 0000000..7b729e9 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SyntheticAccessMethodBinding.java @@ -0,0 +1,288 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration; + +public class SyntheticAccessMethodBinding extends MethodBinding { + + public FieldBinding targetReadField; // read access to a field + public FieldBinding targetWriteField; // write access to a field + public MethodBinding targetMethod; // method or constructor + + public int accessType; + + public final static int FieldReadAccess = 1; // field read + public final static int FieldWriteAccess = 2; // field write + public final static int MethodAccess = 3; // normal method + public final static int ConstructorAccess = 4; // constructor + public final static int SuperMethodAccess = 5; // super method + + final static char[] AccessMethodPrefix = { 'a', 'c', 'c', 'e', 's', 's', '$' }; + + public int sourceStart = 0; // start position of the matching declaration + public int index; // used for sorting access methods in the class file + + public SyntheticAccessMethodBinding(FieldBinding targetField, boolean isReadAccess, ReferenceBinding declaringClass) { + + this.modifiers = AccDefault | AccStatic;// | AccSynthetic; + SourceTypeBinding declaringSourceType = (SourceTypeBinding) declaringClass; + SyntheticAccessMethodBinding[] knownAccessMethods = declaringSourceType.syntheticAccessMethods(); + int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length; + this.index = methodId; + this.selector = CharOperation.concat(AccessMethodPrefix, String.valueOf(methodId).toCharArray()); + if (isReadAccess) { + this.returnType = targetField.type; + if (targetField.isStatic()) { + this.parameters = NoParameters; + } else { + this.parameters = new TypeBinding[1]; + this.parameters[0] = declaringSourceType; + } + this.targetReadField = targetField; + this.accessType = FieldReadAccess; + } else { + this.returnType = VoidBinding; + if (targetField.isStatic()) { + this.parameters = new TypeBinding[1]; + this.parameters[0] = targetField.type; + } else { + this.parameters = new TypeBinding[2]; + this.parameters[0] = declaringSourceType; + this.parameters[1] = targetField.type; + } + this.targetWriteField = targetField; + this.accessType = FieldWriteAccess; + } + this.thrownExceptions = NoExceptions; + this.declaringClass = declaringSourceType; + + // check for method collision + boolean needRename; + do { + check : { + needRename = false; + // check for collision with known methods + MethodBinding[] methods = declaringSourceType.methods; + for (int i = 0, length = methods.length; i < length; i++) { + if (this.selector == methods[i].selector && this.areParametersEqual(methods[i])) { + needRename = true; + break check; + } + } + // check for collision with synthetic accessors + if (knownAccessMethods != null) { + for (int i = 0, length = knownAccessMethods.length; i < length; i++) { + if (knownAccessMethods[i] == null) continue; + if (this.selector == knownAccessMethods[i].selector && this.areParametersEqual(methods[i])) { + needRename = true; + break check; + } + } + } + } + if (needRename) { // retry with a selector postfixed by a growing methodId + this.selector(CharOperation.concat(AccessMethodPrefix, String.valueOf(++methodId).toCharArray())); + } + } while (needRename); + + // retrieve sourceStart position for the target field for line number attributes + FieldDeclaration[] fieldDecls = declaringSourceType.scope.referenceContext.fields; + if (fieldDecls != null) { + for (int i = 0, max = fieldDecls.length; i < max; i++) { + if (fieldDecls[i].binding == targetField) { + this.sourceStart = fieldDecls[i].sourceStart; + return; + } + } + } + + /* did not find the target field declaration - it is a synthetic one + public class A { + public class B { + public class C { + void foo() { + System.out.println("A.this = " + A.this); + } + } + } + public static void main(String args[]) { + new A().new B().new C().foo(); + } + } + */ + // We now at this point - per construction - it is for sure an enclosing instance, we are going to + // show the target field type declaration location. + this.sourceStart = declaringSourceType.scope.referenceContext.sourceStart; // use the target declaring class name position instead + } + + public SyntheticAccessMethodBinding(MethodBinding targetMethod, boolean isSuperAccess, ReferenceBinding receiverType) { + + if (targetMethod.isConstructor()) { + this.initializeConstructorAccessor(targetMethod); + } else { + this.initializeMethodAccessor(targetMethod, isSuperAccess, receiverType); + } + } + + /** + * An constructor accessor is a constructor with an extra argument (declaringClass), in case of + * collision with an existing constructor, then add again an extra argument (declaringClass again). + */ + public void initializeConstructorAccessor(MethodBinding targetConstructor) { + + this.targetMethod = targetConstructor; + this.modifiers = AccDefault;// | AccSynthetic; + SourceTypeBinding sourceType = (SourceTypeBinding) targetConstructor.declaringClass; + SyntheticAccessMethodBinding[] knownAccessMethods = + sourceType.syntheticAccessMethods(); + this.index = knownAccessMethods == null ? 0 : knownAccessMethods.length; + + this.selector = targetConstructor.selector; + this.returnType = targetConstructor.returnType; + this.accessType = ConstructorAccess; + this.parameters = new TypeBinding[targetConstructor.parameters.length + 1]; + System.arraycopy( + targetConstructor.parameters, + 0, + this.parameters, + 0, + targetConstructor.parameters.length); + parameters[targetConstructor.parameters.length] = + targetConstructor.declaringClass; + this.thrownExceptions = targetConstructor.thrownExceptions; + this.declaringClass = sourceType; + + // check for method collision + boolean needRename; + do { + check : { + needRename = false; + // check for collision with known methods + MethodBinding[] methods = sourceType.methods; + for (int i = 0, length = methods.length; i < length; i++) { + if (this.selector == methods[i].selector + && this.areParametersEqual(methods[i])) { + needRename = true; + break check; + } + } + // check for collision with synthetic accessors + if (knownAccessMethods != null) { + for (int i = 0, length = knownAccessMethods.length; i < length; i++) { + if (knownAccessMethods[i] == null) + continue; + if (this.selector == knownAccessMethods[i].selector + && this.areParametersEqual(knownAccessMethods[i])) { + needRename = true; + break check; + } + } + } + } + if (needRename) { // retry with a new extra argument + int length = this.parameters.length; + System.arraycopy( + this.parameters, + 0, + this.parameters = new TypeBinding[length + 1], + 0, + length); + this.parameters[length] = this.declaringClass; + } + } while (needRename); + + // retrieve sourceStart position for the target method for line number attributes + AbstractMethodDeclaration[] methodDecls = + sourceType.scope.referenceContext.methods; + if (methodDecls != null) { + for (int i = 0, length = methodDecls.length; i < length; i++) { + if (methodDecls[i].binding == targetConstructor) { + this.sourceStart = methodDecls[i].sourceStart; + return; + } + } + } + } + + /** + * An method accessor is a method with an access$N selector, where N is incremented in case of collisions. + */ + public void initializeMethodAccessor(MethodBinding targetMethod, boolean isSuperAccess, ReferenceBinding declaringClass) { + + this.targetMethod = targetMethod; + this.modifiers = AccDefault | AccStatic;// | AccSynthetic; + SourceTypeBinding declaringSourceType = (SourceTypeBinding) declaringClass; + SyntheticAccessMethodBinding[] knownAccessMethods = declaringSourceType.syntheticAccessMethods(); + int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length; + this.index = methodId; + + this.selector = CharOperation.concat(AccessMethodPrefix, String.valueOf(methodId).toCharArray()); + this.returnType = targetMethod.returnType; + this.accessType = isSuperAccess ? SuperMethodAccess : MethodAccess; + + if (targetMethod.isStatic()) { + this.parameters = targetMethod.parameters; + } else { + this.parameters = new TypeBinding[targetMethod.parameters.length + 1]; + this.parameters[0] = declaringSourceType; + System.arraycopy(targetMethod.parameters, 0, this.parameters, 1, targetMethod.parameters.length); + } + this.thrownExceptions = targetMethod.thrownExceptions; + this.declaringClass = declaringSourceType; + + // check for method collision + boolean needRename; + do { + check : { + needRename = false; + // check for collision with known methods + MethodBinding[] methods = declaringSourceType.methods; + for (int i = 0, length = methods.length; i < length; i++) { + if (this.selector == methods[i].selector && this.areParametersEqual(methods[i])) { + needRename = true; + break check; + } + } + // check for collision with synthetic accessors + if (knownAccessMethods != null) { + for (int i = 0, length = knownAccessMethods.length; i < length; i++) { + if (knownAccessMethods[i] == null) continue; + if (this.selector == knownAccessMethods[i].selector && this.areParametersEqual(knownAccessMethods[i])) { + needRename = true; + break check; + } + } + } + } + if (needRename) { // retry with a selector & a growing methodId + this.selector(CharOperation.concat(AccessMethodPrefix, String.valueOf(++methodId).toCharArray())); + } + } while (needRename); + + // retrieve sourceStart position for the target method for line number attributes + AbstractMethodDeclaration[] methodDecls = declaringSourceType.scope.referenceContext.methods; + if (methodDecls != null) { + for (int i = 0, length = methodDecls.length; i < length; i++) { + if (methodDecls[i].binding == targetMethod) { + this.sourceStart = methodDecls[i].sourceStart; + return; + } + } + } + } + + protected boolean isConstructorRelated() { + return accessType == ConstructorAccess; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SyntheticArgumentBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SyntheticArgumentBinding.java new file mode 100644 index 0000000..1afe5b8 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SyntheticArgumentBinding.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; + +/** + * Specific local variable location used to: + * - either provide emulation for outer local variables used from within innerclass constructs, + * - or provide emulation to enclosing instances. + * When it is mapping to an outer local variable, this actual outer local is accessible through + * the public field #actualOuterLocalVariable. + * + * Such a synthetic argument binding will be inserted in all constructors of local innertypes before + * the user arguments. + */ + +public class SyntheticArgumentBinding extends LocalVariableBinding { + + { + this.isArgument = true; + this.useFlag = USED; + } + + // if the argument is mapping to an outer local variable, this denotes the outer actual variable + public LocalVariableBinding actualOuterLocalVariable; + // if the argument has a matching synthetic field + public FieldBinding matchingField; + + final static char[] OuterLocalPrefix = { 'v', 'a', 'l', '$' }; + final static char[] EnclosingInstancePrefix = { 't', 'h', 'i', 's', '$' }; + + public SyntheticArgumentBinding(LocalVariableBinding actualOuterLocalVariable) { + + super( + CharOperation.concat(OuterLocalPrefix, actualOuterLocalVariable.name), + actualOuterLocalVariable.type, + AccFinal, + true); + this.actualOuterLocalVariable = actualOuterLocalVariable; + } + + public SyntheticArgumentBinding(ReferenceBinding enclosingType) { + + super( + CharOperation.concat( + SyntheticArgumentBinding.EnclosingInstancePrefix, + String.valueOf(enclosingType.depth()).toCharArray()), + enclosingType, + AccFinal, + true); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SyntheticFieldBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SyntheticFieldBinding.java new file mode 100644 index 0000000..4206652 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SyntheticFieldBinding.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.internal.compiler.impl.Constant; + +public class SyntheticFieldBinding extends FieldBinding { + public int index; +public SyntheticFieldBinding(char[] name, TypeBinding type, int modifiers, ReferenceBinding declaringClass, Constant constant, int index) { + super(name, type, modifiers, declaringClass, constant); + this.index = index; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/TagBits.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/TagBits.java new file mode 100644 index 0000000..5555c83 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/TagBits.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +public interface TagBits { + // Tag bits in the tagBits int of every TypeBinding + final int IsArrayType = 0x0001; + final int IsBaseType = 0x0002; + final int IsNestedType = 0x0004; + final int IsMemberType = 0x0008; + final int MemberTypeMask = IsNestedType | IsMemberType; + final int IsLocalType = 0x0010; + final int LocalTypeMask = IsNestedType | IsLocalType; + final int IsAnonymousType = 0x0020; + final int AnonymousTypeMask = LocalTypeMask | IsAnonymousType; + final int IsBinaryBinding = 0x0040; + + // for the type hierarchy check used by ClassScope + final int BeginHierarchyCheck = 0x0100; + final int EndHierarchyCheck = 0x0200; + + // test bit to see if default abstract methods were computed + final int KnowsDefaultAbstractMethods = 0x0400; + + // Reusable bit currently used by Scopes + final int InterfaceVisited = 0x0800; + + // test bits to see if parts of binary types are faulted + final int AreFieldsComplete = 0x1000; + final int AreMethodsComplete = 0x2000; + + // test bit to avoid asking a type for a member type (includes inherited member types) + final int HasNoMemberTypes = 0x4000; + + // test bit to identify if the type's hierarchy is inconsistent + final int HierarchyHasProblems = 0x8000; +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/TypeBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/TypeBinding.java new file mode 100644 index 0000000..7bb7ec3 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/TypeBinding.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; + +/* + * Not all fields defined by this type (& its subclasses) are initialized when it is created. + * Some are initialized only when needed. + * + * Accessors have been provided for some public fields so all TypeBindings have the same API... + * but access public fields directly whenever possible. + * Non-public fields have accessors which should be used everywhere you expect the field to be initialized. + * + * null is NOT a valid value for a non-public field... it just means the field is not initialized. + */ +abstract public class TypeBinding extends Binding implements BaseTypes, TagBits, TypeConstants, TypeIds { + public int id = NoId; + public int tagBits = 0; // See values in the interface TagBits below +/* API + * Answer the receiver's binding type from Binding.BindingID. + */ + +public final int bindingType() { + return TYPE; +} +/* Answer true if the receiver can be instantiated + */ + +public boolean canBeInstantiated() { + return !isBaseType(); +} +/* Answer the receiver's constant pool name. + * + * NOTE: This method should only be used during/after code gen. + */ + +public abstract char[] constantPoolName(); /* java/lang/Object */ +String debugName() { + return new String(readableName()); +} +/* + * Answer the receiver's dimensions - 0 for non-array types + */ +public int dimensions(){ + return 0; +} +public abstract PackageBinding getPackage(); +/* Answer true if the receiver is an array +*/ + +public final boolean isArrayType() { + return (tagBits & IsArrayType) != 0; +} +/* Answer true if the receiver is a base type +*/ + +public final boolean isBaseType() { + return (tagBits & IsBaseType) != 0; +} +public boolean isClass() { + return false; +} +/* Answer true if the receiver type can be assigned to the argument type (right) +*/ + +public abstract boolean isCompatibleWith(TypeBinding right); +/* Answer true if the receiver's hierarchy has problems (always false for arrays & base types) +*/ + +public final boolean isHierarchyInconsistent() { + return (tagBits & HierarchyHasProblems) != 0; +} +public boolean isInterface() { + return false; +} +public final boolean isNumericType() { + switch (id) { + case T_int : + case T_float : + case T_double : + case T_short : + case T_byte : + case T_long : + case T_char : + return true; + default : + return false; + } +} + +public TypeBinding leafComponentType(){ + return this; +} + +/** + * Answer the qualified name of the receiver's package separated by periods + * or an empty string if its the default package. + * + * For example, {java.util.Hashtable}. + */ + +public char[] qualifiedPackageName() { + PackageBinding packageBinding = getPackage(); + return packageBinding == null || packageBinding.compoundName == CharOperation.NO_CHAR_CHAR + ? CharOperation.NO_CHAR + : packageBinding.readableName(); +} +/** +* Answer the source name for the type. +* In the case of member types, as the qualified name from its top level type. +* For example, for a member type N defined inside M & A: "A.M.N". +*/ + +public abstract char[] qualifiedSourceName(); +/* Answer the receiver's signature. +* +* Arrays & base types do not distinguish between signature() & constantPoolName(). +* +* NOTE: This method should only be used during/after code gen. +*/ + +public char[] signature() { + return constantPoolName(); +} +public abstract char[] sourceName(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/TypeConstants.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/TypeConstants.java new file mode 100644 index 0000000..394e0c9 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/TypeConstants.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +public interface TypeConstants { + final char[] JAVA = "java".toCharArray(); //$NON-NLS-1$ + final char[] LANG = "lang".toCharArray(); //$NON-NLS-1$ + final char[] IO = "io".toCharArray(); //$NON-NLS-1$ + final char[] REFLECT = "reflect".toCharArray(); //$NON-NLS-1$ + final char[] CharArray_JAVA_LANG_OBJECT = "java.lang.Object".toCharArray(); //$NON-NLS-1$ + final char[] LENGTH = "length".toCharArray(); //$NON-NLS-1$ + final char[] CLONE = "clone".toCharArray(); //$NON-NLS-1$ + final char[] OBJECT = "Object".toCharArray(); //$NON-NLS-1$ + final char[] MAIN = "main".toCharArray(); //$NON-NLS-1$ + final char[] SERIALVERSIONUID = "serialVersionUID".toCharArray(); //$NON-NLS-1$ + final char[] READRESOLVE = "readResolve".toCharArray(); //$NON-NLS-1$ + final char[] WRITEREPLACE = "writeReplace".toCharArray(); //$NON-NLS-1$ + final char[] READOBJECT = "readObject".toCharArray(); //$NON-NLS-1$ + final char[] WRITEOBJECT = "writeObject".toCharArray(); //$NON-NLS-1$ + final char[] CharArray_JAVA_IO_OBJECTINPUTSTREAM = "java.io.ObjectInputStream".toCharArray(); //$NON-NLS-1$ + final char[] CharArray_JAVA_IO_OBJECTOUTPUTSTREAM = "java.io.ObjectOutputStream".toCharArray(); //$NON-NLS-1$ + + // Constant compound names + final char[][] JAVA_LANG = {JAVA, LANG}; + final char[][] JAVA_IO = {JAVA, IO}; + final char[][] JAVA_LANG_ASSERTIONERROR = {JAVA, LANG, "AssertionError".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_CLASS = {JAVA, LANG, "Class".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_CLASSNOTFOUNDEXCEPTION = {JAVA, LANG, "ClassNotFoundException".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_CLONEABLE = {JAVA, LANG, "Cloneable".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_EXCEPTION = {JAVA, LANG, "Exception".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_ERROR = {JAVA, LANG, "Error".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_NOCLASSDEFERROR = {JAVA, LANG, "NoClassDefError".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_OBJECT = {OBJECT};//{JAVA, LANG, OBJECT}; + final char[][] JAVA_LANG_STRING = {JAVA, LANG, "String".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_STRINGBUFFER = {JAVA, LANG, "StringBuffer".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_SYSTEM = {JAVA, LANG, "System".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_RUNTIMEEXCEPTION = {JAVA, LANG, "RuntimeException".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_THROWABLE = {JAVA, LANG, "Throwable".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_REFLECT_CONSTRUCTOR = {JAVA, LANG, REFLECT, "Constructor".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_IO_PRINTSTREAM = {JAVA, IO, "PrintStream".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_IO_SERIALIZABLE = {JAVA, IO, "Serializable".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_BYTE = {JAVA, LANG, "Byte".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_SHORT = {JAVA, LANG, "Short".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_CHARACTER = {JAVA, LANG, "Character".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_INTEGER = {JAVA, LANG, "Integer".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_LONG = {JAVA, LANG, "Long".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_FLOAT = {JAVA, LANG, "Float".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_DOUBLE = {JAVA, LANG, "Double".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_BOOLEAN = {JAVA, LANG, "Boolean".toCharArray()}; //$NON-NLS-1$ + final char[][] JAVA_LANG_VOID = {JAVA, LANG, "Void".toCharArray()}; //$NON-NLS-1$ + + // Constants used by the flow analysis + final int EqualOrMoreSpecific = -1; + final int NotRelated = 0; + final int MoreGeneric = 1; + + // Method collections + final TypeBinding[] NoParameters = new TypeBinding[0]; + final ReferenceBinding[] NoExceptions = new ReferenceBinding[0]; + // Type collections + final FieldBinding[] NoFields = new FieldBinding[0]; + final MethodBinding[] NoMethods = new MethodBinding[0]; + final ReferenceBinding[] NoSuperInterfaces = new ReferenceBinding[0]; + final ReferenceBinding[] NoMemberTypes = new ReferenceBinding[0]; +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/TypeIds.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/TypeIds.java new file mode 100644 index 0000000..acca0a1 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/TypeIds.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +public interface TypeIds { + //base type void null undefined Object String + //should have an id that is 0<= id <= 15 + + final int T_undefined = 0; // should not be changed + final int T_Object = 1; + final int T_char = 2; + final int T_byte = 3; + final int T_short = 4; + final int T_boolean = 5; + final int T_void = 6; + final int T_long = 7; + final int T_double = 8; + final int T_float = 9; + final int T_int = 10; + final int T_String = 11; + final int T_null = 12; + //final int T_extendedDouble = 13; + //final int T_extendedLong = 14 + + //=========end of 4 bits constraint=========== + + final int T_JavaLangObject = T_Object; // for consistency + final int T_JavaLangString = T_String; // for consistency + + // well-known exception types + final int T_JavaLangClass = 16; + final int T_JavaLangStringBuffer = 17; + final int T_JavaLangSystem = 18; + final int T_JavaLangError = 19; + final int T_JavaLangReflectConstructor = 20; + final int T_JavaLangThrowable = 21; + final int T_JavaLangNoClassDefError = 22; + final int T_JavaLangClassNotFoundException = 23; + final int T_JavaIoPrintStream = 24; + final int T_JavaLangException = 25; + + // wrapper types + final int T_JavaLangByte = 26; + final int T_JavaLangShort = 27; + final int T_JavaLangCharacter = 28; + final int T_JavaLangInteger = 29; + final int T_JavaLangLong = 30; + final int T_JavaLangFloat = 31; + final int T_JavaLangDouble = 32; + final int T_JavaLangBoolean = 33; + final int T_JavaLangVoid = 34; + + // 1.4 feature + final int T_JavaLangAssertionError = 35; + final int NoId = Integer.MAX_VALUE; + + // implicit conversions: to (note: booleans are integers at runtime) + final int Boolean2Int = T_boolean + (T_int << 4); + final int Boolean2String = T_boolean + (T_String << 4); + final int Boolean2Boolean = T_boolean + (T_boolean << 4); + final int Byte2Byte = T_byte + (T_byte << 4); + final int Byte2Short = T_byte + (T_short << 4); + final int Byte2Char = T_byte + (T_char << 4); + final int Byte2Int = T_byte + (T_int << 4); + final int Byte2Long = T_byte + (T_long << 4); + final int Byte2Float = T_byte + (T_float << 4); + final int Byte2Double = T_byte + (T_double << 4); + final int Byte2String = T_byte + (T_String << 4); + final int Short2Byte = T_short + (T_byte << 4); + final int Short2Short = T_short + (T_short << 4); + final int Short2Char = T_short + (T_char << 4); + final int Short2Int = T_short + (T_int << 4); + final int Short2Long = T_short + (T_long << 4); + final int Short2Float = T_short + (T_float << 4); + final int Short2Double = T_short + (T_double << 4); + final int Short2String = T_short + (T_String << 4); + final int Char2Byte = T_char + (T_byte << 4); + final int Char2Short = T_char + (T_short << 4); + final int Char2Char = T_char + (T_char << 4); + final int Char2Int = T_char + (T_int << 4); + final int Char2Long = T_char + (T_long << 4); + final int Char2Float = T_char + (T_float << 4); + final int Char2Double = T_char + (T_double << 4); + final int Char2String = T_char + (T_String << 4); + final int Int2Byte = T_int + (T_byte << 4); + final int Int2Short = T_int + (T_short << 4); + final int Int2Char = T_int + (T_char << 4); + final int Int2Int = T_int + (T_int << 4); + final int Int2Long = T_int + (T_long << 4); + final int Int2Float = T_int + (T_float << 4); + final int Int2Double = T_int + (T_double << 4); + final int Int2String = T_int + (T_String << 4); + final int Long2Byte = T_long + (T_byte << 4); + final int Long2Short = T_long + (T_short << 4); + final int Long2Char = T_long + (T_char << 4); + final int Long2Int = T_long + (T_int << 4); + final int Long2Long = T_long + (T_long << 4); + final int Long2Float = T_long + (T_float << 4); + final int Long2Double = T_long + (T_double << 4); + final int Long2String = T_long + (T_String << 4); + final int Float2Byte = T_float + (T_byte << 4); + final int Float2Short = T_float + (T_short << 4); + final int Float2Char = T_float + (T_char << 4); + final int Float2Int = T_float + (T_int << 4); + final int Float2Long = T_float + (T_long << 4); + final int Float2Float = T_float + (T_float << 4); + final int Float2Double = T_float + (T_double << 4); + final int Float2String = T_float + (T_String << 4); + final int Double2Byte = T_double + (T_byte << 4); + final int Double2Short = T_double + (T_short << 4); + final int Double2Char = T_double + (T_char << 4); + final int Double2Int = T_double + (T_int << 4); + final int Double2Long = T_double + (T_long << 4); + final int Double2Float = T_double + (T_float << 4); + final int Double2Double = T_double + (T_double << 4); + final int Double2String = T_double + (T_String << 4); + final int String2String = T_String + (T_String << 4); + final int Object2String = T_Object + (T_String << 4); + final int Null2String = T_null + (T_String << 4); + final int Object2Object = T_Object + (T_Object << 4); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/UnresolvedReferenceBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/UnresolvedReferenceBinding.java new file mode 100644 index 0000000..fdf1c4c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/UnresolvedReferenceBinding.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.core.compiler.CharOperation; + +public class UnresolvedReferenceBinding extends ReferenceBinding { + ReferenceBinding resolvedType; +UnresolvedReferenceBinding(char[][] compoundName, PackageBinding packageBinding) { + this.compoundName = compoundName; + this.fPackage = packageBinding; +} +String debugName() { + return toString(); +} +ReferenceBinding resolve(LookupEnvironment environment) { + if (resolvedType != null) return resolvedType; + + ReferenceBinding environmentType = fPackage.getType0(compoundName[compoundName.length - 1]); + if (environmentType == this) + environmentType = environment.askForType(compoundName); + if (environmentType != null && environmentType != this) { // could not resolve any better, error was already reported against it + resolvedType = environmentType; + environment.updateArrayCache(this, environmentType); + return environmentType; // when found, it replaces the unresolved type in the cache + } + + environment.problemReporter.isClassPathCorrect(compoundName, null); + return null; // will not get here since the above error aborts the compilation +} +public String toString() { + return "Unresolved type " + ((compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED"); //$NON-NLS-1$ //$NON-NLS-2$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/VariableBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/VariableBinding.java new file mode 100644 index 0000000..04ee3da --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/VariableBinding.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.lookup; + +import net.sourceforge.phpdt.internal.compiler.impl.Constant; + +public abstract class VariableBinding extends Binding { + public int modifiers; + public TypeBinding type; + public char[] name; + public Constant constant; + public int id; // for flow-analysis (position in flowInfo bit vector) + +public boolean isConstantValue() { + return constant != Constant.NotAConstant; +} + +public final boolean isBlankFinal(){ + return (modifiers & AccBlankFinal) != 0; +} +/* Answer true if the receiver is final and cannot be changed +*/ + +public final boolean isFinal() { + return (modifiers & AccFinal) != 0; +} +public char[] readableName() { + return name; +} +public String toString() { + String s = (type != null) ? type.debugName() : "UNDEFINED TYPE"; //$NON-NLS-1$ + s += " "; //$NON-NLS-1$ + s += (name != null) ? new String(name) : "UNNAMED FIELD"; //$NON-NLS-1$ + return s; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java index 99ead74..1a484bc 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java @@ -12,9 +12,19 @@ package net.sourceforge.phpdt.internal.compiler.parser; import java.util.ArrayList; +import net.sourceforge.phpdt.core.compiler.CharOperation; import net.sourceforge.phpdt.core.compiler.ITerminalSymbols; import net.sourceforge.phpdt.core.compiler.InvalidInputException; +import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; import net.sourceforge.phpeclipse.phpeditor.PHPString; import org.eclipse.core.resources.IFile; @@ -23,7 +33,17 @@ import org.eclipse.jface.preference.IPreferenceStore; import test.PHPParserSuperclass; -public class Parser extends PHPParserSuperclass implements ITerminalSymbols { +public class Parser extends PHPParserSuperclass implements ITerminalSymbols, ParserBasicInformation { + //internal data for the automat + protected final static int StackIncrement = 255; + protected int stateStackTop; + protected int[] stack = new int[StackIncrement]; + public int firstToken; // handle for multiple parsing goals + public int lastAct; //handle for multiple parsing goals + protected RecoveredElement currentElement; + + public static boolean VERBOSE_RECOVERY = false; + protected boolean diet = false; //tells the scanner to jump over some parts of the code/expressions like method bodies //scanner token public Scanner scanner; @@ -137,12 +157,24 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { // final static int TokenNameOR = 159; // final static int TokenNameAT = 153; // @ - public Parser() { + protected Parser() { + this.currentPHPString = 0; + // PHPParserSuperclass.fileToParse = fileToParse; + this.phpList = null; + this.str = ""; + this.token = TokenNameEOF; + // this.chIndx = 0; + // this.rowCount = 1; + // this.columnCount = 0; + this.phpEnd = false; + // getNextToken(); + + this.initializeScanner(); } public void setFileToParse(IFile fileToParse) { this.currentPHPString = 0; - PHPParserSuperclass.fileToParse = fileToParse; + PHPParserSuperclass.fileToParse = fileToParse; this.phpList = null; this.str = ""; this.token = TokenNameEOF; @@ -164,7 +196,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { // } // } this.currentPHPString = 0; - PHPParserSuperclass.fileToParse = fileToParse; + PHPParserSuperclass.fileToParse = fileToParse; this.phpList = null; this.str = ""; this.token = TokenNameEOF; @@ -225,6 +257,10 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { throw new SyntaxError(startRow, 0, " ", error); } + private void reportSyntaxError(String error, int problemStartPosition, int problemEndPosition) { + problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, compilationUnit.compilationResult); + throw new SyntaxError(1, 0, " ", error); + } /** * Method Declaration. * @@ -683,12 +719,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } while (true); } - - /** - * Parses a string with php tags - * i.e. '<body> <?php phpinfo() ?> </body>' - */ - public void parse(String s) throws CoreException { + public void init(String s) { this.str = s; this.token = TokenNameEOF; // this.chIndx = 0; @@ -699,6 +730,34 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { /* scanner initialization */ scanner.setSource(s.toCharArray()); scanner.setPHPMode(false); + } + + protected void initialize() { + compilationUnit = null; + referenceContext = null; + this.str = ""; + this.token = TokenNameEOF; + // this.chIndx = 0; + // this.rowCount = 1; + // this.columnCount = 0; + this.phpEnd = false; + this.phpMode = false; + scanner.setPHPMode(false); + } + /** + * Parses a string with php tags + * i.e. '<body> <?php phpinfo() ?> </body>' + */ + public void parse(String s) throws CoreException { + init(s); + parse(); + } + + /** + * Parses a string with php tags + * i.e. '<body> <?php phpinfo() ?> </body>' + */ + protected void parse() throws CoreException { getNextToken(); do { try { @@ -907,11 +966,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { if (counter == 0 && goBack) { return; } - } else if ( - token == TokenNamerequire - || token == TokenNamerequire_once - || token == TokenNameinclude - || token == TokenNameinclude_once) { + } else if (token == TokenNamerequire || token == TokenNamerequire_once || token == TokenNameinclude || token == TokenNameinclude_once) { ident = scanner.getCurrentTokenSource(); getNextToken(); @@ -957,7 +1012,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } while (true); } - private void compoundStatement() throws CoreException { + private void functionBody(MethodDeclaration methodDecl) throws CoreException { // '{' [statement-list] '}' if (token == TokenNameLBRACE) { getNextToken(); @@ -968,6 +1023,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { statementList(); } if (token == TokenNameRBRACE) { + methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); getNextToken(); } else { throwSyntaxError("'}' expected in compound-statement."); @@ -1287,18 +1343,30 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } return; } else if (token == TokenNamefunction) { + MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult); + methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); getNextToken(); - functionDefinition(); + functionDefinition(methodDecl); return; } else if (token == TokenNameclass) { - getNextToken(); - classDeclarator(); - classBody(); + TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult); + typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); + // default super class + typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0); + compilationUnit.types.add(typeDecl); + try { + pushOnAstStack(typeDecl); + getNextToken(); + classDeclarator(typeDecl); + classBody(typeDecl); + } finally { + astPtr--; + astLengthPtr--; + } return; // } else { // throwSyntaxError("Unexpected keyword '" + keyword + "'"); } else if (token == TokenNameLBRACE) { - // compoundStatement getNextToken(); if (token != TokenNameRBRACE) { statementList(); @@ -1325,10 +1393,14 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } } - private void classDeclarator() throws CoreException { + private void classDeclarator(TypeDeclaration typeDecl) throws CoreException { //identifier //identifier 'extends' identifier + if (token == TokenNameIdentifier) { + typeDecl.sourceStart = scanner.getCurrentTokenStartPosition(); + typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition(); + typeDecl.name = scanner.getCurrentIdentifierSource(); getNextToken(); if (token == TokenNameextends) { do { @@ -1336,19 +1408,30 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { if (token == TokenNameIdentifier) { getNextToken(); } else { - throwSyntaxError("ClassDeclaration name expected after keyword 'extends'."); + reportSyntaxError("Class name expected after keyword 'extends'.", scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition()); + // throwSyntaxError("ClassDeclaration name expected after keyword 'extends'."); } } while (token == TokenNameCOMMA); - } + } } else { + typeDecl.sourceStart = scanner.getCurrentTokenStartPosition(); + typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition(); + if (token > TokenNameKEYWORD) { - throwSyntaxError("Don't use keyword for class declaration [" + token + "]."); - } - throwSyntaxError("ClassDeclaration name expected after keyword 'class'."); + typeDecl.name = scanner.getCurrentIdentifierSource(); + reportSyntaxError( + "Don't use keyword for class declaration [" + scanner.toStringAction(token) + "].", + typeDecl.sourceStart, + typeDecl.sourceEnd); + // throwSyntaxError("Don't use keyword for class declaration [" + token + "]."); + } + typeDecl.name = new char[] { ' ' }; + reportSyntaxError("Class name expected after keyword 'class'.", typeDecl.sourceStart, typeDecl.sourceEnd); + // throwSyntaxError("ClassDeclaration name expected after keyword 'class'."); } } - private void classBody() throws CoreException { + private void classBody(TypeDeclaration typeDecl) throws CoreException { //'{' [class-element-list] '}' if (token == TokenNameLBRACE) { getNextToken(); @@ -1356,6 +1439,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { classElementList(); } if (token == TokenNameRBRACE) { + typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); getNextToken(); } else { throwSyntaxError("'}' expected at end of class body."); @@ -1375,8 +1459,10 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { //class-property //function-definition if (token == TokenNamefunction) { + MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult); + methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); getNextToken(); - functionDefinition(); + functionDefinition(methodDecl); } else if (token == TokenNamevar) { getNextToken(); classProperty(); @@ -1413,17 +1499,36 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } } - private void functionDefinition() throws CoreException { - functionDeclarator(); - compoundStatement(); + private void functionDefinition(MethodDeclaration methodDecl) throws CoreException { + if (astPtr == 0) { + compilationUnit.types.add(methodDecl); + } else { + AstNode node = astStack[astPtr]; + if (node instanceof TypeDeclaration) { + TypeDeclaration typeDecl = ((TypeDeclaration) node); + if (typeDecl.methods == null) { + typeDecl.methods = new AbstractMethodDeclaration[] { methodDecl }; + } else { + AbstractMethodDeclaration[] newMethods; + System.arraycopy(typeDecl.methods, 0, newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1], 1, typeDecl.methods.length); + newMethods[0] = methodDecl; + typeDecl.methods = newMethods; + } + } + } + functionDeclarator(methodDecl); + functionBody(methodDecl); } - private void functionDeclarator() throws CoreException { + private void functionDeclarator(MethodDeclaration methodDecl) throws CoreException { //identifier '(' [parameter-list] ')' if (token == TokenNameAND) { getNextToken(); } if (token == TokenNameIdentifier) { + methodDecl.sourceStart = scanner.getCurrentTokenStartPosition(); + methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition(); + methodDecl.selector = scanner.getCurrentIdentifierSource(); getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); @@ -1436,6 +1541,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { if (token != TokenNameRPAREN) { throwSyntaxError("')' expected in function declaration."); } else { + methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1; getNextToken(); } } else { @@ -1938,12 +2044,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { expressionList(); if (token != TokenNameRPAREN) { throwSyntaxError( - "')' expected after identifier '" - + new String(ident) - + "' in postfix-expression." - + "(Found token: " - + scanner.toStringAction(token) - + ")"); + "')' expected after identifier '" + new String(ident) + "' in postfix-expression." + "(Found token: " + scanner.toStringAction(token) + ")"); } } getNextToken(); @@ -2137,10 +2238,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { // '@' '&' '*' '+' '-' '~' '!' case TokenNameAT : getNextToken(); - if (token == TokenNameinclude - || token == TokenNameinclude_once - || token == TokenNamerequire - || token == TokenNamerequire_once) { + if (token == TokenNameinclude || token == TokenNameinclude_once || token == TokenNamerequire || token == TokenNamerequire_once) { statement(TokenNameAT); } else { postfixExpression(); // castExpression(); @@ -2527,4 +2625,546 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } } + public void reportSyntaxError() { //int act, int currentKind, int stateStackTop) { + + /* remember current scanner position */ + int startPos = scanner.startPosition; + int currentPos = scanner.currentPosition; + + // String[] expectings; + // String tokenName = name[symbol_index[currentKind]]; + + //fetch all "accurate" possible terminals that could recover the error + // int start, end = start = asi(stack[stateStackTop]); + // while (asr[end] != 0) + // end++; + // int length = end - start; + // expectings = new String[length]; + // if (length != 0) { + // char[] indexes = new char[length]; + // System.arraycopy(asr, start, indexes, 0, length); + // for (int i = 0; i < length; i++) { + // expectings[i] = name[symbol_index[indexes[i]]]; + // } + // } + + //if the pb is an EOF, try to tell the user that they are some + // if (tokenName.equals(UNEXPECTED_EOF)) { + // if (!this.checkAndReportBracketAnomalies(problemReporter())) { + // char[] tokenSource; + // try { + // tokenSource = this.scanner.getCurrentTokenSource(); + // } catch (Exception e) { + // tokenSource = new char[] {}; + // } + // problemReporter().parseError( + // this.scanner.startPosition, + // this.scanner.currentPosition - 1, + // tokenSource, + // tokenName, + // expectings); + // } + // } else { //the next test is HEAVILY grammar DEPENDENT. + // if ((length == 14) + // && (expectings[0] == "=") //$NON-NLS-1$ + // && (expectings[1] == "*=") //$NON-NLS-1$ + // && (expressionPtr > -1)) { + // switch(currentKind) { + // case TokenNameSEMICOLON: + // case TokenNamePLUS: + // case TokenNameMINUS: + // case TokenNameDIVIDE: + // case TokenNameREMAINDER: + // case TokenNameMULTIPLY: + // case TokenNameLEFT_SHIFT: + // case TokenNameRIGHT_SHIFT: + //// case TokenNameUNSIGNED_RIGHT_SHIFT: + // case TokenNameLESS: + // case TokenNameGREATER: + // case TokenNameLESS_EQUAL: + // case TokenNameGREATER_EQUAL: + // case TokenNameEQUAL_EQUAL: + // case TokenNameNOT_EQUAL: + // case TokenNameXOR: + // case TokenNameAND: + // case TokenNameOR: + // case TokenNameOR_OR: + // case TokenNameAND_AND: + // // the ; is not the expected token ==> it ends a statement when an expression is not ended + // problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]); + // break; + // case TokenNameRBRACE : + // problemReporter().missingSemiColon(expressionStack[expressionPtr]); + // break; + // default: + // char[] tokenSource; + // try { + // tokenSource = this.scanner.getCurrentTokenSource(); + // } catch (Exception e) { + // tokenSource = new char[] {}; + // } + // problemReporter().parseError( + // this.scanner.startPosition, + // this.scanner.currentPosition - 1, + // tokenSource, + // tokenName, + // expectings); + // this.checkAndReportBracketAnomalies(problemReporter()); + // } + // } else { + char[] tokenSource; + try { + tokenSource = this.scanner.getCurrentTokenSource(); + } catch (Exception e) { + tokenSource = new char[] { + }; + } + // problemReporter().parseError( + // this.scanner.startPosition, + // this.scanner.currentPosition - 1, + // tokenSource, + // tokenName, + // expectings); + this.checkAndReportBracketAnomalies(problemReporter()); + // } + // } + /* reset scanner where it was */ + scanner.startPosition = startPos; + scanner.currentPosition = currentPos; + } + public static final int RoundBracket = 0; + public static final int SquareBracket = 1; + public static final int CurlyBracket = 2; + public static final int BracketKinds = 3; + + protected int[] nestedMethod; //the ptr is nestedType + protected int nestedType, dimensions; + //ast stack + final static int AstStackIncrement = 100; + protected int astPtr; + protected AstNode[] astStack = new AstNode[AstStackIncrement]; + protected int astLengthPtr; + protected int[] astLengthStack; + AstNode[] noAstNodes = new AstNode[AstStackIncrement]; + + public CompilationUnitDeclaration compilationUnit; /*the result from parse()*/ + protected ReferenceContext referenceContext; + protected ProblemReporter problemReporter; + // protected CompilationResult compilationResult; + + /** + * Returns this parser's problem reporter initialized with its reference context. + * Also it is assumed that a problem is going to be reported, so initializes + * the compilation result's line positions. + */ + public ProblemReporter problemReporter() { + if (scanner.recordLineSeparator) { + compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds(); + } + problemReporter.referenceContext = referenceContext; + return problemReporter; + } + /* + * Reconsider the entire source looking for inconsistencies in {} () [] + */ + public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) { + + scanner.wasAcr = false; + boolean anomaliesDetected = false; + try { + char[] source = scanner.source; + int[] leftCount = { 0, 0, 0 }; + int[] rightCount = { 0, 0, 0 }; + int[] depths = { 0, 0, 0 }; + int[][] leftPositions = new int[][] { new int[10], new int[10], new int[10] }; + int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10] }; + int[][] rightPositions = new int[][] { new int[10], new int[10], new int[10] }; + int[][] rightDepths = new int[][] { new int[10], new int[10], new int[10] }; + scanner.currentPosition = scanner.initialPosition; //starting point (first-zero-based char) + while (scanner.currentPosition < scanner.eofPosition) { //loop for jumping over comments + try { + // ---------Consume white space and handles startPosition--------- + boolean isWhiteSpace; + do { + scanner.startPosition = scanner.currentPosition; + // if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { + // isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace(); + // } else { + if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) { + if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) { + // only record line positions we have not recorded yet + scanner.pushLineSeparator(); + } + } + isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter); + // } + } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition)); + + // -------consume token until } is found--------- + + switch (scanner.currentCharacter) { + case '{' : + { + int index = leftCount[CurlyBracket]++; + if (index == leftPositions[CurlyBracket].length) { + System.arraycopy(leftPositions[CurlyBracket], 0, (leftPositions[CurlyBracket] = new int[index * 2]), 0, index); + System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = new int[index * 2]), 0, index); + } + leftPositions[CurlyBracket][index] = scanner.startPosition; + leftDepths[CurlyBracket][index] = depths[CurlyBracket]++; + } + break; + case '}' : + { + int index = rightCount[CurlyBracket]++; + if (index == rightPositions[CurlyBracket].length) { + System.arraycopy(rightPositions[CurlyBracket], 0, (rightPositions[CurlyBracket] = new int[index * 2]), 0, index); + System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = new int[index * 2]), 0, index); + } + rightPositions[CurlyBracket][index] = scanner.startPosition; + rightDepths[CurlyBracket][index] = --depths[CurlyBracket]; + } + break; + case '(' : + { + int index = leftCount[RoundBracket]++; + if (index == leftPositions[RoundBracket].length) { + System.arraycopy(leftPositions[RoundBracket], 0, (leftPositions[RoundBracket] = new int[index * 2]), 0, index); + System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = new int[index * 2]), 0, index); + } + leftPositions[RoundBracket][index] = scanner.startPosition; + leftDepths[RoundBracket][index] = depths[RoundBracket]++; + } + break; + case ')' : + { + int index = rightCount[RoundBracket]++; + if (index == rightPositions[RoundBracket].length) { + System.arraycopy(rightPositions[RoundBracket], 0, (rightPositions[RoundBracket] = new int[index * 2]), 0, index); + System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = new int[index * 2]), 0, index); + } + rightPositions[RoundBracket][index] = scanner.startPosition; + rightDepths[RoundBracket][index] = --depths[RoundBracket]; + } + break; + case '[' : + { + int index = leftCount[SquareBracket]++; + if (index == leftPositions[SquareBracket].length) { + System.arraycopy(leftPositions[SquareBracket], 0, (leftPositions[SquareBracket] = new int[index * 2]), 0, index); + System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = new int[index * 2]), 0, index); + } + leftPositions[SquareBracket][index] = scanner.startPosition; + leftDepths[SquareBracket][index] = depths[SquareBracket]++; + } + break; + case ']' : + { + int index = rightCount[SquareBracket]++; + if (index == rightPositions[SquareBracket].length) { + System.arraycopy(rightPositions[SquareBracket], 0, (rightPositions[SquareBracket] = new int[index * 2]), 0, index); + System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] = new int[index * 2]), 0, index); + } + rightPositions[SquareBracket][index] = scanner.startPosition; + rightDepths[SquareBracket][index] = --depths[SquareBracket]; + } + break; + case '\'' : + { + if (scanner.getNextChar('\\')) { + scanner.scanEscapeCharacter(); + } else { // consume next character + scanner.unicodeAsBackSlash = false; + // if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { + // scanner.getNextUnicodeChar(); + // } else { + if (scanner.withoutUnicodePtr != 0) { + scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; + } + // } + } + scanner.getNextChar('\''); + break; + } + case '"' : // consume next character + scanner.unicodeAsBackSlash = false; + // if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { + // scanner.getNextUnicodeChar(); + // } else { + if (scanner.withoutUnicodePtr != 0) { + scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; + } + // } + while (scanner.currentCharacter != '"') { + if (scanner.currentCharacter == '\r') { + if (source[scanner.currentPosition] == '\n') + scanner.currentPosition++; + break; // the string cannot go further that the line + } + if (scanner.currentCharacter == '\n') { + break; // the string cannot go further that the line + } + if (scanner.currentCharacter == '\\') { + scanner.scanEscapeCharacter(); + } + // consume next character + scanner.unicodeAsBackSlash = false; + // if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { + // scanner.getNextUnicodeChar(); + // } else { + if (scanner.withoutUnicodePtr != 0) { + scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; + } + // } + } + break; + case '/' : + { + int test; + if ((test = scanner.getNextChar('/', '*')) == 0) { //line comment + //get the next char + if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { + //-------------unicode traitement ------------ + int c1 = 0, c2 = 0, c3 = 0, c4 = 0; + scanner.currentPosition++; + while (source[scanner.currentPosition] == 'u') { + scanner.currentPosition++; + } + if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c1 < 0 + || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c2 < 0 + || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c3 < 0 + || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c4 < 0) { //error don't care of the value + scanner.currentCharacter = 'A'; + } //something different from \n and \r + else { + scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); + } + } + while (scanner.currentCharacter != '\r' && scanner.currentCharacter != '\n') { + //get the next char + scanner.startPosition = scanner.currentPosition; + if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { + //-------------unicode traitement ------------ + int c1 = 0, c2 = 0, c3 = 0, c4 = 0; + scanner.currentPosition++; + while (source[scanner.currentPosition] == 'u') { + scanner.currentPosition++; + } + if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c1 < 0 + || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c2 < 0 + || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c3 < 0 + || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c4 < 0) { //error don't care of the value + scanner.currentCharacter = 'A'; + } //something different from \n and \r + else { + scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); + } + } + } + if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) { + if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) { + // only record line positions we have not recorded yet + scanner.pushLineSeparator(); + if (this.scanner.taskTags != null) { + this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition()); + } + } + } + break; + } + if (test > 0) { //traditional and annotation comment + boolean star = false; + // consume next character + scanner.unicodeAsBackSlash = false; + // if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { + // scanner.getNextUnicodeChar(); + // } else { + if (scanner.withoutUnicodePtr != 0) { + scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; + } + // } + if (scanner.currentCharacter == '*') { + star = true; + } + //get the next char + if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { + //-------------unicode traitement ------------ + int c1 = 0, c2 = 0, c3 = 0, c4 = 0; + scanner.currentPosition++; + while (source[scanner.currentPosition] == 'u') { + scanner.currentPosition++; + } + if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c1 < 0 + || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c2 < 0 + || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c3 < 0 + || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c4 < 0) { //error don't care of the value + scanner.currentCharacter = 'A'; + } //something different from * and / + else { + scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); + } + } + //loop until end of comment */ + while ((scanner.currentCharacter != '/') || (!star)) { + star = scanner.currentCharacter == '*'; + //get next char + if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { + //-------------unicode traitement ------------ + int c1 = 0, c2 = 0, c3 = 0, c4 = 0; + scanner.currentPosition++; + while (source[scanner.currentPosition] == 'u') { + scanner.currentPosition++; + } + if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c1 < 0 + || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c2 < 0 + || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c3 < 0 + || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + || c4 < 0) { //error don't care of the value + scanner.currentCharacter = 'A'; + } //something different from * and / + else { + scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); + } + } + } + if (this.scanner.taskTags != null) { + this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition()); + } + break; + } + break; + } + default : + if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) { + scanner.scanIdentifierOrKeyword(false); + break; + } + if (Character.isDigit(scanner.currentCharacter)) { + scanner.scanNumber(false); + break; + } + } + //-----------------end switch while try-------------------- + } catch (IndexOutOfBoundsException e) { + break; // read until EOF + } catch (InvalidInputException e) { + return false; // no clue + } + } + if (scanner.recordLineSeparator) { + // compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds(); + } + + // check placement anomalies against other kinds of brackets + for (int kind = 0; kind < BracketKinds; kind++) { + for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) { + int start = leftPositions[kind][leftIndex]; // deepest first + // find matching closing bracket + int depth = leftDepths[kind][leftIndex]; + int end = -1; + for (int i = 0; i < rightCount[kind]; i++) { + int pos = rightPositions[kind][i]; + // want matching bracket further in source with same depth + if ((pos > start) && (depth == rightDepths[kind][i])) { + end = pos; + break; + } + } + if (end < 0) { // did not find a good closing match + problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); + return true; + } + // check if even number of opening/closing other brackets in between this pair of brackets + int balance = 0; + for (int otherKind = 0;(balance == 0) && (otherKind < BracketKinds); otherKind++) { + for (int i = 0; i < leftCount[otherKind]; i++) { + int pos = leftPositions[otherKind][i]; + if ((pos > start) && (pos < end)) + balance++; + } + for (int i = 0; i < rightCount[otherKind]; i++) { + int pos = rightPositions[otherKind][i]; + if ((pos > start) && (pos < end)) + balance--; + } + if (balance != 0) { + problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); //bracket anomaly + return true; + } + } + } + // too many opening brackets ? + for (int i = rightCount[kind]; i < leftCount[kind]; i++) { + anomaliesDetected = true; + problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i - 1], referenceContext, compilationUnit.compilationResult); + } + // too many closing brackets ? + for (int i = leftCount[kind]; i < rightCount[kind]; i++) { + anomaliesDetected = true; + problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, compilationUnit.compilationResult); + } + if (anomaliesDetected) + return true; + } + + return anomaliesDetected; + } catch (ArrayStoreException e) { // jdk1.2.2 jit bug + return anomaliesDetected; + } catch (NullPointerException e) { // jdk1.2.2 jit bug + return anomaliesDetected; + } + } + + protected void pushOnAstLengthStack(int pos) { + try { + astLengthStack[++astLengthPtr] = pos; + } catch (IndexOutOfBoundsException e) { + int oldStackLength = astLengthStack.length; + int[] oldPos = astLengthStack; + astLengthStack = new int[oldStackLength + StackIncrement]; + System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength); + astLengthStack[astLengthPtr] = pos; + } + } + + protected void pushOnAstStack(AstNode node) { + /*add a new obj on top of the ast stack + astPtr points on the top*/ + + try { + astStack[++astPtr] = node; + } catch (IndexOutOfBoundsException e) { + int oldStackLength = astStack.length; + AstNode[] oldStack = astStack; + astStack = new AstNode[oldStackLength + AstStackIncrement]; + System.arraycopy(oldStack, 0, astStack, 0, oldStackLength); + astPtr = oldStackLength; + astStack[astPtr] = node; + } + + try { + astLengthStack[++astLengthPtr] = 1; + } catch (IndexOutOfBoundsException e) { + int oldStackLength = astLengthStack.length; + int[] oldPos = astLengthStack; + astLengthStack = new int[oldStackLength + AstStackIncrement]; + System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength); + astLengthStack[astLengthPtr] = 1; + } + } } \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/ParserBasicInformation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/ParserBasicInformation.java new file mode 100644 index 0000000..e5c59b5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/ParserBasicInformation.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.parser; + +/*An interface that contains static declarations for some basic information + about the parser such as the number of rules in the grammar, the starting state, etc...*/ + +public interface ParserBasicInformation { + + public final static int + NT_OFFSET = 308, + SCOPE_UBOUND = -1, + SCOPE_SIZE = 0, + LA_STATE_OFFSET = 17759, + MAX_LA = 1, + NUM_RULES = 437, + NUM_TERMINALS = 104, + NUM_NON_TERMINALS = 204, + NUM_SYMBOLS = 308, + START_STATE = 16034, + EOFT_SYMBOL = 114, + EOLT_SYMBOL = 105, + ACCEPT_ACTION = 17758, + ERROR_ACTION = 17759; +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/RecoveredElement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/RecoveredElement.java new file mode 100644 index 0000000..38ba5e5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/RecoveredElement.java @@ -0,0 +1,319 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.parser; + +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; +import net.sourceforge.phpeclipse.internal.compiler.ast.Block; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.Statement; + +/** + * Internal structure for parsing recovery + */ + +public class RecoveredElement { + + public RecoveredElement parent; + public int bracketBalance; + public boolean foundOpeningBrace; + protected Parser recoveringParser; +public RecoveredElement(RecoveredElement parent, int bracketBalance){ + this(parent, bracketBalance, null); +} +public RecoveredElement(RecoveredElement parent, int bracketBalance, Parser parser){ + this.parent = parent; + this.bracketBalance = bracketBalance; + this.recoveringParser = parser; +} +/* + * Record a method declaration + */ +//public RecoveredElement add(AbstractMethodDeclaration methodDeclaration, int bracketBalance) { +// +// /* default behavior is to delegate recording to parent if any */ +// if (parent == null) { +// return this; // ignore +// } else { +// this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(methodDeclaration.declarationSourceStart - 1)); +// return this.parent.add(methodDeclaration, bracketBalance); +// } +//} +/* + * Record a nested block declaration + */ +public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalance) { + + /* default behavior is to delegate recording to parent if any */ + if (parent == null) { + return this; // ignore + } else { + this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(nestedBlockDeclaration.sourceStart - 1)); + return this.parent.add(nestedBlockDeclaration, bracketBalance); + } +} +/* + * Record a field declaration + */ +//public RecoveredElement add(FieldDeclaration fieldDeclaration, int bracketBalance) { +// +// /* default behavior is to delegate recording to parent if any */ +// if (parent == null) { +// return this; // ignore +// } else { +// this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(fieldDeclaration.declarationSourceStart - 1)); +// return this.parent.add(fieldDeclaration, bracketBalance); +// } +//} +///* +// * Record an import reference +// */ +//public RecoveredElement add(ImportReference importReference, int bracketBalance){ +// +// /* default behavior is to delegate recording to parent if any */ +// if (parent == null) { +// return this; // ignore +// } else { +// this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(importReference.declarationSourceStart - 1)); +// return this.parent.add(importReference, bracketBalance); +// } +//} +///* +// * Record a local declaration +// */ +//public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalance) { +// +// /* default behavior is to delegate recording to parent if any */ +// if (parent == null) { +// return this; // ignore +// } else { +// this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(localDeclaration.declarationSourceStart - 1)); +// return this.parent.add(localDeclaration, bracketBalance); +// } +//} +/* + * Record a statement + */ +public RecoveredElement add(Statement statement, int bracketBalance) { + + /* default behavior is to delegate recording to parent if any */ + if (parent == null) { + return this; // ignore + } else { + this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(statement.sourceStart - 1)); + return this.parent.add(statement, bracketBalance); + } +} +/* + * Record a type declaration + */ +//public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalance){ +// +// /* default behavior is to delegate recording to parent if any */ +// if (parent == null) { +// return this; // ignore +// } else { +// this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(typeDeclaration.declarationSourceStart - 1)); +// return this.parent.add(typeDeclaration, bracketBalance); +// } +//} +/* + * Answer the depth of this element, considering the parent link. + */ +public int depth(){ + int depth = 0; + RecoveredElement current = this; + while ((current = current.parent) != null) depth++; + return depth; +} +/* + * Answer the enclosing method node, or null if none + */ +//public RecoveredInitializer enclosingInitializer(){ +// RecoveredElement current = this; +// while (current != null){ +// if (current instanceof RecoveredInitializer){ +// return (RecoveredInitializer) current; +// } +// current = current.parent; +// } +// return null; +//} +/* + * Answer the enclosing method node, or null if none + */ +//public RecoveredMethod enclosingMethod(){ +// RecoveredElement current = this; +// while (current != null){ +// if (current instanceof RecoveredMethod){ +// return (RecoveredMethod) current; +// } +// current = current.parent; +// } +// return null; +//} +/* + * Answer the enclosing type node, or null if none + */ +//public RecoveredType enclosingType(){ +// RecoveredElement current = this; +// while (current != null){ +// if (current instanceof RecoveredType){ +// return (RecoveredType) current; +// } +// current = current.parent; +// } +// return null; +//} +/* + * Answer the closest specified parser + */ +public Parser parser(){ + RecoveredElement current = this; + while (current != null){ + if (current.recoveringParser != null){ + return current.recoveringParser; + } + current = current.parent; + } + return null; +} +/* + * Answer the associated parsed structure + */ +public AstNode parseTree(){ + return null; +} +/* + * Iterate the enclosing blocks and tag them so as to preserve their content + */ +//public void preserveEnclosingBlocks(){ +// RecoveredElement current = this; +// while (current != null){ +// if (current instanceof RecoveredBlock){ +// ((RecoveredBlock)current).preserveContent = true; +// } +// if (current instanceof RecoveredType){ // for anonymous types +// ((RecoveredType)current).preserveContent = true; +// } +// current = current.parent; +// } +//} +/* + * Answer the position of the previous line end if + * there is nothing but spaces in between it and the + * line end. Used to trim spaces on unclosed elements. + */ +public int previousAvailableLineEnd(int position){ + + Parser parser = this.parser(); + if (parser == null) return position; + + Scanner scanner = parser.scanner; + if (scanner.lineEnds == null) return position; + + int index = scanner.getLineNumber(position); + if (index < 2) return position; + int previousLineEnd = scanner.lineEnds[index-2]; + + char[] source = scanner.source; + for (int i = previousLineEnd+1; i < position; i++){ + if (!(source[i] == ' ' || source[i] == '\t')) return position; + } + return previousLineEnd; +} +/* + * Answer the very source end of the corresponding parse node + */ +public int sourceEnd(){ + return 0; +} +protected String tabString(int tab) { + StringBuffer result = new StringBuffer(); + for (int i = tab; i > 0; i--) { + result.append(" "); //$NON-NLS-1$ + } + return result.toString(); +} +/* + * Answer the top node + */ +public RecoveredElement topElement(){ + RecoveredElement current = this; + while (current.parent != null){ + current = current.parent; + } + return current; +} +public String toString() { + return toString(0); +} +public String toString(int tab) { + return super.toString(); +} +/* + * Answer the enclosing type node, or null if none + */ +//public RecoveredType type(){ +// RecoveredElement current = this; +// while (current != null){ +// if (current instanceof RecoveredType){ +// return (RecoveredType) current; +// } +// current = current.parent; +// } +// return null; +//} +/* + * Update the bodyStart of the corresponding parse node + */ +public void updateBodyStart(int bodyStart){ + this.foundOpeningBrace = true; +} +/* + * Update the corresponding parse node from parser state which + * is about to disappear because of restarting recovery + */ +public void updateFromParserState(){ +} +/* + * A closing brace got consumed, might have closed the current element, + * in which case both the currentElement is exited + */ +public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){ + if ((--bracketBalance <= 0) && (parent != null)){ + this.updateSourceEndIfNecessary(braceEnd); + return parent; + } + return this; +} +/* + * An opening brace got consumed, might be the expected opening one of the current element, + * in which case the bodyStart is updated. + */ +public RecoveredElement updateOnOpeningBrace(int braceEnd){ + + if (bracketBalance++ == 0){ + this.updateBodyStart(braceEnd + 1); + return this; + } + return null; // no update is necessary +} +/* + * Final update the corresponding parse node + */ +public void updateParseTree(){ +} +/* + * Update the declarationSourceEnd of the corresponding parse node + */ +public void updateSourceEndIfNecessary(int sourceEnd){ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java index 2206c00..1ff0619 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import net.sourceforge.phpdt.core.compiler.CharOperation; import net.sourceforge.phpdt.core.compiler.IScanner; import net.sourceforge.phpdt.core.compiler.ITerminalSymbols; import net.sourceforge.phpdt.core.compiler.InvalidInputException; @@ -152,7 +153,16 @@ public class Scanner implements IScanner, ITerminalSymbols { public static final int SquareBracket = 1; public static final int CurlyBracket = 2; public static final int BracketKinds = 3; - + + // task tag support + public char[][] foundTaskTags = null; + public char[][] foundTaskMessages; + public char[][] foundTaskPriorities = null; + public int[][] foundTaskPositions; + public int foundTaskCount = 0; + public char[][] taskTags = null; + public char[][] taskPriorities = null; + public static final boolean DEBUG = false; public Scanner() { @@ -3518,4 +3528,177 @@ public class Scanner implements IScanner, ITerminalSymbols { } currentLine = null; } + + + public final void scanEscapeCharacter() throws InvalidInputException { + // the string with "\\u" is a legal string of two chars \ and u + //thus we use a direct access to the source (for regular cases). + + if (unicodeAsBackSlash) { + // consume next character + unicodeAsBackSlash = false; +// if (((currentCharacter = source[currentPosition++]) == '\\') && (source[currentPosition] == 'u')) { +// getNextUnicodeChar(); +// } else { + if (withoutUnicodePtr != 0) { + withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter; +// } + } + } else + currentCharacter = source[currentPosition++]; + switch (currentCharacter) { + case 'b' : + currentCharacter = '\b'; + break; + case 't' : + currentCharacter = '\t'; + break; + case 'n' : + currentCharacter = '\n'; + break; + case 'f' : + currentCharacter = '\f'; + break; + case 'r' : + currentCharacter = '\r'; + break; + case '\"' : + currentCharacter = '\"'; + break; + case '\'' : + currentCharacter = '\''; + break; + case '\\' : + currentCharacter = '\\'; + break; + default : + // -----------octal escape-------------- + // OctalDigit + // OctalDigit OctalDigit + // ZeroToThree OctalDigit OctalDigit + + int number = Character.getNumericValue(currentCharacter); + if (number >= 0 && number <= 7) { + boolean zeroToThreeNot = number > 3; + if (Character.isDigit(currentCharacter = source[currentPosition++])) { + int digit = Character.getNumericValue(currentCharacter); + if (digit >= 0 && digit <= 7) { + number = (number * 8) + digit; + if (Character.isDigit(currentCharacter = source[currentPosition++])) { + if (zeroToThreeNot) {// has read \NotZeroToThree OctalDigit Digit --> ignore last character + currentPosition--; + } else { + digit = Character.getNumericValue(currentCharacter); + if (digit >= 0 && digit <= 7){ // has read \ZeroToThree OctalDigit OctalDigit + number = (number * 8) + digit; + } else {// has read \ZeroToThree OctalDigit NonOctalDigit --> ignore last character + currentPosition--; + } + } + } else { // has read \OctalDigit NonDigit--> ignore last character + currentPosition--; + } + } else { // has read \OctalDigit NonOctalDigit--> ignore last character + currentPosition--; + } + } else { // has read \OctalDigit --> ignore last character + currentPosition--; + } + if (number > 255) + throw new InvalidInputException(INVALID_ESCAPE); + currentCharacter = (char) number; + } else + throw new InvalidInputException(INVALID_ESCAPE); + } + } + +// chech presence of task: tags +public void checkTaskTag(int commentStart, int commentEnd) { + + // only look for newer task: tags + if (this.foundTaskCount > 0 && this.foundTaskPositions[this.foundTaskCount-1][0] >= commentStart) { + return; + } + int foundTaskIndex = this.foundTaskCount; + nextChar: for (int i = commentStart; i < commentEnd && i < this.eofPosition; i++) { + + char[] tag = null; + char[] priority = null; + + // check for tag occurrence + nextTag: for (int itag = 0; itag < this.taskTags.length; itag++){ + tag = this.taskTags[itag]; + priority = + this.taskPriorities != null && itag < this.taskPriorities.length ? + this.taskPriorities[itag] : + null; + int tagLength = tag.length; + for (int t = 0; t < tagLength; t++){ + if (this.source[i+t] != tag[t]) continue nextTag; + } + + if (this.foundTaskTags == null){ + this.foundTaskTags = new char[5][]; + this.foundTaskMessages = new char[5][]; + this.foundTaskPriorities = new char[5][]; + this.foundTaskPositions = new int[5][]; + } else if (this.foundTaskCount == this.foundTaskTags.length) { + System.arraycopy(this.foundTaskTags, 0, this.foundTaskTags = new char[this.foundTaskCount*2][], 0, this.foundTaskCount); + System.arraycopy(this.foundTaskMessages, 0, this.foundTaskMessages = new char[this.foundTaskCount*2][], 0, this.foundTaskCount); + System.arraycopy(this.foundTaskPriorities, 0, this.foundTaskPriorities = new char[this.foundTaskCount*2][], 0, this.foundTaskCount); + System.arraycopy(this.foundTaskPositions, 0, this.foundTaskPositions = new int[this.foundTaskCount*2][], 0, this.foundTaskCount); + } + this.foundTaskTags[this.foundTaskCount] = tag; + this.foundTaskPriorities[this.foundTaskCount] = priority; + this.foundTaskPositions[this.foundTaskCount] = new int[]{ i, i+tagLength-1 }; + this.foundTaskMessages[this.foundTaskCount] = CharOperation.NO_CHAR; + this.foundTaskCount++; + + i += tagLength-1; // will be incremented when looping + } + } + + for (int i = foundTaskIndex; i < this.foundTaskCount; i++) { + // retrieve message start and end positions + int msgStart = this.foundTaskPositions[i][0] + this.foundTaskTags[i].length; + int max_value = i + 1 < this.foundTaskCount ? this.foundTaskPositions[i + 1][0] - 1 : commentEnd-1; // at most beginning of next task + if (max_value < msgStart) max_value = msgStart; // would only occur if tag is before EOF. + int end = -1; + char c; + + for (int j = msgStart; j < max_value; j++){ + if ((c = this.source[j]) == '\n' || c == '\r'){ + end = j-1; + break; + } + } + + if (end == -1){ + for (int j = max_value; j > msgStart; j--){ + if ((c = this.source[j]) == '*') { + end = j-1; + break; + } + } + if (end == -1) end = max_value; + } + + if (msgStart == end) continue; // empty + + // trim the message + while (CharOperation.isWhitespace(source[end]) && msgStart <= end) end--; + while (CharOperation.isWhitespace(source[msgStart]) && msgStart <= end) msgStart++; + + // update the end position of the task + this.foundTaskPositions[i][1] = end; + + // get the message source + final int messageLength = end-msgStart+1; + char[] message = new char[messageLength]; + + System.arraycopy(source, msgStart, message, 0, messageLength); + this.foundTaskMessages[i] = message; + } +} + } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/SourceTypeConverter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/SourceTypeConverter.java new file mode 100644 index 0000000..732407a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/SourceTypeConverter.java @@ -0,0 +1,393 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.parser; + +/** + * Converter from source element type to parsed compilation unit. + * + * Limitation: + * | The source element field does not carry any information for its constant part, thus + * | the converted parse tree will not include any field initializations. + * | Therefore, any binary produced by compiling against converted source elements will + * | not take advantage of remote field constant inlining. + * | Given the intended purpose of the conversion is to resolve references, this is not + * | a problem. + * + */ + +import java.util.ArrayList; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.env.ISourceField; +import net.sourceforge.phpdt.internal.compiler.env.ISourceMethod; +import net.sourceforge.phpdt.internal.compiler.env.ISourceType; +import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; +import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.Argument; +import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayQualifiedTypeReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayTypeReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.MemberTypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedTypeReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeReference; + +public class SourceTypeConverter implements CompilerModifiers { + + private boolean needFieldInitialization; + private CompilationUnitDeclaration unit; + private UnitParser parser; + private ProblemReporter problemReporter; + + private SourceTypeConverter(boolean needFieldInitialization, ProblemReporter problemReporter) { + this.needFieldInitialization = needFieldInitialization; + this.problemReporter = problemReporter; + } + + /* + * Convert a set of source element types into a parsed compilation unit declaration + * The argument types are then all grouped in the same unit. The argument types must + * at least contain one type. + * Can optionally ignore fields & methods or member types or field initialization + */ + public static CompilationUnitDeclaration buildCompilationUnit( + ISourceType[] sourceTypes, + boolean needFieldsAndMethods, + boolean needMemberTypes, + boolean needFieldInitialization, + ProblemReporter problemReporter, + CompilationResult compilationResult) { + + return + new SourceTypeConverter(needFieldInitialization, problemReporter).convert( + sourceTypes, + needFieldsAndMethods, + needMemberTypes, + compilationResult); + } + + /* + * Convert a set of source element types into a parsed compilation unit declaration + * The argument types are then all grouped in the same unit. The argument types must + * at least contain one type. + */ + private CompilationUnitDeclaration convert( + ISourceType[] sourceTypes, + boolean needFieldsAndMethods, + boolean needMemberTypes, + CompilationResult compilationResult) { + ISourceType sourceType = sourceTypes[0]; + if (sourceType.getName() == null) + return null; // do a basic test that the sourceType is valid + + this.unit = new CompilationUnitDeclaration(problemReporter, compilationResult, 0); + // not filled at this point + + /* only positions available */ + int start = sourceType.getNameSourceStart(); + int end = sourceType.getNameSourceEnd(); + + /* convert package and imports */ + if (sourceType.getPackageName() != null + && sourceType.getPackageName().length > 0) + // if its null then it is defined in the default package + this.unit.currentPackage = + createImportReference(sourceType.getPackageName(), start, end); + char[][] importNames = sourceType.getImports(); + int importCount = importNames == null ? 0 : importNames.length; + this.unit.imports = new ImportReference[importCount]; + for (int i = 0; i < importCount; i++) + this.unit.imports[i] = createImportReference(importNames[i], start, end); + /* convert type(s) */ + int typeCount = sourceTypes.length; + this.unit.types = new ArrayList(typeCount); + for (int i = 0; i < typeCount; i++) { + this.unit.types.set(i, + convert(sourceTypes[i], needFieldsAndMethods, needMemberTypes, compilationResult)); +// this.unit.types[i] = +// convert(sourceTypes[i], needFieldsAndMethods, needMemberTypes, compilationResult); + } + return this.unit; + } + + /* + * Convert a field source element into a parsed field declaration + */ + private FieldDeclaration convert(ISourceField sourceField, TypeDeclaration type) { + + FieldDeclaration field = new FieldDeclaration(); + + int start = sourceField.getNameSourceStart(); + int end = sourceField.getNameSourceEnd(); + + field.name = sourceField.getName(); + field.sourceStart = start; + field.sourceEnd = end; + field.type = createTypeReference(sourceField.getTypeName(), start, end); + field.declarationSourceStart = sourceField.getDeclarationSourceStart(); + field.declarationSourceEnd = sourceField.getDeclarationSourceEnd(); + field.modifiers = sourceField.getModifiers(); + + if (this.needFieldInitialization) { + /* conversion of field constant */ + char[] initializationSource = sourceField.getInitializationSource(); + if (initializationSource != null) { + if (this.parser == null) { + this.parser = + new UnitParser( + this.problemReporter); +// true, +// this.problemReporter.options.sourceLevel >= CompilerOptions.JDK1_4); + } + this.parser.parse(field, type, this.unit, initializationSource); + } + } + + return field; + } + + /* + * Convert a method source element into a parsed method/constructor declaration + */ + private AbstractMethodDeclaration convert(ISourceMethod sourceMethod, CompilationResult compilationResult) { + + AbstractMethodDeclaration method; + + /* only source positions available */ + int start = sourceMethod.getNameSourceStart(); + int end = sourceMethod.getNameSourceEnd(); + + if (sourceMethod.isConstructor()) { + ConstructorDeclaration decl = new ConstructorDeclaration(compilationResult); + decl.isDefaultConstructor = false; + method = decl; + } else { + MethodDeclaration decl = new MethodDeclaration(compilationResult); + /* convert return type */ + decl.returnType = + createTypeReference(sourceMethod.getReturnTypeName(), start, end); + method = decl; + } + method.selector = sourceMethod.getSelector(); + method.modifiers = sourceMethod.getModifiers(); + method.sourceStart = start; + method.sourceEnd = end; + method.declarationSourceStart = sourceMethod.getDeclarationSourceStart(); + method.declarationSourceEnd = sourceMethod.getDeclarationSourceEnd(); + + /* convert arguments */ + char[][] argumentTypeNames = sourceMethod.getArgumentTypeNames(); + char[][] argumentNames = sourceMethod.getArgumentNames(); + int argumentCount = argumentTypeNames == null ? 0 : argumentTypeNames.length; + long position = (long) start << 32 + end; + method.arguments = new Argument[argumentCount]; + for (int i = 0; i < argumentCount; i++) { + method.arguments[i] = + new Argument( + argumentNames[i], + position, + createTypeReference(argumentTypeNames[i], start, end), + AccDefault); + // do not care whether was final or not + } + + /* convert thrown exceptions */ + char[][] exceptionTypeNames = sourceMethod.getExceptionTypeNames(); + int exceptionCount = exceptionTypeNames == null ? 0 : exceptionTypeNames.length; + method.thrownExceptions = new TypeReference[exceptionCount]; + for (int i = 0; i < exceptionCount; i++) { + method.thrownExceptions[i] = + createTypeReference(exceptionTypeNames[i], start, end); + } + return method; + } + + /* + * Convert a source element type into a parsed type declaration + * + * Can optionally ignore fields & methods + */ + private TypeDeclaration convert( + ISourceType sourceType, + boolean needFieldsAndMethods, + boolean needMemberTypes, + CompilationResult compilationResult) { + /* create type declaration - can be member type */ + TypeDeclaration type; + if (sourceType.getEnclosingType() == null) { + type = new TypeDeclaration(compilationResult); + } else { + type = new MemberTypeDeclaration(compilationResult); + } + type.name = sourceType.getName(); + int start, end; // only positions available + type.sourceStart = start = sourceType.getNameSourceStart(); + type.sourceEnd = end = sourceType.getNameSourceEnd(); + type.modifiers = sourceType.getModifiers(); + type.declarationSourceStart = sourceType.getDeclarationSourceStart(); + type.declarationSourceEnd = sourceType.getDeclarationSourceEnd(); + type.bodyEnd = type.declarationSourceEnd; + + /* set superclass and superinterfaces */ + if (sourceType.getSuperclassName() != null) + type.superclass = + createTypeReference(sourceType.getSuperclassName(), start, end); + char[][] interfaceNames = sourceType.getInterfaceNames(); + int interfaceCount = interfaceNames == null ? 0 : interfaceNames.length; + type.superInterfaces = new TypeReference[interfaceCount]; + for (int i = 0; i < interfaceCount; i++) { + type.superInterfaces[i] = createTypeReference(interfaceNames[i], start, end); + } + /* convert member types */ + if (needMemberTypes) { + ISourceType[] sourceMemberTypes = sourceType.getMemberTypes(); + int sourceMemberTypeCount = + sourceMemberTypes == null ? 0 : sourceMemberTypes.length; + type.memberTypes = new MemberTypeDeclaration[sourceMemberTypeCount]; + for (int i = 0; i < sourceMemberTypeCount; i++) { + type.memberTypes[i] = + (MemberTypeDeclaration) convert(sourceMemberTypes[i], + needFieldsAndMethods, + true, + compilationResult); + } + } + /* convert fields and methods */ + if (needFieldsAndMethods) { + /* convert fields */ + ISourceField[] sourceFields = sourceType.getFields(); + int sourceFieldCount = sourceFields == null ? 0 : sourceFields.length; + type.fields = new FieldDeclaration[sourceFieldCount]; + for (int i = 0; i < sourceFieldCount; i++) { + type.fields[i] = convert(sourceFields[i], type); + } + + /* convert methods - need to add default constructor if necessary */ + ISourceMethod[] sourceMethods = sourceType.getMethods(); + int sourceMethodCount = sourceMethods == null ? 0 : sourceMethods.length; + + /* source type has a constructor ? */ + /* by default, we assume that one is needed. */ + int neededCount = 0; + if (!type.isInterface()) { + neededCount = 1; + for (int i = 0; i < sourceMethodCount; i++) { + if (sourceMethods[i].isConstructor()) { + neededCount = 0; + // Does not need the extra constructor since one constructor already exists. + break; + } + } + } + type.methods = new AbstractMethodDeclaration[sourceMethodCount + neededCount]; + if (neededCount != 0) { // add default constructor in first position + type.methods[0] = type.createsInternalConstructor(false, false); + } + boolean isInterface = type.isInterface(); + for (int i = 0; i < sourceMethodCount; i++) { + AbstractMethodDeclaration method =convert(sourceMethods[i], compilationResult); + if (isInterface || method.isAbstract()) { // fix-up flag + method.modifiers |= AccSemicolonBody; + } + type.methods[neededCount + i] = method; + } + } + return type; + } + + /* + * Build an import reference from an import name, e.g. java.lang.* + */ + private ImportReference createImportReference( + char[] importName, + int start, + int end) { + + /* count identifiers */ + int max = importName.length; + int identCount = 0; + for (int i = 0; i < max; i++) { + if (importName[i] == '.') + identCount++; + } + /* import on demand? */ + boolean onDemand = importName[max - 1] == '*'; + if (!onDemand) + identCount++; // one more ident than dots + + long[] positions = new long[identCount]; + long position = (long) start << 32 + end; + for (int i = 0; i < identCount; i++) { + positions[i] = position; + } + return new ImportReference( + CharOperation.splitOn('.', importName, 0, max - (onDemand ? 2 : 0)), + positions, + onDemand); + } + + /* + * Build a type reference from a readable name, e.g. java.lang.Object[][] + */ + private TypeReference createTypeReference( + char[] typeSignature, + int start, + int end) { + + /* count identifiers and dimensions */ + int max = typeSignature.length; + int dimStart = max; + int dim = 0; + int identCount = 1; + for (int i = 0; i < max; i++) { + switch (typeSignature[i]) { + case '[' : + if (dim == 0) + dimStart = i; + dim++; + break; + case '.' : + identCount++; + break; + } + } + /* rebuild identifiers and dimensions */ + if (identCount == 1) { // simple type reference + if (dim == 0) { + return new SingleTypeReference(typeSignature, (((long) start )<< 32) + end); + } else { + char[] identifier = new char[dimStart]; + System.arraycopy(typeSignature, 0, identifier, 0, dimStart); + return new ArrayTypeReference(identifier, dim, (((long) start) << 32) + end); + } + } else { // qualified type reference + long[] positions = new long[identCount]; + long pos = (((long) start) << 32) + end; + for (int i = 0; i < identCount; i++) { + positions[i] = pos; + } + char[][] identifiers = + CharOperation.splitOn('.', typeSignature, 0, dimStart); + if (dim == 0) { + return new QualifiedTypeReference(identifiers, positions); + } else { + return new ArrayQualifiedTypeReference(identifiers, dim, positions); + } + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/UnitParser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/UnitParser.java new file mode 100644 index 0000000..2da0761 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/UnitParser.java @@ -0,0 +1,483 @@ +package net.sourceforge.phpdt.internal.compiler.parser; + +import net.sourceforge.phpdt.core.IJavaModelMarker; +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpdt.internal.core.BasicCompilationUnit; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.Initializer; +import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; + +/** + * @author jsurfer + * + * + */ +public class UnitParser extends Parser { + + public UnitParser(ProblemReporter problemReporter) { //, boolean optimizeStringLiterals, boolean assertMode) { + super(); + nestedMethod = new int[30]; + this.problemReporter = problemReporter; + // this.optimizeStringLiterals = optimizeStringLiterals; + // this.assertMode = assertMode; + // this.initializeScanner(); + astLengthStack = new int[50]; + // expressionLengthStack = new int[30]; + // intStack = new int[50]; + // identifierStack = new char[30][]; + // identifierLengthStack = new int[30]; + // nestedMethod = new int[30]; + // realBlockStack = new int[30]; + // identifierPositionStack = new long[30]; + // variablesCounter = new int[30]; + } + + public void goForConstructorBody() { + //tells the scanner to go for compilation unit parsing + + firstToken = TokenNameEQUAL_EQUAL; + scanner.recordLineSeparator = false; + } + public void goForExpression() { + //tells the scanner to go for an expression parsing + + firstToken = TokenNameREMAINDER; + scanner.recordLineSeparator = false; + } + public void goForCompilationUnit() { + //tells the scanner to go for compilation unit parsing + + firstToken = TokenNamePLUS_PLUS; + scanner.linePtr = -1; + scanner.foundTaskCount = 0; + scanner.recordLineSeparator = true; + // scanner.currentLine= null; + } + public void goForInitializer() { + //tells the scanner to go for initializer parsing + + firstToken = TokenNameRIGHT_SHIFT; + scanner.recordLineSeparator = false; + } + public void goForMethodBody() { + //tells the scanner to go for method body parsing + + firstToken = TokenNameMINUS_MINUS; + scanner.recordLineSeparator = false; + } + public void initialize() { + super.initialize(); + //positionning the parser for a new compilation unit + //avoiding stack reallocation and all that.... + // astPtr = -1; + // astLengthPtr = -1; + // expressionPtr = -1; + // expressionLengthPtr = -1; + // identifierPtr = -1; + // identifierLengthPtr = -1; + // intPtr = -1; + // nestedMethod[nestedType = 0] = 0; // need to reset for further reuse + // variablesCounter[nestedType] = 0; + // dimensions = 0 ; + // realBlockPtr = -1; + // endStatementPosition = 0; + + //remove objects from stack too, while the same parser/compiler couple is + //re-used between two compilations .... + + // int astLength = astStack.length; + // if (noAstNodes.length < astLength){ + // noAstNodes = new AstNode[astLength]; + // //System.out.println("Resized AST stacks : "+ astLength); + // + // } + // System.arraycopy(noAstNodes, 0, astStack, 0, astLength); + // + // int expressionLength = expressionStack.length; + // if (noExpressions.length < expressionLength){ + // noExpressions = new Expression[expressionLength]; + // //System.out.println("Resized EXPR stacks : "+ expressionLength); + // } + // System.arraycopy(noExpressions, 0, expressionStack, 0, expressionLength); + + // reset scanner state + scanner.commentPtr = -1; + scanner.foundTaskCount = 0; + scanner.eofPosition = Integer.MAX_VALUE; + + // resetModifiers(); + // + // // recovery + // lastCheckPoint = -1; + // currentElement = null; + // restartRecovery = false; + // hasReportedError = false; + // recoveredStaticInitializerStart = 0; + // lastIgnoredToken = -1; + // lastErrorEndPosition = -1; + // listLength = 0; + } + + // A P I + + public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult) { + // parses a compilation unit and manages error handling (even bugs....) + + CompilationUnitDeclaration unit; + try { + /* automaton initialization */ + initialize(); + goForCompilationUnit(); + + /* scanner initialization */ + scanner.setSource(sourceUnit.getContents()); + + /* unit creation */ + referenceContext = + compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length); + // TODO TypeDeclaration test + // TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult); + // typeDecl.sourceStart = 0; + // typeDecl.sourceEnd = 10; + // typeDecl.name = new char[]{'t', 'e','s','t'}; + // this.compilationUnit.types = new ArrayList(); + // this.compilationUnit.types.add(typeDecl); + /* run automaton */ + super.parse(); +// // TODO jsurfer start +// if (sourceUnit instanceof BasicCompilationUnit) { +// storeProblemsFor(((BasicCompilationUnit)sourceUnit).getResource(), compilationResult.getAllProblems()); +// } +// // jsurfer end + } catch (CoreException e) { + e.printStackTrace(); + } finally { + unit = compilationUnit; + compilationUnit = null; // reset parser + } + return unit; + } + /** + * Creates a marker from each problem and adds it to the resource. + * The marker is as follows: + * - its type is T_PROBLEM + * - its plugin ID is the JavaBuilder's plugin ID + * - its message is the problem's message + * - its priority reflects the severity of the problem + * - its range is the problem's range + * - it has an extra attribute "ID" which holds the problem's id + */ + protected void storeProblemsFor(IResource resource, IProblem[] problems) throws CoreException { + if (resource == null || problems == null || problems.length == 0) + return; + + for (int i = 0, l = problems.length; i < l; i++) { + IProblem problem = problems[i]; + int id = problem.getID(); + if (id != IProblem.Task) { + IMarker marker = resource.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); + marker.setAttributes( + new String[] { + IMarker.MESSAGE, + IMarker.SEVERITY, + IJavaModelMarker.ID, + IMarker.CHAR_START, + IMarker.CHAR_END, + IMarker.LINE_NUMBER, + IJavaModelMarker.ARGUMENTS }, + new Object[] { + problem.getMessage(), + new Integer(problem.isError() ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING), + new Integer(id), + new Integer(problem.getSourceStart()), + new Integer(problem.getSourceEnd() + 1), + new Integer(problem.getSourceLineNumber()), + net.sourceforge.phpdt.internal.core.Util.getProblemArgumentsForMarker(problem.getArguments())}); + } + + } + } + protected CompilationUnitDeclaration endParse(int act) { + + this.lastAct = act; + + if (currentElement != null) { + currentElement.topElement().updateParseTree(); + if (VERBOSE_RECOVERY) { + System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$ + System.out.println("--------------------------"); //$NON-NLS-1$ + System.out.println(compilationUnit); + System.out.println("----------------------------------"); //$NON-NLS-1$ + } + } else { + if (diet & VERBOSE_RECOVERY) { + System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$ + System.out.println("--------------------------"); //$NON-NLS-1$ + System.out.println(compilationUnit); + System.out.println("----------------------------------"); //$NON-NLS-1$ + } + } + if (scanner.recordLineSeparator) { + compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds(); + } + if (scanner.taskTags != null) { + for (int i = 0; i < scanner.foundTaskCount; i++) { + problemReporter().task( + new String(scanner.foundTaskTags[i]), + new String(scanner.foundTaskMessages[i]), + scanner.foundTaskPriorities[i] == null ? null : new String(scanner.foundTaskPriorities[i]), + scanner.foundTaskPositions[i][0], + scanner.foundTaskPositions[i][1]); + } + } + return compilationUnit; + } + + // A P I + + public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) { + //only parse the method body of cd + //fill out its statements + + //convert bugs into parse error + + initialize(); + goForConstructorBody(); + nestedMethod[nestedType]++; + + referenceContext = cd; + compilationUnit = unit; + + scanner.resetTo(cd.sourceEnd + 1, cd.declarationSourceEnd); + try { + parse(); + } catch (AbortCompilation ex) { + lastAct = ERROR_ACTION; + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + nestedMethod[nestedType]--; + } + + if (lastAct == ERROR_ACTION) { + initialize(); + return; + } + + //statements + // cd.explicitDeclarations = realBlockStack[realBlockPtr--]; + // int length; + // if ((length = astLengthStack[astLengthPtr--]) != 0) { + // astPtr -= length; + // if (astStack[astPtr + 1] instanceof ExplicitConstructorCall) + // //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ? + // { + // System.arraycopy( + // astStack, + // astPtr + 2, + // cd.statements = new Statement[length - 1], + // 0, + // length - 1); + // cd.constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1]; + // } else { //need to add explicitly the super(); + // System.arraycopy( + // astStack, + // astPtr + 1, + // cd.statements = new Statement[length], + // 0, + // length); + // cd.constructorCall = SuperReference.implicitSuperConstructorCall(); + // } + // } else { + // cd.constructorCall = SuperReference.implicitSuperConstructorCall(); + // } + // + // if (cd.constructorCall.sourceEnd == 0) { + // cd.constructorCall.sourceEnd = cd.sourceEnd; + // cd.constructorCall.sourceStart = cd.sourceStart; + // } + } + // A P I + + public void parse(FieldDeclaration field, TypeDeclaration type, CompilationUnitDeclaration unit, char[] initializationSource) { + //only parse the initializationSource of the given field + + //convert bugs into parse error + + initialize(); + goForExpression(); + nestedMethod[nestedType]++; + + referenceContext = type; + compilationUnit = unit; + + scanner.setSource(initializationSource); + scanner.resetTo(0, initializationSource.length - 1); + try { + parse(); + } catch (AbortCompilation ex) { + lastAct = ERROR_ACTION; + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + nestedMethod[nestedType]--; + } + + // if (lastAct == ERROR_ACTION) { + // return; + // } + // + // field.initialization = expressionStack[expressionPtr]; + // + // // mark field with local type if one was found during parsing + // if ((type.bits & AstNode.HasLocalTypeMASK) != 0) { + // field.bits |= AstNode.HasLocalTypeMASK; + // } + } + // A P I + + public void parse(Initializer ini, TypeDeclaration type, CompilationUnitDeclaration unit) { + //only parse the method body of md + //fill out method statements + + //convert bugs into parse error + + initialize(); + goForInitializer(); + nestedMethod[nestedType]++; + + referenceContext = type; + compilationUnit = unit; + + scanner.resetTo(ini.sourceStart, ini.sourceEnd); // just on the beginning { + try { + parse(); + } catch (AbortCompilation ex) { + lastAct = ERROR_ACTION; + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + nestedMethod[nestedType]--; + } + + // if (lastAct == ERROR_ACTION) { + // return; + // } + // + // ini.block = ((Initializer) astStack[astPtr]).block; + // + // // mark initializer with local type if one was found during parsing + // if ((type.bits & AstNode.HasLocalTypeMASK) != 0) { + // ini.bits |= AstNode.HasLocalTypeMASK; + // } + } + // A P I + + public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) { + //only parse the method body of md + //fill out method statements + + //convert bugs into parse error + + if (md.isAbstract()) + return; + // if (md.isNative()) + // return; + // if ((md.modifiers & AccSemicolonBody) != 0) + // return; + + initialize(); + goForMethodBody(); + nestedMethod[nestedType]++; + + referenceContext = md; + compilationUnit = unit; + + scanner.resetTo(md.sourceEnd + 1, md.declarationSourceEnd); + // reset the scanner to parser from { down to } + try { + parse(); + } catch (AbortCompilation ex) { + lastAct = ERROR_ACTION; + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + nestedMethod[nestedType]--; + } + + // if (lastAct == ERROR_ACTION) { + // return; + // } + // + // //refill statements + // md.explicitDeclarations = realBlockStack[realBlockPtr--]; + // int length; + // if ((length = astLengthStack[astLengthPtr--]) != 0) + // System.arraycopy( + // astStack, + // (astPtr -= length) + 1, + // md.statements = new Statement[length], + // 0, + // length); + } + + // A P I + + public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, int start, int end) { + // parses a compilation unit and manages error handling (even bugs....) + + CompilationUnitDeclaration unit; + try { + /* automaton initialization */ + initialize(); + goForCompilationUnit(); + + /* scanner initialization */ + scanner.setSource(sourceUnit.getContents()); + scanner.resetTo(start, end); + /* unit creation */ + referenceContext = + compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length); + /* run automaton */ + parse(); + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SyntaxError syntaxError) { + // + } finally { + unit = compilationUnit; + compilationUnit = null; // reset parser + } + return unit; + } + + public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) { + + CompilationUnitDeclaration parsedUnit; + boolean old = diet; + try { + diet = true; + parsedUnit = parse(sourceUnit, compilationResult); + } finally { + diet = old; + } + return parsedUnit; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/AbortCompilation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/AbortCompilation.java new file mode 100644 index 0000000..f954e99 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/AbortCompilation.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.problem; + +import net.sourceforge.phpdt.internal.compiler.CompilationResult; + +/* + * Special unchecked exception type used + * to abort from the compilation process + * + * should only be thrown from within problem handlers. + */ +public class AbortCompilation extends RuntimeException { + + public CompilationResult compilationResult; + public Throwable exception; + public int problemId; + public String[] problemArguments, messageArguments; + /* special fields used to abort silently (e.g. when cancelling build process) */ + public boolean isSilent; + public RuntimeException silentException; + + public AbortCompilation() { + + this((CompilationResult)null); + } + + public AbortCompilation(int problemId, String[] problemArguments, String[] messageArguments) { + + this.problemId = problemId; + this.problemArguments = problemArguments; + this.messageArguments = messageArguments; + } + + public AbortCompilation(CompilationResult compilationResult) { + + this(compilationResult, null); + } + + public AbortCompilation(CompilationResult compilationResult, Throwable exception) { + + this.compilationResult = compilationResult; + this.exception = exception; + } + + public AbortCompilation(boolean isSilent, RuntimeException silentException) { + + this.isSilent = isSilent; + this.silentException = silentException; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/AbortCompilationUnit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/AbortCompilationUnit.java new file mode 100644 index 0000000..d708839 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/AbortCompilationUnit.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.problem; + +import net.sourceforge.phpdt.internal.compiler.CompilationResult; + +/* + * Special unchecked exception type used + * to abort from the compilation process + * + * should only be thrown from within problem handlers. + */ +public class AbortCompilationUnit extends AbortCompilation { +public AbortCompilationUnit(CompilationResult compilationResult) { + super(compilationResult); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/AbortMethod.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/AbortMethod.java new file mode 100644 index 0000000..77e8920 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/AbortMethod.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.problem; + +import net.sourceforge.phpdt.internal.compiler.CompilationResult; + +/* + * Special unchecked exception type used + * to abort from the compilation process + * + * should only be thrown from within problem handlers. + */ +public class AbortMethod extends AbortType { +public AbortMethod(CompilationResult compilationResult) { + super(compilationResult); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/AbortType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/AbortType.java new file mode 100644 index 0000000..16e388e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/AbortType.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.problem; + +import net.sourceforge.phpdt.internal.compiler.CompilationResult; + +/* + * Special unchecked exception type used + * to abort from the compilation process + * + * should only be thrown from within problem handlers. + */ +public class AbortType extends AbortCompilationUnit { +public AbortType(CompilationResult compilationResult) { + super(compilationResult); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/DefaultProblem.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/DefaultProblem.java new file mode 100644 index 0000000..1e7169e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/DefaultProblem.java @@ -0,0 +1,252 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.problem; + +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.util.Util; + +import org.eclipse.ui.texteditor.ITextEditor; + + +public class DefaultProblem implements ProblemSeverities, IProblem { + + private char[] fileName; + private int id; + private int startPosition, endPosition, line; + private int severity; + private String[] arguments; + private String message; + + public DefaultProblem( + char[] originatingFileName, + String message, + int id, + String[] stringArguments, + int severity, + int startPosition, + int endPosition, + int line) { + + this.fileName = originatingFileName; + this.message = message; + this.id = id; + this.arguments = stringArguments; + this.severity = severity; + this.startPosition = startPosition; + this.endPosition = endPosition; + this.line = line; + } + + public String errorReportSource(ITextEditor textEditor){ //ICompilationUnit compilationUnit) { + //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 ..... + if ((startPosition > endPosition) + || ((startPosition <= 0) && (endPosition <= 0))) + return Util.bind("problem.noSourceInformation"); //$NON-NLS-1$ + + final char SPACE = '\u0020'; + final char MARK = '^'; + final char TAB = '\t'; +// char[] source = compilationUnit.getContents(); + char[] source = textEditor.getDocumentProvider().getDocument(null).get().toCharArray(); + //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 !) + + //compute the how-much-char we are displaying around the inaccurate token + int begin = startPosition >= source.length ? source.length - 1 : startPosition; + int relativeStart = 0; + int end = endPosition >= source.length ? source.length - 1 : endPosition; + int relativeEnd = 0; + label : for (relativeStart = 0;; relativeStart++) { + if (begin == 0) + break label; + if ((source[begin - 1] == '\n') || (source[begin - 1] == '\r')) + break label; + begin--; + } + label : for (relativeEnd = 0;; relativeEnd++) { + if ((end + 1) >= source.length) + break label; + if ((source[end + 1] == '\r') || (source[end + 1] == '\n')) { + break label; + } + end++; + } + //extract the message form the source + char[] extract = new char[end - begin + 1]; + System.arraycopy(source, begin, extract, 0, extract.length); + char c; + //remove all SPACE and TAB that begin the error message... + int trimLeftIndex = 0; + while (((c = extract[trimLeftIndex++]) == TAB) || (c == SPACE)) { + }; + System.arraycopy( + extract, + trimLeftIndex - 1, + extract = new char[extract.length - trimLeftIndex + 1], + 0, + extract.length); + relativeStart -= trimLeftIndex; + //buffer spaces and tabs in order to reach the error position + int pos = 0; + char[] underneath = new char[extract.length]; // can't be bigger + for (int i = 0; i <= relativeStart; i++) { + if (extract[i] == TAB) { + underneath[pos++] = TAB; + } else { + underneath[pos++] = SPACE; + } + } + //mark the error position + for (int i = startPosition; + i <= (endPosition >= source.length ? source.length - 1 : endPosition); + i++) + underneath[pos++] = MARK; + //resize underneathto remove 'null' chars + System.arraycopy(underneath, 0, underneath = new char[pos], 0, pos); + + return " " + Util.bind("problem.atLine", String.valueOf(line)) //$NON-NLS-2$ //$NON-NLS-1$ + + "\n\t" + new String(extract) + "\n\t" + new String(underneath); //$NON-NLS-2$ //$NON-NLS-1$ + } + + /** + * Answer back the original arguments recorded into the problem. + * @return java.lang.String[] + */ + public String[] getArguments() { + + return arguments; + } + + /** + * Answer the type of problem. + * @see org.eclipse.jdt.core.compiler.IProblem#getID() + * @return int + */ + public int getID() { + + return id; + } + + /** + * Answer a localized, human-readable message string which describes the problem. + * @return java.lang.String + */ + public String getMessage() { + + return message; + } + + /** + * Answer the file name in which the problem was found. + * @return char[] + */ + public char[] getOriginatingFileName() { + + return fileName; + } + + /** + * Answer the end position of the problem (inclusive), or -1 if unknown. + * @return int + */ + public int getSourceEnd() { + + return endPosition; + } + + /** + * Answer the line number in source where the problem begins. + * @return int + */ + public int getSourceLineNumber() { + + return line; + } + + /** + * Answer the start position of the problem (inclusive), or -1 if unknown. + * @return int + */ + public int getSourceStart() { + + return startPosition; + } + + /* + * Helper method: checks the severity to see if the Error bit is set. + * @return boolean + */ + public boolean isError() { + + return (severity & ProblemSeverities.Error) != 0; + } + + /* + * Helper method: checks the severity to see if the Error bit is not set. + * @return boolean + */ + public boolean isWarning() { + + return (severity & ProblemSeverities.Error) == 0; + } + + /** + * Set the end position of the problem (inclusive), or -1 if unknown. + * + * Used for shifting problem positions. + * @param sourceEnd the new value of the sourceEnd of the receiver + */ + public void setSourceEnd(int sourceEnd) { + + endPosition = sourceEnd; + } + + /** + * Set the line number in source where the problem begins. + * @param lineNumber the new value of the line number of the receiver + */ + public void setSourceLineNumber(int lineNumber) { + + line = lineNumber; + } + + /** + * Set the start position of the problem (inclusive), or -1 if unknown. + * + * Used for shifting problem positions. + * @param sourceStart the new value of the source start position of the receiver + */ + public void setSourceStart(int sourceStart) { + + startPosition = sourceStart; + } + + public String toString() { + + String s = "Pb(" + (id & IgnoreCategoriesMask) + ") "; //$NON-NLS-1$ //$NON-NLS-2$ + if (message != null) { + s += message; + } else { + if (arguments != null) + for (int i = 0; i < arguments.length; i++) + s += " " + arguments[i]; //$NON-NLS-1$ + } + return s; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/DefaultProblemFactory.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/DefaultProblemFactory.java new file mode 100644 index 0000000..fe0896d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/DefaultProblemFactory.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.problem; + +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.IProblemFactory; + +public class DefaultProblemFactory implements IProblemFactory { + + + public String[] messageTemplates; + private Locale locale; + private static String[] DEFAULT_LOCALE_TEMPLATES; + private final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$ + private final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$ + +/** + * @param loc the locale used to get the right message + */ +public DefaultProblemFactory(Locale loc) { + this.locale = loc; + if (Locale.getDefault().equals(loc)){ + if (DEFAULT_LOCALE_TEMPLATES == null){ + DEFAULT_LOCALE_TEMPLATES = loadMessageTemplates(loc); + } + this.messageTemplates = DEFAULT_LOCALE_TEMPLATES; + } else { + this.messageTemplates = loadMessageTemplates(loc); + } +} +/** + * Answer a new IProblem created according to the parameters value + *
      + *
    • originatingFileName the name of the file name from which the problem is originated + *
    • problemId the problem id + *
    • problemArguments the fully qualified arguments recorded inside the problem + *
    • messageArguments the arguments needed to set the error message (shorter names than problemArguments ones) + *
    • severity the severity of the problem + *
    • startPosition the starting position of the problem + *
    • endPosition the end position of the problem + *
    • lineNumber the line on which the problem occured + *
    + * @param originatingFileName char[] + * @param problemId int + * @param arguments String[] + * @param severity int + * @param startPosition int + * @param endPosition int + * @param lineNumber int + * @return org.eclipse.jdt.internal.compiler.IProblem + */ +public IProblem createProblem( + char[] originatingFileName, + int problemId, + String[] problemArguments, + String[] messageArguments, + int severity, + int startPosition, + int endPosition, + int lineNumber) { + + return new DefaultProblem( + originatingFileName, + this.getLocalizedMessage(problemId, messageArguments), + problemId, + problemArguments, + severity, + startPosition, + endPosition, + lineNumber); +} +/** + * Answer the locale used to retrieve the error messages + * @return java.util.Locale + */ +public Locale getLocale() { + return locale; +} +public final String getLocalizedMessage(int id, String[] problemArguments) { + StringBuffer output = new StringBuffer(80); + String message = + messageTemplates[(id & IProblem.IgnoreCategoriesMask)]; + if (message == null) { + return "Unable to retrieve the error message for problem id: " //$NON-NLS-1$ + + (id & IProblem.IgnoreCategoriesMask) + + ". Check compiler resources."; //$NON-NLS-1$ + } + + // for compatibility with MessageFormat which eliminates double quotes in original message + char[] messageWithNoDoubleQuotes = + CharOperation.replace(message.toCharArray(), DOUBLE_QUOTES, SINGLE_QUOTE); + message = new String(messageWithNoDoubleQuotes); + + int length = message.length(); + int start = -1, end = length; + while (true) { + if ((end = message.indexOf('{', start)) > -1) { + output.append(message.substring(start + 1, end)); + if ((start = message.indexOf('}', end)) > -1) { + try { + output.append( + problemArguments[Integer.parseInt(message.substring(end + 1, start))]); + } catch (NumberFormatException nfe) { + output.append(message.substring(end + 1, start + 1)); + } catch (ArrayIndexOutOfBoundsException e) { + return "Corrupted compiler resources for problem id: " //$NON-NLS-1$ + + (id & IProblem.IgnoreCategoriesMask) + + ". Check compiler resources."; //$NON-NLS-1$ + } + } else { + output.append(message.substring(end, length)); + break; + } + } else { + output.append(message.substring(start + 1, length)); + break; + } + } + return output.toString(); +} +/** + * @param problem org.eclipse.jdt.internal.compiler.IProblem + * @return String + */ +public final String localizedMessage(IProblem problem) { + return getLocalizedMessage(problem.getID(), problem.getArguments()); +} + +/** + * This method initializes the MessageTemplates class variable according + * to the current Locale. + */ +public static String[] loadMessageTemplates(Locale loc) { + ResourceBundle bundle = null; + String bundleName = "net.sourceforge.phpdt.internal.compiler.problem.messages"; //$NON-NLS-1$ + try { + bundle = ResourceBundle.getBundle(bundleName, loc); + } catch(MissingResourceException e) { + System.out.println("Missing resource : " + bundleName.replace('.', '/') + ".properties for locale " + loc); //$NON-NLS-1$//$NON-NLS-2$ + throw e; + } + String[] templates = new String[500]; + for (int i = 0, max = templates.length; i < max; i++) { + try { + templates[i] = bundle.getString(String.valueOf(i)); + } catch (MissingResourceException e) { + // available ID + } + } + return templates; +} + +public DefaultProblemFactory() { + this(Locale.getDefault()); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/ProblemHandler.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/ProblemHandler.java new file mode 100644 index 0000000..e96bead --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/ProblemHandler.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.problem; + +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.IErrorHandlingPolicy; +import net.sourceforge.phpdt.internal.compiler.IProblemFactory; +import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; + + +/* + * Compiler error handler, responsible to determine whether + * a problem is actually a warning or an error; also will + * decide whether the compilation task can be processed further or not. + * + * Behavior : will request its current policy if need to stop on + * first error, and if should proceed (persist) with problems. + */ + +public class ProblemHandler implements ProblemSeverities { + + public final static String[] NoArgument = new String[0]; + + final public IErrorHandlingPolicy policy; + public final IProblemFactory problemFactory; +// public final CompilerOptions options; +/* + * Problem handler can be supplied with a policy to specify + * its behavior in error handling. Also see static methods for + * built-in policies. + * + */ +public ProblemHandler(IErrorHandlingPolicy policy, IProblemFactory problemFactory) { +//CompilerOptions options, IProblemFactory problemFactory) { + this.policy = policy; + this.problemFactory = problemFactory; +// this.options = options; +} +/* + * Given the current configuration, answers which category the problem + * falls into: + * Error | Warning | Ignore + */ +public int computeSeverity(int problemId){ + + return Error; // by default all problems are errors +} +public IProblem createProblem( + char[] fileName, + int problemId, + String[] problemArguments, + String[] messageArguments, + int severity, + int problemStartPosition, + int problemEndPosition, + int lineNumber, + ReferenceContext referenceContext, + CompilationResult unitResult) { + + return problemFactory.createProblem( + fileName, + problemId, + problemArguments, + messageArguments, + severity, + problemStartPosition, + problemEndPosition, + lineNumber); +} +public void handle( + int problemId, + String[] problemArguments, + String[] messageArguments, + int severity, + int problemStartPosition, + int problemEndPosition, + ReferenceContext referenceContext, + CompilationResult unitResult) { + + if (severity == Ignore) + return; + + // if no reference context, we need to abort from the current compilation process + if (referenceContext == null) { + if ((severity & Error) != 0) { // non reportable error is fatal + throw new AbortCompilation(problemId, problemArguments, messageArguments); + } else { + return; // ignore non reportable warning + } + } + + IProblem problem = + this.createProblem( + unitResult.getFileName(), + problemId, + problemArguments, + messageArguments, + severity, + problemStartPosition, + problemEndPosition, + problemStartPosition >= 0 + ? searchLineNumber(unitResult.lineSeparatorPositions, problemStartPosition) + : 0, + referenceContext, + unitResult); + if (problem == null) return; // problem couldn't be created, ignore + + switch (severity & Error) { + case Error : + this.record(problem, unitResult, referenceContext); + referenceContext.tagAsHavingErrors(); + + // should abort ? + int abortLevel; + if ((abortLevel = + (policy.stopOnFirstError() ? AbortCompilation : severity & Abort)) != 0) { + + referenceContext.abort(abortLevel); + } + break; + case Warning : + this.record(problem, unitResult, referenceContext); + break; + } +} +/** + * Standard problem handling API, the actual severity (warning/error/ignore) is deducted + * from the problem ID and the current compiler options. + */ +public void handle( + int problemId, + String[] problemArguments, + String[] messageArguments, + int problemStartPosition, + int problemEndPosition, + ReferenceContext referenceContext, + CompilationResult unitResult) { + + this.handle( + problemId, + problemArguments, + messageArguments, + this.computeSeverity(problemId), // severity inferred using the ID + problemStartPosition, + problemEndPosition, + referenceContext, + unitResult); +} +public void record(IProblem problem, CompilationResult unitResult, ReferenceContext referenceContext) { + unitResult.record(problem, referenceContext); +} +/** + * Search the line number corresponding to a specific position + * + * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding + */ +public static final int searchLineNumber(int[] startLineIndexes, int position) { + if (startLineIndexes == null) + return 1; + int length = startLineIndexes.length; + if (length == 0) + return 1; + int g = 0, d = length - 1; + int m = 0; + while (g <= d) { + m = (g + d) /2; + if (position < startLineIndexes[m]) { + d = m-1; + } else if (position > startLineIndexes[m]) { + g = m+1; + } else { + return m + 1; + } + } + if (position < startLineIndexes[m]) { + return m+1; + } + return m+2; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/ProblemReporter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/ProblemReporter.java new file mode 100644 index 0000000..5bdab62 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/ProblemReporter.java @@ -0,0 +1,3330 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.problem; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.core.compiler.InvalidInputException; +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.IErrorHandlingPolicy; +import net.sourceforge.phpdt.internal.compiler.IProblemFactory; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; +import net.sourceforge.phpdt.internal.compiler.lookup.Binding; +import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ProblemMethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ProblemReasons; +import net.sourceforge.phpdt.internal.compiler.lookup.ProblemReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SyntheticArgumentBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants; +import net.sourceforge.phpdt.internal.compiler.parser.Parser; +import net.sourceforge.phpdt.internal.compiler.parser.Scanner; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractVariableDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.AllocationExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.Argument; +import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayAllocationExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.Assignment; +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; +import net.sourceforge.phpeclipse.internal.compiler.ast.BinaryExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.BranchStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.Case; +import net.sourceforge.phpeclipse.internal.compiler.ast.CastExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompoundAssignment; +import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.DefaultCase; +import net.sourceforge.phpeclipse.internal.compiler.ast.EqualExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.ExplicitConstructorCall; +import net.sourceforge.phpeclipse.internal.compiler.ast.Expression; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.InstanceOfExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.IntLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.Literal; +import net.sourceforge.phpeclipse.internal.compiler.ast.LocalDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.LongLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.MessageSend; +import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.NameReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.NumberLiteral; +import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedNameReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.Reference; +import net.sourceforge.phpeclipse.internal.compiler.ast.ReturnStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.SingleNameReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.Statement; +import net.sourceforge.phpeclipse.internal.compiler.ast.ThisReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.ThrowStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.TryStatement; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.UnaryExpression; + +public class ProblemReporter extends ProblemHandler implements ProblemReasons { + + public ReferenceContext referenceContext; +public ProblemReporter(IErrorHandlingPolicy policy, IProblemFactory problemFactory) { +//CompilerOptions options, IProblemFactory problemFactory) { + super(policy, problemFactory);//options, problemFactory); +} +public void abortDueToInternalError(String errorMessage) { + String[] arguments = new String[] {errorMessage}; + this.handle( + IProblem.Unclassified, + arguments, + arguments, + Error | Abort, + 0, + 0); +} +public void abortDueToInternalError(String errorMessage, AstNode location) { + String[] arguments = new String[] {errorMessage}; + this.handle( + IProblem.Unclassified, + arguments, + arguments, + Error | Abort, + location.sourceStart, + location.sourceEnd); +} +public void abstractMethodCannotBeOverridden(SourceTypeBinding type, MethodBinding concreteMethod) { + + this.handle( + // %1 must be abstract since it cannot override the inherited package-private abstract method %2 + IProblem.AbstractMethodCannotBeOverridden, + new String[] { + new String(type.sourceName()), + new String( + CharOperation.concat( + concreteMethod.declaringClass.readableName(), + concreteMethod.readableName(), + '.'))}, + new String[] { + new String(type.sourceName()), + new String( + CharOperation.concat( + concreteMethod.declaringClass.shortReadableName(), + concreteMethod.shortReadableName(), + '.'))}, + type.sourceStart(), + type.sourceEnd()); +} +public void abstractMethodInAbstractClass(SourceTypeBinding type, AbstractMethodDeclaration methodDecl) { + + String[] arguments = new String[] {new String(type.sourceName()), new String(methodDecl.selector)}; + this.handle( + IProblem.AbstractMethodInAbstractClass, + arguments, + arguments, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void abstractMethodMustBeImplemented(SourceTypeBinding type, MethodBinding abstractMethod) { + this.handle( + // Must implement the inherited abstract method %1 + // 8.4.3 - Every non-abstract subclass of an abstract type, A, must provide a concrete implementation of all of A's methods. + IProblem.AbstractMethodMustBeImplemented, + new String[] { + new String( + CharOperation.concat( + abstractMethod.declaringClass.readableName(), + abstractMethod.readableName(), + '.'))}, + new String[] { + new String( + CharOperation.concat( + abstractMethod.declaringClass.shortReadableName(), + abstractMethod.shortReadableName(), + '.'))}, + type.sourceStart(), + type.sourceEnd()); +} +public void abstractMethodNeedingNoBody(AbstractMethodDeclaration method) { + this.handle( + IProblem.BodyForAbstractMethod, + NoArgument, + NoArgument, + method.sourceStart, + method.sourceEnd, + method, + method.compilationResult()); +} +public void alreadyDefinedLabel(char[] labelName, AstNode location) { + String[] arguments = new String[] {new String(labelName)}; + this.handle( + IProblem.DuplicateLabel, + arguments, + arguments, + location.sourceStart, + location.sourceEnd); +} +public void anonymousClassCannotExtendFinalClass(Expression expression, TypeBinding type) { + this.handle( + IProblem.AnonymousClassCannotExtendFinalClass, + new String[] {new String(type.readableName())}, + new String[] {new String(type.shortReadableName())}, + expression.sourceStart, + expression.sourceEnd); +} +public void argumentTypeCannotBeVoid(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, Argument arg) { + String[] arguments = new String[] {new String(methodDecl.selector), new String(arg.name)}; + this.handle( + IProblem.ArgumentTypeCannotBeVoid, + arguments, + arguments, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void argumentTypeCannotBeVoidArray(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, Argument arg) { + String[] arguments = new String[] {new String(methodDecl.selector), new String(arg.name)}; + this.handle( + IProblem.ArgumentTypeCannotBeVoidArray, + arguments, + arguments, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void argumentTypeProblem(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, Argument arg, TypeBinding expectedType) { + int problemId = expectedType.problemId(); + int id; + switch (problemId) { + case NotFound : // 1 + id = IProblem.ArgumentTypeNotFound; + break; + case NotVisible : // 2 + id = IProblem.ArgumentTypeNotVisible; + break; + case Ambiguous : // 3 + id = IProblem.ArgumentTypeAmbiguous; + break; + case InternalNameProvided : // 4 + id = IProblem.ArgumentTypeInternalNameProvided; + break; + case InheritedNameHidesEnclosingName : // 5 + id = IProblem.ArgumentTypeInheritedNameHidesEnclosingName; + break; + case NoError : // 0 + default : + needImplementation(); // want to fail to see why we were here... + return; + } + this.handle( + id, + new String[] {new String(methodDecl.selector), arg.name(), new String(expectedType.readableName())}, + new String[] {new String(methodDecl.selector), arg.name(), new String(expectedType.shortReadableName())}, + arg.type.sourceStart, + arg.type.sourceEnd); +} +public void arrayConstantsOnlyInArrayInitializers(int sourceStart, int sourceEnd) { + this.handle( + IProblem.ArrayConstantsOnlyInArrayInitializers, + NoArgument, + NoArgument, + sourceStart, + sourceEnd); +} +public void assignmentHasNoEffect(Assignment assignment, char[] name){ + String[] arguments = new String[] { new String(name) }; + this.handle( + IProblem.AssignmentHasNoEffect, + arguments, + arguments, + assignment.sourceStart, + assignment.sourceEnd); +} +public void attemptToReturnNonVoidExpression(ReturnStatement returnStatement, TypeBinding expectedType) { + this.handle( + IProblem.VoidMethodReturnsValue, + new String[] {new String(expectedType.readableName())}, + new String[] {new String(expectedType.shortReadableName())}, + returnStatement.sourceStart, + returnStatement.sourceEnd); +} +public void attemptToReturnVoidValue(ReturnStatement returnStatement) { + this.handle( + IProblem.MethodReturnsVoid, + NoArgument, + NoArgument, + returnStatement.sourceStart, + returnStatement.sourceEnd); +} +//public void bytecodeExceeds64KLimit(AbstractMethodDeclaration location) { +// String[] arguments = new String[] {new String(location.selector), parametersAsString(location.binding)}; +// if (location.isConstructor()) { +// this.handle( +// IProblem.BytecodeExceeds64KLimitForConstructor, +// arguments, +// arguments, +// Error | Abort, +// location.sourceStart, +// location.sourceEnd); +// } else { +// this.handle( +// IProblem.BytecodeExceeds64KLimit, +// arguments, +// arguments, +// Error | Abort, +// location.sourceStart, +// location.sourceEnd); +// } +//} +public void bytecodeExceeds64KLimit(TypeDeclaration location) { + this.handle( + IProblem.BytecodeExceeds64KLimitForClinit, + NoArgument, + NoArgument, + Error | Abort, + location.sourceStart, + location.sourceEnd); +} +public void cannotAllocateVoidArray(Expression expression) { + this.handle( + IProblem.CannotAllocateVoidArray, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void cannotAssignToFinalField(FieldBinding field, AstNode location) { + this.handle( + IProblem.FinalFieldAssignment, + new String[] { + (field.declaringClass == null ? "array" : new String(field.declaringClass.readableName())), //$NON-NLS-1$ + new String(field.readableName())}, + new String[] { + (field.declaringClass == null ? "array" : new String(field.declaringClass.shortReadableName())), //$NON-NLS-1$ + new String(field.shortReadableName())}, + location.sourceStart, + location.sourceEnd); +} +public void cannotAssignToFinalLocal(LocalVariableBinding local, AstNode location) { + String[] arguments = new String[] { new String(local.readableName())}; + this.handle( + IProblem.NonBlankFinalLocalAssignment, + arguments, + arguments, + location.sourceStart, + location.sourceEnd); +} +public void cannotAssignToFinalOuterLocal(LocalVariableBinding local, AstNode location) { + String[] arguments = new String[] {new String(local.readableName())}; + this.handle( + IProblem.FinalOuterLocalAssignment, + arguments, + arguments, + location.sourceStart, + location.sourceEnd); +} +public void cannotDeclareLocalInterface(char[] interfaceName, int sourceStart, int sourceEnd) { + String[] arguments = new String[] {new String(interfaceName)}; + this.handle( + IProblem.CannotDefineInterfaceInLocalType, + arguments, + arguments, + sourceStart, + sourceEnd); +} +public void cannotDefineDimensionsAndInitializer(ArrayAllocationExpression expresssion) { + this.handle( + IProblem.CannotDefineDimensionExpressionsWithInit, + NoArgument, + NoArgument, + expresssion.sourceStart, + expresssion.sourceEnd); +} +public void cannotDireclyInvokeAbstractMethod(MessageSend messageSend, MethodBinding method) { + this.handle( + IProblem.DirectInvocationOfAbstractMethod, + new String[] {new String(method.declaringClass.readableName()), new String(method.selector), parametersAsString(method)}, + new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), parametersAsShortString(method)}, + messageSend.sourceStart, + messageSend.sourceEnd); +} +public void cannotImportPackage(ImportReference importRef) { + String[] arguments = new String[] {CharOperation.toString(importRef.tokens)}; + this.handle( + IProblem.CannotImportPackage, + arguments, + arguments, + importRef.sourceStart, + importRef.sourceEnd); +} +public void cannotInstantiate(TypeReference typeRef, TypeBinding type) { + this.handle( + IProblem.InvalidClassInstantiation, + new String[] {new String(type.readableName())}, + new String[] {new String(type.shortReadableName())}, + typeRef.sourceStart, + typeRef.sourceEnd); +} +public void cannotReferToNonFinalOuterLocal(LocalVariableBinding local, AstNode location) { + String[] arguments =new String[]{ new String(local.readableName())}; + this.handle( + IProblem.OuterLocalMustBeFinal, + arguments, + arguments, + location.sourceStart, + location.sourceEnd); +} +public void cannotReturnInInitializer(AstNode location) { + this.handle( + IProblem.CannotReturnInInitializer, + NoArgument, + NoArgument, + location.sourceStart, + location.sourceEnd); +} +public void cannotThrowNull(ThrowStatement statement) { + this.handle( + IProblem.CannotThrowNull, + NoArgument, + NoArgument, + statement.sourceStart, + statement.sourceEnd); +} +public void cannotThrowType(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, TypeReference exceptionType, TypeBinding expectedType) { + this.handle( + IProblem.CannotThrowType, + new String[] {new String(expectedType.readableName())}, + new String[] {new String(expectedType.shortReadableName())}, + exceptionType.sourceStart, + exceptionType.sourceEnd); +} +public void cannotUseSuperInJavaLangObject(AstNode reference) { + this.handle( + IProblem.ObjectHasNoSuperclass, + NoArgument, + NoArgument, + reference.sourceStart, + reference.sourceEnd); +} +public void cannotUseSuperInCodeSnippet(int start, int end) { + this.handle( + IProblem.CannotUseSuperInCodeSnippet, + NoArgument, + NoArgument, + Error | Abort, + start, + end); +} +public void caseExpressionMustBeConstant(Expression expression) { + this.handle( + IProblem.NonConstantExpression, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void classExtendFinalClass(SourceTypeBinding type, TypeReference superclass, TypeBinding expectedType) { + String name = new String(type.sourceName()); + String expectedFullName = new String(expectedType.readableName()); + String expectedShortName = new String(expectedType.shortReadableName()); + if (expectedShortName.equals(name)) expectedShortName = expectedFullName; + this.handle( + IProblem.ClassExtendFinalClass, + new String[] {expectedFullName, name}, + new String[] {expectedShortName, name}, + superclass.sourceStart, + superclass.sourceEnd); +} +public void codeSnippetMissingClass(String missing, int start, int end) { + String[] arguments = new String[]{missing}; + this.handle( + IProblem.CodeSnippetMissingClass, + arguments, + arguments, + Error | Abort, + start, + end); +} +public void codeSnippetMissingMethod(String className, String missingMethod, String argumentTypes, int start, int end) { + String[] arguments = new String[]{ className, missingMethod, argumentTypes }; + this.handle( + IProblem.CodeSnippetMissingMethod, + arguments, + arguments, + Error | Abort, + start, + end); +} +/* + * Given the current configuration, answers which category the problem + * falls into: + * Error | Warning | Ignore + */ +//public int computeSeverity(int problemId){ +// +// // severity can have been preset on the problem +//// if ((problem.severity & Fatal) != 0){ +//// return Error; +//// } +// +// // if not then check whether it is a configurable problem +// int errorThreshold = options.errorThreshold; +// int warningThreshold = options.warningThreshold; +// +// switch(problemId){ +// +// case IProblem.UnreachableCatch : +// case IProblem.CodeCannotBeReached : +// if ((errorThreshold & CompilerOptions.UnreachableCode) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.UnreachableCode) != 0){ +// return Warning; +// } +// return Ignore; +// +// case IProblem.MaskedCatch : +// if ((errorThreshold & CompilerOptions.MaskedCatchBlock) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.MaskedCatchBlock) != 0){ +// return Warning; +// } +// return Ignore; +// +///* +// case Never Used : +// if ((errorThreshold & ParsingOptionalError) != 0){ +// return Error; +// } +// if ((warningThreshold & ParsingOptionalError) != 0){ +// return Warning; +// } +// return Ignore; +//*/ +// case IProblem.ImportNotFound : +// case IProblem.ImportNotVisible : +// case IProblem.ImportAmbiguous : +// case IProblem.ImportInternalNameProvided : +// case IProblem.ImportInheritedNameHidesEnclosingName : +// case IProblem.DuplicateImport : +// case IProblem.ConflictingImport : +// case IProblem.CannotImportPackage : +// if ((errorThreshold & CompilerOptions.ImportProblem) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.ImportProblem) != 0){ +// return Warning; +// } +// return Ignore; +// +// case IProblem.UnusedImport : +// // if import problem are disabled, then ignore +// if ((errorThreshold & CompilerOptions.ImportProblem) == 0 +// && (warningThreshold & CompilerOptions.ImportProblem) == 0){ +// return Ignore; +// } +// if ((errorThreshold & CompilerOptions.UnusedImport) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.UnusedImport) != 0){ +// return Warning; +// } +// return Ignore; +// +// case IProblem.MethodButWithConstructorName : +// if ((errorThreshold & CompilerOptions.MethodWithConstructorName) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.MethodWithConstructorName) != 0){ +// return Warning; +// } +// return Ignore; +// +// case IProblem.OverridingNonVisibleMethod : +// if ((errorThreshold & CompilerOptions.OverriddenPackageDefaultMethod) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.OverriddenPackageDefaultMethod) != 0){ +// return Warning; +// } +// return Ignore; +// +// case IProblem.IncompatibleReturnTypeForNonInheritedInterfaceMethod : +// case IProblem.IncompatibleExceptionInThrowsClauseForNonInheritedInterfaceMethod : +// if ((errorThreshold & CompilerOptions.IncompatibleNonInheritedInterfaceMethod) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.IncompatibleNonInheritedInterfaceMethod) != 0){ +// return Warning; +// } +// return Ignore; +// +// case IProblem.OverridingDeprecatedMethod : +// case IProblem.UsingDeprecatedType : +// case IProblem.UsingDeprecatedMethod : +// case IProblem.UsingDeprecatedConstructor : +// case IProblem.UsingDeprecatedField : +// if ((errorThreshold & CompilerOptions.UsingDeprecatedAPI) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.UsingDeprecatedAPI) != 0){ +// return Warning; +// } +// return Ignore; +// +// case IProblem.LocalVariableIsNeverUsed : +// if ((errorThreshold & CompilerOptions.UnusedLocalVariable) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.UnusedLocalVariable) != 0){ +// return Warning; +// } +// return Ignore; +// +// case IProblem.ArgumentIsNeverUsed : +// if ((errorThreshold & CompilerOptions.UnusedArgument) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.UnusedArgument) != 0){ +// return Warning; +// } +// return Ignore; +// +// case IProblem.NoImplicitStringConversionForCharArrayExpression : +// if ((errorThreshold & CompilerOptions.NoImplicitStringConversion) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.NoImplicitStringConversion) != 0){ +// return Warning; +// } +// return Ignore; +// +// case IProblem.NeedToEmulateFieldReadAccess : +// case IProblem.NeedToEmulateFieldWriteAccess : +// case IProblem.NeedToEmulateMethodAccess : +// case IProblem.NeedToEmulateConstructorAccess : +// if ((errorThreshold & CompilerOptions.AccessEmulation) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.AccessEmulation) != 0){ +// return Warning; +// } +// return Ignore; +// case IProblem.NonExternalizedStringLiteral : +// if ((errorThreshold & CompilerOptions.NonExternalizedString) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.NonExternalizedString) != 0){ +// return Warning; +// } +// return Ignore; +// case IProblem.UseAssertAsAnIdentifier : +// if ((errorThreshold & CompilerOptions.AssertUsedAsAnIdentifier) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.AssertUsedAsAnIdentifier) != 0){ +// return Warning; +// } +// return Ignore; +// case IProblem.NonStaticAccessToStaticMethod : +// case IProblem.NonStaticAccessToStaticField : +// if ((errorThreshold & CompilerOptions.StaticAccessReceiver) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.StaticAccessReceiver) != 0){ +// return Warning; +// } +// return Ignore; +// case IProblem.AssignmentHasNoEffect: +// if ((errorThreshold & CompilerOptions.NoEffectAssignment) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.NoEffectAssignment) != 0){ +// return Warning; +// } +// return Ignore; +// case IProblem.UnusedPrivateConstructor: +// case IProblem.UnusedPrivateMethod: +// case IProblem.UnusedPrivateField: +// case IProblem.UnusedPrivateType: +// if ((errorThreshold & CompilerOptions.UnusedPrivateMember) != 0){ +// return Error; +// } +// if ((warningThreshold & CompilerOptions.UnusedPrivateMember) != 0){ +// return Warning; +// } +// return Ignore; +// +// case IProblem.Task : +// return Warning; +// default: +// return Error; +// } +//} +//public void conditionalArgumentsIncompatibleTypes(ConditionalExpression expression, TypeBinding trueType, TypeBinding falseType) { +// this.handle( +// IProblem.IncompatibleTypesInConditionalOperator, +// new String[] {new String(trueType.readableName()), new String(falseType.readableName())}, +// new String[] {new String(trueType.sourceName()), new String(falseType.sourceName())}, +// expression.sourceStart, +// expression.sourceEnd); +//} +public void conflictingImport(ImportReference importRef) { + String[] arguments = new String[] {CharOperation.toString(importRef.tokens)}; + this.handle( + IProblem.ConflictingImport, + arguments, + arguments, + importRef.sourceStart, + importRef.sourceEnd); +} +public void constantOutOfFormat(NumberLiteral lit) { + // the literal is not in a correct format + // this code is called on IntLiteral and LongLiteral + // example 000811 ...the 8 is uncorrect. + + if ((lit instanceof LongLiteral) || (lit instanceof IntLiteral)) { + char[] source = lit.source(); + try { + final String Radix; + final int radix; + if ((source[1] == 'x') || (source[1] == 'X')) { + radix = 16; + Radix = "Hexa"; //$NON-NLS-1$ + } else { + radix = 8; + Radix = "Octal"; //$NON-NLS-1$ + } + //look for the first digit that is incorrect + int place = -1; + label : for (int i = radix == 8 ? 1 : 2; i < source.length; i++) { + if (Character.digit(source[i], radix) == -1) { + place = i; + break label; + } + } + String[] arguments = new String[] {Radix + " " + new String(source) + " (digit " + new String(new char[] {source[place]}) + ")"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + this.handle( + IProblem.NumericValueOutOfRange, + arguments, + arguments, + lit.sourceStart, + lit.sourceEnd); + return; + } catch (IndexOutOfBoundsException ex) {} + + // just in case .... use a predefined error.. + // we should never come here...(except if the code changes !) + this.constantOutOfRange(lit); + } +} +public void constantOutOfRange(Literal lit) { + // lit is some how out of range of it declared type + // example 9999999999999999999999999999999999999999999999999999999999999999999 + String[] arguments = new String[] {new String(lit.source())}; + this.handle( + IProblem.NumericValueOutOfRange, + arguments, + arguments, + lit.sourceStart, + lit.sourceEnd); +} +public void deprecatedField(FieldBinding field, AstNode location) { + this.handle( + IProblem.UsingDeprecatedField, + new String[] {new String(field.declaringClass.readableName()), new String(field.name)}, + new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)}, + location.sourceStart, + location.sourceEnd); +} +public void deprecatedMethod(MethodBinding method, AstNode location) { + if (method.isConstructor()) + this.handle( + IProblem.UsingDeprecatedConstructor, + new String[] {new String(method.declaringClass.readableName()), parametersAsString(method)}, + new String[] {new String(method.declaringClass.shortReadableName()), parametersAsShortString(method)}, + location.sourceStart, + location.sourceEnd); + else + this.handle( + IProblem.UsingDeprecatedMethod, + new String[] {new String(method.declaringClass.readableName()), new String(method.selector), parametersAsString(method)}, + new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), parametersAsShortString(method)}, + location.sourceStart, + location.sourceEnd); +} +public void deprecatedType(TypeBinding type, AstNode location) { + if (location == null) return; // 1G828DN - no type ref for synthetic arguments + this.handle( + IProblem.UsingDeprecatedType, + new String[] {new String(type.readableName())}, + new String[] {new String(type.shortReadableName())}, + location.sourceStart, + location.sourceEnd); +} +public void duplicateCase(Case statement, Constant constant) { + String[] arguments = new String[] {String.valueOf(constant.intValue())}; + this.handle( + IProblem.DuplicateCase, + arguments, + arguments, + statement.sourceStart, + statement.sourceEnd); +} +public void duplicateDefaultCase(DefaultCase statement) { + this.handle( + IProblem.DuplicateDefaultCase, + NoArgument, + NoArgument, + statement.sourceStart, + statement.sourceEnd); +} +public void duplicateFieldInType(SourceTypeBinding type, FieldDeclaration fieldDecl) { + this.handle( + IProblem.DuplicateField, + new String[] {new String(type.sourceName()), fieldDecl.name()}, + new String[] {new String(type.shortReadableName()), fieldDecl.name()}, + fieldDecl.sourceStart, + fieldDecl.sourceEnd); +} +public void duplicateImport(ImportReference importRef) { + String[] arguments = new String[] {CharOperation.toString(importRef.tokens)}; + this.handle( + IProblem.DuplicateImport, + arguments, + arguments, + importRef.sourceStart, + importRef.sourceEnd); +} +public void duplicateInitializationOfBlankFinalField(FieldBinding field, Reference reference) { + String[] arguments = new String[]{ new String(field.readableName())}; + this.handle( + IProblem.DuplicateBlankFinalFieldInitialization, + arguments, + arguments, + reference.sourceStart, + reference.sourceEnd); +} +public void duplicateInitializationOfFinalLocal(LocalVariableBinding local, AstNode location) { + String[] arguments = new String[] { new String(local.readableName())}; + this.handle( + IProblem.DuplicateFinalLocalInitialization, + arguments, + arguments, + location.sourceStart, + location.sourceEnd); +} +public void duplicateMethodInType(SourceTypeBinding type, AbstractMethodDeclaration methodDecl) { + String[] arguments = new String[] {new String(methodDecl.selector), new String(type.sourceName())}; + this.handle( + IProblem.DuplicateMethod, + arguments, + arguments, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void duplicateModifierForField(ReferenceBinding type, FieldDeclaration fieldDecl) { +/* to highlight modifiers use: + this.handle( + new Problem( + DuplicateModifierForField, + new String[] {fieldDecl.name()}, + fieldDecl.modifiers.sourceStart, + fieldDecl.modifiers.sourceEnd)); +*/ + String[] arguments = new String[] {fieldDecl.name()}; + this.handle( + IProblem.DuplicateModifierForField, + arguments, + arguments, + fieldDecl.sourceStart, + fieldDecl.sourceEnd); +} +public void duplicateModifierForMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) { + this.handle( + IProblem.DuplicateModifierForMethod, + new String[] {new String(type.sourceName()), new String(methodDecl.selector)}, + new String[] {new String(type.shortReadableName()), new String(methodDecl.selector)}, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void duplicateModifierForType(SourceTypeBinding type) { + String[] arguments = new String[] {new String(type.sourceName())}; + this.handle( + IProblem.DuplicateModifierForType, + arguments, + arguments, + type.sourceStart(), + type.sourceEnd()); +} +public void duplicateModifierForVariable(LocalDeclaration localDecl, boolean complainForArgument) { + String[] arguments = new String[] {localDecl.name()}; + this.handle( + complainForArgument + ? IProblem.DuplicateModifierForArgument + : IProblem.DuplicateModifierForVariable, + arguments, + arguments, + localDecl.sourceStart, + localDecl.sourceEnd); +} +public void duplicateNestedType(TypeDeclaration typeDecl) { + String[] arguments = new String[] {new String(typeDecl.name)}; + this.handle( + IProblem.DuplicateNestedType, + arguments, + arguments, + typeDecl.sourceStart, + typeDecl.sourceEnd); +} +public void duplicateSuperinterface(SourceTypeBinding type, TypeDeclaration typeDecl, ReferenceBinding superType) { + this.handle( + IProblem.DuplicateSuperInterface, + new String[] { + new String(superType.readableName()), + new String(type.sourceName())}, + new String[] { + new String(superType.shortReadableName()), + new String(type.sourceName())}, + typeDecl.sourceStart, + typeDecl.sourceEnd); +} +public void duplicateTypes(CompilationUnitDeclaration compUnitDecl, TypeDeclaration typeDecl) { + String[] arguments = new String[] {new String(compUnitDecl.getFileName()), new String(typeDecl.name)}; + this.referenceContext = typeDecl; // report the problem against the type not the entire compilation unit + this.handle( + IProblem.DuplicateTypes, + arguments, + arguments, + typeDecl.sourceStart, + typeDecl.sourceEnd, + compUnitDecl.compilationResult); +} +public void errorNoMethodFor(MessageSend messageSend, TypeBinding recType, TypeBinding[] params) { + StringBuffer buffer = new StringBuffer(); + StringBuffer shortBuffer = new StringBuffer(); + for (int i = 0, length = params.length; i < length; i++) { + if (i != 0){ + buffer.append(", "); //$NON-NLS-1$ + shortBuffer.append(", "); //$NON-NLS-1$ + } + buffer.append(new String(params[i].readableName())); + shortBuffer.append(new String(params[i].shortReadableName())); + } + + this.handle( + recType.isArrayType() ? IProblem.NoMessageSendOnArrayType : IProblem.NoMessageSendOnBaseType, + new String[] {new String(recType.readableName()), new String(messageSend.selector), buffer.toString()}, + new String[] {new String(recType.shortReadableName()), new String(messageSend.selector), shortBuffer.toString()}, + messageSend.sourceStart, + messageSend.sourceEnd); +} +public void errorThisSuperInStatic(AstNode reference) { + String[] arguments = new String[] {reference.isSuper() ? "super" : "this"}; //$NON-NLS-2$ //$NON-NLS-1$ + this.handle( + IProblem.ThisInStaticContext, + arguments, + arguments, + reference.sourceStart, + reference.sourceEnd); +} +public void exceptionTypeProblem(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, TypeReference exceptionType, TypeBinding expectedType) { + int problemId = expectedType.problemId(); + int id; + switch (problemId) { + case NotFound : // 1 + id = IProblem.ExceptionTypeNotFound; + break; + case NotVisible : // 2 + id = IProblem.ExceptionTypeNotVisible; + break; + case Ambiguous : // 3 + id = IProblem.ExceptionTypeAmbiguous; + break; + case InternalNameProvided : // 4 + id = IProblem.ExceptionTypeInternalNameProvided; + break; + case InheritedNameHidesEnclosingName : // 5 + id = IProblem.ExceptionTypeInheritedNameHidesEnclosingName; + break; + case NoError : // 0 + default : + needImplementation(); // want to fail to see why we were here... + return; + } + this.handle( + id, + new String[] {new String(methodDecl.selector), new String(expectedType.readableName())}, + new String[] {new String(methodDecl.selector), new String(expectedType.shortReadableName())}, + exceptionType.sourceStart, + exceptionType.sourceEnd); +} +public void expressionShouldBeAVariable(Expression expression) { + this.handle( + IProblem.ExpressionShouldBeAVariable, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void fieldsOrThisBeforeConstructorInvocation(ThisReference reference) { + this.handle( + IProblem.ThisSuperDuringConstructorInvocation, + NoArgument, + NoArgument, + reference.sourceStart, + reference.sourceEnd); +} +public void fieldTypeProblem(SourceTypeBinding type, FieldDeclaration fieldDecl, TypeBinding expectedType) { + int problemId = expectedType.problemId(); + int id; + switch (problemId) { + case NotFound : // 1 + id = IProblem.FieldTypeNotFound; + break; + case NotVisible : // 2 + id = IProblem.FieldTypeNotVisible; + break; + case Ambiguous : // 3 + id = IProblem.FieldTypeAmbiguous; + break; + case InternalNameProvided : // 4 + id = IProblem.FieldTypeInternalNameProvided; + break; + case InheritedNameHidesEnclosingName : // 5 + id = IProblem.FieldTypeInheritedNameHidesEnclosingName; + break; + case NoError : // 0 + default : + needImplementation(); // want to fail to see why we were here... + return; + } + this.handle( + id, + new String[] {fieldDecl.name(), new String(type.sourceName()), new String(expectedType.readableName())}, + new String[] {fieldDecl.name(), new String(type.sourceName()), new String(expectedType.shortReadableName())}, + fieldDecl.type.sourceStart, + fieldDecl.type.sourceEnd); +} +public void finalMethodCannotBeOverridden(MethodBinding currentMethod, MethodBinding inheritedMethod) { + this.handle( + // Cannot override the final method from %1 + // 8.4.3.3 - Final methods cannot be overridden or hidden. + IProblem.FinalMethodCannotBeOverridden, + new String[] {new String(inheritedMethod.declaringClass.readableName())}, + new String[] {new String(inheritedMethod.declaringClass.shortReadableName())}, + currentMethod.sourceStart(), + currentMethod.sourceEnd()); +} +public void forwardReference(Reference reference, int indexInQualification, TypeBinding type) { + this.handle( + IProblem.ReferenceToForwardField, + NoArgument, + NoArgument, + reference.sourceStart, + reference.sourceEnd); +} +// use this private API when the compilation unit result can be found through the +// reference context. Otherwise, use the other API taking a problem and a compilation result +// as arguments + +private void handle( + int problemId, + String[] problemArguments, + String[] messageArguments, + int problemStartPosition, + int problemEndPosition){ + + this.handle( + problemId, + problemArguments, + messageArguments, + problemStartPosition, + problemEndPosition, + referenceContext, + referenceContext == null ? null : referenceContext.compilationResult()); + referenceContext = null; +} +// use this private API when the compilation unit result can be found through the +// reference context. Otherwise, use the other API taking a problem and a compilation result +// as arguments + +private void handle( + int problemId, + String[] problemArguments, + String[] messageArguments, + int severity, + int problemStartPosition, + int problemEndPosition){ + + this.handle( + problemId, + problemArguments, + messageArguments, + severity, + problemStartPosition, + problemEndPosition, + referenceContext, + referenceContext == null ? null : referenceContext.compilationResult()); + referenceContext = null; +} +// use this private API when the compilation unit result cannot be found through the +// reference context. + +private void handle( + int problemId, + String[] problemArguments, + String[] messageArguments, + int problemStartPosition, + int problemEndPosition, + CompilationResult unitResult){ + + this.handle( + problemId, + problemArguments, + messageArguments, + problemStartPosition, + problemEndPosition, + referenceContext, + unitResult); + referenceContext = null; +} +public void hidingEnclosingType(TypeDeclaration typeDecl) { + String[] arguments = new String[] {new String(typeDecl.name)}; + this.handle( + IProblem.HidingEnclosingType, + arguments, + arguments, + typeDecl.sourceStart, + typeDecl.sourceEnd); +} +public void hierarchyCircularity(SourceTypeBinding sourceType, ReferenceBinding superType, TypeReference reference) { + int start = 0; + int end = 0; + String typeName = ""; //$NON-NLS-1$ + String shortTypeName = ""; //$NON-NLS-1$ + + if (reference == null) { // can only happen when java.lang.Object is busted + start = sourceType.sourceStart(); + end = sourceType.sourceEnd(); + typeName = new String(superType.readableName()); + shortTypeName = new String(superType.sourceName()); + } else { + start = reference.sourceStart; + end = reference.sourceEnd; + char[][] qName = reference.getTypeName(); + typeName = CharOperation.toString(qName); + shortTypeName = new String(qName[qName.length-1]); + } + + if (sourceType == superType) + this.handle( + IProblem.HierarchyCircularitySelfReference, + new String[] {new String(sourceType.sourceName()), typeName}, + new String[] {new String(sourceType.sourceName()), shortTypeName}, + start, + end); + else + this.handle( + IProblem.HierarchyCircularity, + new String[] {new String(sourceType.sourceName()), typeName}, + new String[] {new String(sourceType.sourceName()), shortTypeName}, + start, + end); +} +public void hierarchyHasProblems(SourceTypeBinding type) { + String[] arguments = new String[] {new String(type.sourceName())}; + this.handle( + IProblem.HierarchyHasProblems, + arguments, + arguments, + type.sourceStart(), + type.sourceEnd()); +} +public void illegalAbstractModifierCombinationForMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) { + String[] arguments = new String[] {new String(type.sourceName()), new String(methodDecl.selector)}; + this.handle( + IProblem.IllegalAbstractModifierCombinationForMethod, + arguments, + arguments, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void illegalModifierCombinationFinalAbstractForClass(SourceTypeBinding type) { + String[] arguments = new String[] {new String(type.sourceName())}; + this.handle( + IProblem.IllegalModifierCombinationFinalAbstractForClass, + arguments, + arguments, + type.sourceStart(), + type.sourceEnd()); +} +public void illegalModifierCombinationFinalVolatileForField(ReferenceBinding type, FieldDeclaration fieldDecl) { + String[] arguments = new String[] {fieldDecl.name()}; + + this.handle( + IProblem.IllegalModifierCombinationFinalVolatileForField, + arguments, + arguments, + fieldDecl.sourceStart, + fieldDecl.sourceEnd); +} + +public void illegalModifierForClass(SourceTypeBinding type) { + String[] arguments = new String[] {new String(type.sourceName())}; + this.handle( + IProblem.IllegalModifierForClass, + arguments, + arguments, + type.sourceStart(), + type.sourceEnd()); +} +public void illegalModifierForField(ReferenceBinding type, FieldDeclaration fieldDecl) { + String[] arguments = new String[] {fieldDecl.name()}; + this.handle( + IProblem.IllegalModifierForField, + arguments, + arguments, + fieldDecl.sourceStart, + fieldDecl.sourceEnd); +} +public void illegalModifierForInterface(SourceTypeBinding type) { + String[] arguments = new String[] {new String(type.sourceName())}; + this.handle( + IProblem.IllegalModifierForInterface, + arguments, + arguments, + type.sourceStart(), + type.sourceEnd()); +} +public void illegalModifierForInterfaceField(ReferenceBinding type, FieldDeclaration fieldDecl) { + String[] arguments = new String[] {fieldDecl.name()}; + this.handle( + IProblem.IllegalModifierForInterfaceField, + arguments, + arguments, + fieldDecl.sourceStart, + fieldDecl.sourceEnd); +} +public void illegalModifierForInterfaceMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) { + String[] arguments = new String[] {new String(type.sourceName()), new String(methodDecl.selector)}; + this.handle( + IProblem.IllegalModifierForInterfaceMethod, + arguments, + arguments, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void illegalModifierForLocalClass(SourceTypeBinding type) { + String[] arguments = new String[] {new String(type.sourceName())}; + this.handle( + IProblem.IllegalModifierForLocalClass, + arguments, + arguments, + type.sourceStart(), + type.sourceEnd()); +} +public void illegalModifierForMemberClass(SourceTypeBinding type) { + String[] arguments = new String[] {new String(type.sourceName())}; + this.handle( + IProblem.IllegalModifierForMemberClass, + arguments, + arguments, + type.sourceStart(), + type.sourceEnd()); +} +public void illegalModifierForMemberInterface(SourceTypeBinding type) { + String[] arguments = new String[] {new String(type.sourceName())}; + this.handle( + IProblem.IllegalModifierForMemberInterface, + arguments, + arguments, + type.sourceStart(), + type.sourceEnd()); +} +public void illegalModifierForMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) { + String[] arguments = new String[] {new String(type.sourceName()), new String(methodDecl.selector)}; + this.handle( + IProblem.IllegalModifierForMethod, + arguments, + arguments, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void illegalModifierForVariable(LocalDeclaration localDecl, boolean complainAsArgument) { + String[] arguments = new String[] {localDecl.name()}; + this.handle( + complainAsArgument + ? IProblem.IllegalModifierForArgument + : IProblem.IllegalModifierForVariable, + arguments, + arguments, + localDecl.sourceStart, + localDecl.sourceEnd); +} +public void illegalPrimitiveOrArrayTypeForEnclosingInstance(TypeBinding enclosingType, AstNode location) { + this.handle( + IProblem.IllegalPrimitiveOrArrayTypeForEnclosingInstance, + new String[] {new String(enclosingType.readableName())}, + new String[] {new String(enclosingType.shortReadableName())}, + location.sourceStart, + location.sourceEnd); +} +public void illegalStaticModifierForMemberType(SourceTypeBinding type) { + String[] arguments = new String[] {new String(type.sourceName())}; + this.handle( + IProblem.IllegalStaticModifierForMemberType, + arguments, + arguments, + type.sourceStart(), + type.sourceEnd()); +} +public void illegalVisibilityModifierCombinationForField(ReferenceBinding type, FieldDeclaration fieldDecl) { + String[] arguments = new String[] {new String(fieldDecl.name())}; + this.handle( + IProblem.IllegalVisibilityModifierCombinationForField, + arguments, + arguments, + fieldDecl.sourceStart, + fieldDecl.sourceEnd); +} +public void illegalVisibilityModifierCombinationForMemberType(SourceTypeBinding type) { + String[] arguments = new String[] {new String(type.sourceName())}; + this.handle( + IProblem.IllegalVisibilityModifierCombinationForMemberType, + arguments, + arguments, + type.sourceStart(), + type.sourceEnd()); +} +public void illegalVisibilityModifierCombinationForMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) { + String[] arguments = new String[] {new String(type.sourceName()), new String(methodDecl.selector)}; + this.handle( + IProblem.IllegalVisibilityModifierCombinationForMethod, + arguments, + arguments, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void illegalVisibilityModifierForInterfaceMemberType(SourceTypeBinding type) { + String[] arguments = new String[] {new String(type.sourceName())}; + this.handle( + IProblem.IllegalVisibilityModifierForInterfaceMemberType, + arguments, + arguments, + type.sourceStart(), + type.sourceEnd()); +} +public void illegalVoidExpression(AstNode location) { + this.handle( + IProblem.InvalidVoidExpression, + NoArgument, + NoArgument, + location.sourceStart, + location.sourceEnd); +} +public void importProblem(ImportReference importRef, Binding expectedImport) { + int problemId = expectedImport.problemId(); + int id; + switch (problemId) { + case NotFound : // 1 + id = IProblem.ImportNotFound; + break; + case NotVisible : // 2 + id = IProblem.ImportNotVisible; + break; + case Ambiguous : // 3 + id = IProblem.ImportAmbiguous; + break; + case InternalNameProvided : // 4 + id = IProblem.ImportInternalNameProvided; + break; + case InheritedNameHidesEnclosingName : // 5 + id = IProblem.ImportInheritedNameHidesEnclosingName; + break; + case NoError : // 0 + default : + needImplementation(); // want to fail to see why we were here... + return; + } + String argument; + if(expectedImport instanceof ProblemReferenceBinding) { + argument = CharOperation.toString(((ProblemReferenceBinding)expectedImport).compoundName); + } else { + argument = CharOperation.toString(importRef.tokens); + } + String[] arguments = new String[]{argument}; + this.handle(id, arguments, arguments, importRef.sourceStart, importRef.sourceEnd); +} +public void incompatibleExceptionInThrowsClause(SourceTypeBinding type, MethodBinding currentMethod, MethodBinding inheritedMethod, ReferenceBinding exceptionType) { + if (type == currentMethod.declaringClass) { + int id; + if (currentMethod.declaringClass.isInterface() + && !inheritedMethod.isPublic()){ // interface inheriting Object protected method + id = IProblem.IncompatibleExceptionInThrowsClauseForNonInheritedInterfaceMethod; + } else { + id = IProblem.IncompatibleExceptionInThrowsClause; + } + this.handle( + // Exception %1 is not compatible with throws clause in %2 + // 9.4.4 - The type of exception in the throws clause is incompatible. + id, + new String[] { + new String(exceptionType.sourceName()), + new String( + CharOperation.concat( + inheritedMethod.declaringClass.readableName(), + inheritedMethod.readableName(), + '.'))}, + new String[] { + new String(exceptionType.sourceName()), + new String( + CharOperation.concat( + inheritedMethod.declaringClass.shortReadableName(), + inheritedMethod.shortReadableName(), + '.'))}, + currentMethod.sourceStart(), + currentMethod.sourceEnd()); + } else + this.handle( + // Exception %1 in throws clause of %2 is not compatible with %3 + // 9.4.4 - The type of exception in the throws clause is incompatible. + IProblem.IncompatibleExceptionInInheritedMethodThrowsClause, + new String[] { + new String(exceptionType.sourceName()), + new String( + CharOperation.concat( + currentMethod.declaringClass.sourceName(), + currentMethod.readableName(), + '.')), + new String( + CharOperation.concat( + inheritedMethod.declaringClass.readableName(), + inheritedMethod.readableName(), + '.'))}, + new String[] { + new String(exceptionType.sourceName()), + new String( + CharOperation.concat( + currentMethod.declaringClass.sourceName(), + currentMethod.shortReadableName(), + '.')), + new String( + CharOperation.concat( + inheritedMethod.declaringClass.shortReadableName(), + inheritedMethod.shortReadableName(), + '.'))}, + type.sourceStart(), + type.sourceEnd()); +} +public void incompatibleReturnType(MethodBinding currentMethod, MethodBinding inheritedMethod) { + StringBuffer methodSignature = new StringBuffer(); + methodSignature + .append(inheritedMethod.declaringClass.readableName()) + .append('.') + .append(inheritedMethod.readableName()); + + StringBuffer shortSignature = new StringBuffer(); + shortSignature + .append(inheritedMethod.declaringClass.shortReadableName()) + .append('.') + .append(inheritedMethod.shortReadableName()); + + int id; + if (currentMethod.declaringClass.isInterface() + && !inheritedMethod.isPublic()){ // interface inheriting Object protected method + id = IProblem.IncompatibleReturnTypeForNonInheritedInterfaceMethod; + } else { + id = IProblem.IncompatibleReturnType; + } + this.handle( + id, + new String[] {methodSignature.toString()}, + new String[] {shortSignature.toString()}, + currentMethod.sourceStart(), + currentMethod.sourceEnd()); +} +public void incorrectLocationForEmptyDimension(ArrayAllocationExpression expression, int index) { + this.handle( + IProblem.IllegalDimension, + NoArgument, + NoArgument, + expression.dimensions[index + 1].sourceStart, + expression.dimensions[index + 1].sourceEnd); +} +public void incorrectSwitchType(Expression expression, TypeBinding testType) { + this.handle( + IProblem.IncorrectSwitchType, + new String[] {new String(testType.readableName())}, + new String[] {new String(testType.shortReadableName())}, + expression.sourceStart, + expression.sourceEnd); +} +public void inheritedMethodReducesVisibility(SourceTypeBinding type, MethodBinding concreteMethod, MethodBinding[] abstractMethods) { + StringBuffer concreteSignature = new StringBuffer(); + concreteSignature + .append(concreteMethod.declaringClass.readableName()) + .append('.') + .append(concreteMethod.readableName()); + StringBuffer shortSignature = new StringBuffer(); + shortSignature + .append(concreteMethod.declaringClass.shortReadableName()) + .append('.') + .append(concreteMethod.shortReadableName()); + this.handle( + // The inherited method %1 cannot hide the public abstract method in %2 + IProblem.InheritedMethodReducesVisibility, + new String[] { + new String(concreteSignature.toString()), + new String(abstractMethods[0].declaringClass.readableName())}, + new String[] { + new String(shortSignature.toString()), + new String(abstractMethods[0].declaringClass.shortReadableName())}, + type.sourceStart(), + type.sourceEnd()); +} +public void inheritedMethodsHaveIncompatibleReturnTypes(SourceTypeBinding type, MethodBinding[] inheritedMethods, int length) { + StringBuffer methodSignatures = new StringBuffer(); + StringBuffer shortSignatures = new StringBuffer(); + for (int i = length; --i >= 0;) { + methodSignatures + .append(inheritedMethods[i].declaringClass.readableName()) + .append('.') + .append(inheritedMethods[i].readableName()); + shortSignatures + .append(inheritedMethods[i].declaringClass.shortReadableName()) + .append('.') + .append(inheritedMethods[i].shortReadableName()); + if (i != 0){ + methodSignatures.append(", "); //$NON-NLS-1$ + shortSignatures.append(", "); //$NON-NLS-1$ + } + } + + this.handle( + // Return type is incompatible with %1 + // 9.4.2 - The return type from the method is incompatible with the declaration. + IProblem.IncompatibleReturnType, + new String[] {methodSignatures.toString()}, + new String[] {shortSignatures.toString()}, + type.sourceStart(), + type.sourceEnd()); +} +public void initializerMustCompleteNormally(FieldDeclaration fieldDecl) { + this.handle( + IProblem.InitializerMustCompleteNormally, + NoArgument, + NoArgument, + fieldDecl.sourceStart, + fieldDecl.sourceEnd); +} +public void innerTypesCannotDeclareStaticInitializers(ReferenceBinding innerType, AstNode location) { + this.handle( + IProblem.CannotDefineStaticInitializerInLocalType, + new String[] {new String(innerType.readableName())}, + new String[] {new String(innerType.shortReadableName())}, + location.sourceStart, + location.sourceEnd); +} +public void interfaceCannotHaveConstructors(ConstructorDeclaration constructor) { + this.handle( + IProblem.InterfaceCannotHaveConstructors, + NoArgument, + NoArgument, + constructor.sourceStart, + constructor.sourceEnd, + constructor, + constructor.compilationResult()); +} +public void interfaceCannotHaveInitializers(SourceTypeBinding type, FieldDeclaration fieldDecl) { + String[] arguments = new String[] {new String(type.sourceName())}; + + this.handle( + IProblem.InterfaceCannotHaveInitializers, + arguments, + arguments, + fieldDecl.sourceStart, + fieldDecl.sourceEnd); +} +public void invalidBreak(AstNode location) { + this.handle( + IProblem.InvalidBreak, + NoArgument, + NoArgument, + location.sourceStart, + location.sourceEnd); +} +public void invalidConstructor(Statement statement, MethodBinding targetConstructor) { + + boolean insideDefaultConstructor = + (referenceContext instanceof ConstructorDeclaration) + && ((ConstructorDeclaration)referenceContext).isDefaultConstructor(); + boolean insideImplicitConstructorCall = + (statement instanceof ExplicitConstructorCall) + && (((ExplicitConstructorCall) statement).accessMode == ExplicitConstructorCall.ImplicitSuper); + + int flag = IProblem.UndefinedConstructor; //default... + switch (targetConstructor.problemId()) { + case NotFound : + if (insideDefaultConstructor){ + flag = IProblem.UndefinedConstructorInDefaultConstructor; + } else if (insideImplicitConstructorCall){ + flag = IProblem.UndefinedConstructorInImplicitConstructorCall; + } else { + flag = IProblem.UndefinedConstructor; + } + break; + case NotVisible : + if (insideDefaultConstructor){ + flag = IProblem.NotVisibleConstructorInDefaultConstructor; + } else if (insideImplicitConstructorCall){ + flag = IProblem.NotVisibleConstructorInImplicitConstructorCall; + } else { + flag = IProblem.NotVisibleConstructor; + } + break; + case Ambiguous : + if (insideDefaultConstructor){ + flag = IProblem.AmbiguousConstructorInDefaultConstructor; + } else if (insideImplicitConstructorCall){ + flag = IProblem.AmbiguousConstructorInImplicitConstructorCall; + } else { + flag = IProblem.AmbiguousConstructor; + } + break; + case NoError : // 0 + default : + needImplementation(); // want to fail to see why we were here... + break; + } + + + this.handle( + flag, + new String[] {new String(targetConstructor.declaringClass.readableName()), parametersAsString(targetConstructor)}, + new String[] {new String(targetConstructor.declaringClass.shortReadableName()), parametersAsShortString(targetConstructor)}, + statement.sourceStart, + statement.sourceEnd); +} +public void invalidContinue(AstNode location) { + this.handle( + IProblem.InvalidContinue, + NoArgument, + NoArgument, + location.sourceStart, + location.sourceEnd); +} +public void invalidEnclosingType(Expression expression, TypeBinding type, ReferenceBinding enclosingType) { + + if (enclosingType.isAnonymousType()) enclosingType = enclosingType.superclass(); + int flag = IProblem.UndefinedType; // default + switch (type.problemId()) { + case NotFound : // 1 + flag = IProblem.UndefinedType; + break; + case NotVisible : // 2 + flag = IProblem.NotVisibleType; + break; + case Ambiguous : // 3 + flag = IProblem.AmbiguousType; + break; + case InternalNameProvided : + flag = IProblem.InternalTypeNameProvided; + break; + case NoError : // 0 + default : + needImplementation(); // want to fail to see why we were here... + break; + } + + this.handle( + flag, + new String[] {new String(enclosingType.readableName()) + "." + new String(type.readableName())}, //$NON-NLS-1$ + new String[] {new String(enclosingType.shortReadableName()) + "." + new String(type.shortReadableName())}, //$NON-NLS-1$ + expression.sourceStart, + expression.sourceEnd); +} +public void invalidExpressionAsStatement(Expression expression){ + this.handle( + IProblem.InvalidExpressionAsStatement, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void invalidField(FieldReference fieldRef, TypeBinding searchedType) { + int severity = Error; + int flag = IProblem.UndefinedField; + FieldBinding field = fieldRef.binding; + switch (field.problemId()) { + case NotFound : + flag = IProblem.UndefinedField; +/* also need to check that the searchedType is the receiver type + if (searchedType.isHierarchyInconsistent()) + severity = SecondaryError; +*/ + break; + case NotVisible : + flag = IProblem.NotVisibleField; + break; + case Ambiguous : + flag = IProblem.AmbiguousField; + break; + case NonStaticReferenceInStaticContext : + flag = IProblem.NonStaticFieldFromStaticInvocation; + break; + case NonStaticReferenceInConstructorInvocation : + flag = IProblem.InstanceFieldDuringConstructorInvocation; + break; + case InheritedNameHidesEnclosingName : + flag = IProblem.InheritedFieldHidesEnclosingName; + break; + case ReceiverTypeNotVisible : + this.handle( + IProblem.NotVisibleType, + new String[] {new String(searchedType.leafComponentType().readableName())}, + new String[] {new String(searchedType.leafComponentType().shortReadableName())}, + fieldRef.receiver.sourceStart, + fieldRef.receiver.sourceEnd); + return; + + case NoError : // 0 + default : + needImplementation(); // want to fail to see why we were here... + break; + } + + String[] arguments = new String[] {new String(field.readableName())}; + this.handle( + flag, + arguments, + arguments, + severity, + fieldRef.sourceStart, + fieldRef.sourceEnd); +} +public void invalidField(NameReference nameRef, FieldBinding field) { + int flag = IProblem.UndefinedField; + switch (field.problemId()) { + case NotFound : + flag = IProblem.UndefinedField; + break; + case NotVisible : + flag = IProblem.NotVisibleField; + break; + case Ambiguous : + flag = IProblem.AmbiguousField; + break; + case NonStaticReferenceInStaticContext : + flag = IProblem.NonStaticFieldFromStaticInvocation; + break; + case NonStaticReferenceInConstructorInvocation : + flag = IProblem.InstanceFieldDuringConstructorInvocation; + break; + case InheritedNameHidesEnclosingName : + flag = IProblem.InheritedFieldHidesEnclosingName; + break; + case ReceiverTypeNotVisible : + this.handle( + IProblem.NotVisibleType, + new String[] {new String(field.declaringClass.leafComponentType().readableName())}, + new String[] {new String(field.declaringClass.leafComponentType().shortReadableName())}, + nameRef.sourceStart, + nameRef.sourceEnd); + return; + case NoError : // 0 + default : + needImplementation(); // want to fail to see why we were here... + break; + } + String[] arguments = new String[] {new String(field.readableName())}; + this.handle( + flag, + arguments, + arguments, + nameRef.sourceStart, + nameRef.sourceEnd); +} +public void invalidField(QualifiedNameReference nameRef, FieldBinding field, int index, TypeBinding searchedType) { + //the resolution of the index-th field of qname failed + //qname.otherBindings[index] is the binding that has produced the error + + //The different targetted errors should be : + //UndefinedField + //NotVisibleField + //AmbiguousField + + if (searchedType.isBaseType()) { + this.handle( + IProblem.NoFieldOnBaseType, + new String[] { + new String(searchedType.readableName()), + CharOperation.toString(CharOperation.subarray(nameRef.tokens, 0, index)), + new String(nameRef.tokens[index])}, + new String[] { + new String(searchedType.sourceName()), + CharOperation.toString(CharOperation.subarray(nameRef.tokens, 0, index)), + new String(nameRef.tokens[index])}, + nameRef.sourceStart, + nameRef.sourceEnd); + return; + } + + int flag = IProblem.UndefinedField; + switch (field.problemId()) { + case NotFound : + flag = IProblem.UndefinedField; +/* also need to check that the searchedType is the receiver type + if (searchedType.isHierarchyInconsistent()) + severity = SecondaryError; +*/ + break; + case NotVisible : + flag = IProblem.NotVisibleField; + break; + case Ambiguous : + flag = IProblem.AmbiguousField; + break; + case NonStaticReferenceInStaticContext : + flag = IProblem.NonStaticFieldFromStaticInvocation; + break; + case NonStaticReferenceInConstructorInvocation : + flag = IProblem.InstanceFieldDuringConstructorInvocation; + break; + case InheritedNameHidesEnclosingName : + flag = IProblem.InheritedFieldHidesEnclosingName; + break; + case ReceiverTypeNotVisible : + this.handle( + IProblem.NotVisibleType, + new String[] {new String(searchedType.leafComponentType().readableName())}, + new String[] {new String(searchedType.leafComponentType().shortReadableName())}, + nameRef.sourceStart, + nameRef.sourceEnd); + return; + case NoError : // 0 + default : + needImplementation(); // want to fail to see why we were here... + break; + } + String[] arguments = new String[] {CharOperation.toString(CharOperation.subarray(nameRef.tokens, 0, index + 1))}; + this.handle( + flag, + arguments, + arguments, + nameRef.sourceStart, + nameRef.sourceEnd); +} +public void invalidMethod(MessageSend messageSend, MethodBinding method) { + // CODE should be UPDATED according to error coding in the different method binding errors + // The different targetted errors should be : + // UndefinedMethod + // NotVisibleMethod + // AmbiguousMethod + // InheritedNameHidesEnclosingName + // InstanceMethodDuringConstructorInvocation + // StaticMethodRequested + + int flag = IProblem.UndefinedMethod; //default... + switch (method.problemId()) { + case NotFound : + flag = IProblem.UndefinedMethod; + break; + case NotVisible : + flag = IProblem.NotVisibleMethod; + break; + case Ambiguous : + flag = IProblem.AmbiguousMethod; + break; + case InheritedNameHidesEnclosingName : + flag = IProblem.InheritedMethodHidesEnclosingName; + break; + case NonStaticReferenceInConstructorInvocation : + flag = IProblem.InstanceMethodDuringConstructorInvocation; + break; + case NonStaticReferenceInStaticContext : + flag = IProblem.StaticMethodRequested; + break; + case ReceiverTypeNotVisible : + this.handle( + IProblem.NotVisibleType, + new String[] {new String(method.declaringClass.leafComponentType().readableName())}, + new String[] {new String(method.declaringClass.leafComponentType().shortReadableName())}, + messageSend.receiver.sourceStart, + messageSend.receiver.sourceEnd); + return; + + case NoError : // 0 + default : + needImplementation(); // want to fail to see why we were here... + break; + } + + if (flag == IProblem.UndefinedMethod) { + ProblemMethodBinding problemMethod = (ProblemMethodBinding) method; + if (problemMethod.closestMatch != null) { + String closestParameterTypeNames = parametersAsString(problemMethod.closestMatch); + String parameterTypeNames = parametersAsString(method); + String closestParameterTypeShortNames = parametersAsShortString(problemMethod.closestMatch); + String parameterTypeShortNames = parametersAsShortString(method); + if (closestParameterTypeShortNames.equals(parameterTypeShortNames)){ + closestParameterTypeShortNames = closestParameterTypeNames; + parameterTypeShortNames = parameterTypeNames; + } + this.handle( + IProblem.ParameterMismatch, + new String[] { + new String(problemMethod.closestMatch.declaringClass.readableName()), + new String(problemMethod.closestMatch.selector), + closestParameterTypeNames, + parameterTypeNames + }, + new String[] { + new String(problemMethod.closestMatch.declaringClass.shortReadableName()), + new String(problemMethod.closestMatch.selector), + closestParameterTypeShortNames, + parameterTypeShortNames + }, + (int) (messageSend.nameSourcePosition >>> 32), + (int) messageSend.nameSourcePosition); + return; + } + } + + this.handle( + flag, + new String[] { + new String(method.declaringClass.readableName()), + new String(method.selector), parametersAsString(method)}, + new String[] { + new String(method.declaringClass.shortReadableName()), + new String(method.selector), parametersAsShortString(method)}, + (int) (messageSend.nameSourcePosition >>> 32), + (int) messageSend.nameSourcePosition); +} +public void invalidNullToSynchronize(Expression expression) { + this.handle( + IProblem.InvalidNullToSynchronized, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void invalidOperator(BinaryExpression expression, TypeBinding leftType, TypeBinding rightType) { + String leftName = new String(leftType.readableName()); + String rightName = new String(rightType.readableName()); + String leftShortName = new String(leftType.shortReadableName()); + String rightShortName = new String(rightType.shortReadableName()); + if (leftShortName.equals(rightShortName)){ + leftShortName = leftName; + rightShortName = rightName; + } + this.handle( + IProblem.InvalidOperator, + new String[] { + expression.operatorToString(), + leftName + ", " + rightName}, //$NON-NLS-1$ + new String[] { + expression.operatorToString(), + leftShortName + ", " + rightShortName}, //$NON-NLS-1$ + expression.sourceStart, + expression.sourceEnd); +} +public void invalidOperator(CompoundAssignment assign, TypeBinding leftType, TypeBinding rightType) { + String leftName = new String(leftType.readableName()); + String rightName = new String(rightType.readableName()); + String leftShortName = new String(leftType.shortReadableName()); + String rightShortName = new String(rightType.shortReadableName()); + if (leftShortName.equals(rightShortName)){ + leftShortName = leftName; + rightShortName = rightName; + } + this.handle( + IProblem.InvalidOperator, + new String[] { + assign.operatorToString(), + leftName + ", " + rightName}, //$NON-NLS-1$ + new String[] { + assign.operatorToString(), + leftShortName + ", " + rightShortName}, //$NON-NLS-1$ + assign.sourceStart, + assign.sourceEnd); +} +public void invalidOperator(UnaryExpression expression, TypeBinding type) { + this.handle( + IProblem.InvalidOperator, + new String[] {expression.operatorToString(), new String(type.readableName())}, + new String[] {expression.operatorToString(), new String(type.shortReadableName())}, + expression.sourceStart, + expression.sourceEnd); +} +public void invalidParenthesizedExpression(AstNode reference) { + this.handle( + IProblem.InvalidParenthesizedExpression, + NoArgument, + NoArgument, + reference.sourceStart, + reference.sourceEnd); +} +public void invalidSuperclass(SourceTypeBinding type, TypeReference superclassRef, ReferenceBinding expectedType) { + int problemId = expectedType.problemId(); + int id; + switch (problemId) { + case NotFound : // 1 + id = IProblem.SuperclassNotFound; + break; + case NotVisible : // 2 + id = IProblem.SuperclassNotVisible; + break; + case Ambiguous : // 3 + id = IProblem.SuperclassAmbiguous; + break; + case InternalNameProvided : // 4 + id = IProblem.SuperclassInternalNameProvided; + break; + case InheritedNameHidesEnclosingName : // 5 + id = IProblem.SuperclassInheritedNameHidesEnclosingName; + break; + case NoError : // 0 + default : + needImplementation(); // want to fail to see why we were here... + return; + } + this.handle( + id, + new String[] {new String(expectedType.readableName()), new String(type.sourceName())}, + new String[] {new String(expectedType.shortReadableName()), new String(type.sourceName())}, + superclassRef.sourceStart, + superclassRef.sourceEnd); +} +public void invalidSuperinterface(SourceTypeBinding type, TypeReference superinterfaceRef, ReferenceBinding expectedType) { + int problemId = expectedType.problemId(); + int id; + switch (problemId) { + case NotFound : // 1 + id = IProblem.InterfaceNotFound; + break; + case NotVisible : // 2 + id = IProblem.InterfaceNotVisible; + break; + case Ambiguous : // 3 + id = IProblem.InterfaceAmbiguous; + break; + case InternalNameProvided : // 4 + id = IProblem.InterfaceInternalNameProvided; + break; + case InheritedNameHidesEnclosingName : // 5 + id = IProblem.InterfaceInheritedNameHidesEnclosingName; + break; + case NoError : // 0 + default : + needImplementation(); // want to fail to see why we were here... + return; + } + this.handle( + id, + new String[] {new String(expectedType.readableName()), new String(type.sourceName())}, + new String[] {new String(expectedType.shortReadableName()), new String(type.sourceName())}, + superinterfaceRef.sourceStart, + superinterfaceRef.sourceEnd); +} +public void invalidType(AstNode location, TypeBinding type) { + int flag = IProblem.UndefinedType; // default + switch (type.problemId()) { + case NotFound : + flag = IProblem.UndefinedType; + break; + case NotVisible : + flag = IProblem.NotVisibleType; + break; + case Ambiguous : + flag = IProblem.AmbiguousType; + break; + case InternalNameProvided : + flag = IProblem.InternalTypeNameProvided; + break; + case InheritedNameHidesEnclosingName : + flag = IProblem.InheritedTypeHidesEnclosingName; + break; + case NoError : // 0 + default : + needImplementation(); // want to fail to see why we were here... + break; + } + + this.handle( + flag, + new String[] {new String(type.readableName())}, + new String[] {new String(type.shortReadableName())}, + location.sourceStart, + location.sourceEnd); +} +public void invalidTypeReference(Expression expression) { + this.handle( + IProblem.InvalidTypeExpression, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void invalidTypeToSynchronize(Expression expression, TypeBinding type) { + this.handle( + IProblem.InvalidTypeToSynchronized, + new String[] {new String(type.readableName())}, + new String[] {new String(type.shortReadableName())}, + expression.sourceStart, + expression.sourceEnd); +} +public void invalidUnaryExpression(Expression expression) { + this.handle( + IProblem.InvalidUnaryExpression, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void isClassPathCorrect(char[][] wellKnownTypeName, CompilationUnitDeclaration compUnitDecl) { + referenceContext = compUnitDecl; + String[] arguments = new String[] {CharOperation.toString(wellKnownTypeName)}; + this.handle( + IProblem.IsClassPathCorrect, + arguments, + arguments, + AbortCompilation | Error, + compUnitDecl == null ? 0 : compUnitDecl.sourceStart, + compUnitDecl == null ? 1 : compUnitDecl.sourceEnd); +} +public void maskedExceptionHandler(ReferenceBinding exceptionType, AstNode location) { + this.handle( + IProblem.MaskedCatch, + NoArgument, + NoArgument, + location.sourceStart, + location.sourceEnd); +} +public void methodNeedingAbstractModifier(MethodDeclaration methodDecl) { + this.handle( + IProblem.MethodRequiresBody, + NoArgument, + NoArgument, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void methodNeedingNoBody(MethodDeclaration methodDecl) { + this.handle( +// ((methodDecl.modifiers & CompilerModifiers.AccNative) != 0) ? IProblem.BodyForNativeMethod : IProblem.BodyForAbstractMethod, + IProblem.BodyForAbstractMethod, + NoArgument, + NoArgument, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void methodWithConstructorName(MethodDeclaration methodDecl) { + this.handle( + IProblem.MethodButWithConstructorName, + NoArgument, + NoArgument, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +//public void missingEnclosingInstanceSpecification(ReferenceBinding enclosingType, AstNode location) { +// boolean insideConstructorCall = +// (location instanceof ExplicitConstructorCall) +// && (((ExplicitConstructorCall) location).accessMode == ExplicitConstructorCall.ImplicitSuper); +// +// this.handle( +// insideConstructorCall +// ? IProblem.MissingEnclosingInstanceForConstructorCall +// : IProblem.MissingEnclosingInstance, +// new String[] {new String(enclosingType.readableName())}, +// new String[] {new String(enclosingType.shortReadableName())}, +// location.sourceStart, +// location.sourceEnd); +//} +public void missingReturnType(AbstractMethodDeclaration methodDecl) { + this.handle( + IProblem.MissingReturnType, + NoArgument, + NoArgument, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void missingSemiColon(Expression expression){ + this.handle( + IProblem.MissingSemiColon, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void mustDefineDimensionsOrInitializer(ArrayAllocationExpression expression) { + this.handle( + IProblem.MustDefineEitherDimensionExpressionsOrInitializer, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void mustSpecifyPackage(CompilationUnitDeclaration compUnitDecl) { + String[] arguments = new String[] {new String(compUnitDecl.getFileName())}; + this.handle( + IProblem.MustSpecifyPackage, + arguments, + arguments, + compUnitDecl.sourceStart, + compUnitDecl.sourceStart + 1); +} +public void mustUseAStaticMethod(MessageSend messageSend, MethodBinding method) { + this.handle( + IProblem.StaticMethodRequested, + new String[] {new String(method.declaringClass.readableName()), new String(method.selector), parametersAsString(method)}, + new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), parametersAsShortString(method)}, + messageSend.sourceStart, + messageSend.sourceEnd); +} + +public void nativeMethodsCannotBeStrictfp(ReferenceBinding type, AbstractMethodDeclaration methodDecl) { + String[] arguments = new String[] {new String(type.sourceName()), new String(methodDecl.selector)}; + this.handle( + IProblem.NativeMethodsCannotBeStrictfp, + arguments, + arguments, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void needImplementation() { + this.abortDueToInternalError(Util.bind("abort.missingCode")); //$NON-NLS-1$ +} +public void needToEmulateFieldReadAccess(FieldBinding field, AstNode location) { + this.handle( + IProblem.NeedToEmulateFieldReadAccess, + new String[] {new String(field.declaringClass.readableName()), new String(field.name)}, + new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)}, + location.sourceStart, + location.sourceEnd); +} +public void needToEmulateFieldWriteAccess(FieldBinding field, AstNode location) { + this.handle( + IProblem.NeedToEmulateFieldWriteAccess, + new String[] {new String(field.declaringClass.readableName()), new String(field.name)}, + new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)}, + location.sourceStart, + location.sourceEnd); +} +public void needToEmulateMethodAccess( + MethodBinding method, + AstNode location) { + + if (method.isConstructor()) + this.handle( + IProblem.NeedToEmulateConstructorAccess, + new String[] { + new String(method.declaringClass.readableName()), + parametersAsString(method) + }, + new String[] { + new String(method.declaringClass.shortReadableName()), + parametersAsShortString(method) + }, + location.sourceStart, + location.sourceEnd); + else + this.handle( + IProblem.NeedToEmulateMethodAccess, + new String[] { + new String(method.declaringClass.readableName()), + new String(method.selector), + parametersAsString(method) + }, + new String[] { + new String(method.declaringClass.shortReadableName()), + new String(method.selector), + parametersAsShortString(method) + }, + location.sourceStart, + location.sourceEnd); +} +public void nestedClassCannotDeclareInterface(TypeDeclaration typeDecl) { + String[] arguments = new String[] {new String(typeDecl.name)}; + this.handle( + IProblem.CannotDefineInterfaceInLocalType, + arguments, + arguments, + typeDecl.sourceStart, + typeDecl.sourceEnd); +} +public void noMoreAvailableSpaceForArgument(LocalVariableBinding local, AstNode location) { + String[] arguments = new String[]{ new String(local.name) }; + this.handle( + local instanceof SyntheticArgumentBinding + ? IProblem.TooManySyntheticArgumentSlots + : IProblem.TooManyArgumentSlots, + arguments, + arguments, + Abort | Error, + location.sourceStart, + location.sourceEnd); +} +public void noMoreAvailableSpaceForLocal(LocalVariableBinding local, AstNode location) { + String[] arguments = new String[]{ new String(local.name) }; + this.handle( + IProblem.TooManyLocalVariableSlots, + arguments, + arguments, + Abort | Error, + location.sourceStart, + location.sourceEnd); +} +public void noSuchEnclosingInstance(TypeBinding targetType, AstNode location, boolean isConstructorCall) { + + int id; + + if (isConstructorCall) { + //28 = No enclosing instance of type {0} is available due to some intermediate constructor invocation + id = IProblem.EnclosingInstanceInConstructorCall; + } else if ((location instanceof ExplicitConstructorCall) + && ((ExplicitConstructorCall) location).accessMode == ExplicitConstructorCall.ImplicitSuper) { + //20 = No enclosing instance of type {0} is accessible to invoke the super constructor. Must define a constructor and explicitly qualify its super constructor invocation with an instance of {0} (e.g. x.super() where x is an instance of {0}). + id = IProblem.MissingEnclosingInstanceForConstructorCall; + } else if (location instanceof AllocationExpression + && (((AllocationExpression) location).binding.declaringClass.isMemberType() + || (((AllocationExpression) location).binding.declaringClass.isAnonymousType() + && ((AllocationExpression) location).binding.declaringClass.superclass().isMemberType()))) { + //21 = No enclosing instance of type {0} is accessible. Must qualify the allocation with an enclosing instance of type {0} (e.g. x.new A() where x is an instance of {0}). + id = IProblem.MissingEnclosingInstance; + } else { // default + //22 = No enclosing instance of the type {0} is accessible in scope + id = IProblem.IncorrectEnclosingInstanceReference; + } + + this.handle( + id, + new String[] { new String(targetType.readableName())}, + new String[] { new String(targetType.shortReadableName())}, + location.sourceStart, + location.sourceEnd); +} +public void notCompatibleTypesError(EqualExpression expression, TypeBinding leftType, TypeBinding rightType) { + String leftName = new String(leftType.readableName()); + String rightName = new String(rightType.readableName()); + String leftShortName = new String(leftType.shortReadableName()); + String rightShortName = new String(rightType.shortReadableName()); + if (leftShortName.equals(rightShortName)){ + leftShortName = leftName; + rightShortName = rightName; + } + this.handle( + IProblem.IncompatibleTypesInEqualityOperator, + new String[] {leftName, rightName }, + new String[] {leftShortName, rightShortName }, + expression.sourceStart, + expression.sourceEnd); +} +public void notCompatibleTypesError(InstanceOfExpression expression, TypeBinding leftType, TypeBinding rightType) { + String leftName = new String(leftType.readableName()); + String rightName = new String(rightType.readableName()); + String leftShortName = new String(leftType.shortReadableName()); + String rightShortName = new String(rightType.shortReadableName()); + if (leftShortName.equals(rightShortName)){ + leftShortName = leftName; + rightShortName = rightName; + } + this.handle( + IProblem.IncompatibleTypesInConditionalOperator, + new String[] {leftName, rightName }, + new String[] {leftShortName, rightShortName }, + expression.sourceStart, + expression.sourceEnd); +} +public void objectCannotHaveSuperTypes(SourceTypeBinding type) { + this.handle( + IProblem.ObjectCannotHaveSuperTypes, + NoArgument, + NoArgument, + type.sourceStart(), + type.sourceEnd()); +} +public void operatorOnlyValidOnNumericType(CompoundAssignment assignment, TypeBinding leftType, TypeBinding rightType) { + String leftName = new String(leftType.readableName()); + String rightName = new String(rightType.readableName()); + String leftShortName = new String(leftType.shortReadableName()); + String rightShortName = new String(rightType.shortReadableName()); + if (leftShortName.equals(rightShortName)){ + leftShortName = leftName; + rightShortName = rightName; + } + this.handle( + IProblem.TypeMismatch, + new String[] {leftName, rightName }, + new String[] {leftShortName, rightShortName }, + assignment.sourceStart, + assignment.sourceEnd); +} +public void overridesDeprecatedMethod(MethodBinding localMethod, MethodBinding inheritedMethod) { + this.handle( + IProblem.OverridingDeprecatedMethod, + new String[] { + new String( + CharOperation.concat( + localMethod.declaringClass.readableName(), + localMethod.readableName(), + '.')), + new String(inheritedMethod.declaringClass.readableName())}, + new String[] { + new String( + CharOperation.concat( + localMethod.declaringClass.shortReadableName(), + localMethod.shortReadableName(), + '.')), + new String(inheritedMethod.declaringClass.shortReadableName())}, + localMethod.sourceStart(), + localMethod.sourceEnd()); +} +public void overridesPackageDefaultMethod(MethodBinding localMethod, MethodBinding inheritedMethod) { + this.handle( + IProblem.OverridingNonVisibleMethod, + new String[] { + new String( + CharOperation.concat( + localMethod.declaringClass.readableName(), + localMethod.readableName(), + '.')), + new String(inheritedMethod.declaringClass.readableName())}, + new String[] { + new String( + CharOperation.concat( + localMethod.declaringClass.shortReadableName(), + localMethod.shortReadableName(), + '.')), + new String(inheritedMethod.declaringClass.shortReadableName())}, + localMethod.sourceStart(), + localMethod.sourceEnd()); +} +public void packageCollidesWithType(CompilationUnitDeclaration compUnitDecl) { + String[] arguments = new String[] {CharOperation.toString(compUnitDecl.currentPackage.tokens)}; + this.handle( + IProblem.PackageCollidesWithType, + arguments, + arguments, + compUnitDecl.currentPackage.sourceStart, + compUnitDecl.currentPackage.sourceEnd); +} +public void packageIsNotExpectedPackage(CompilationUnitDeclaration compUnitDecl) { + String[] arguments = new String[] {CharOperation.toString(compUnitDecl.compilationResult.compilationUnit.getPackageName())}; + this.handle( + IProblem.PackageIsNotExpectedPackage, + arguments, + arguments, + compUnitDecl.currentPackage == null ? 0 : compUnitDecl.currentPackage.sourceStart, + compUnitDecl.currentPackage == null ? 0 : compUnitDecl.currentPackage.sourceEnd); +} +private String parametersAsString(MethodBinding method) { + TypeBinding[] params = method.parameters; + StringBuffer buffer = new StringBuffer(); + for (int i = 0, length = params.length; i < length; i++) { + if (i != 0) + buffer.append(", "); //$NON-NLS-1$ + buffer.append(new String(params[i].readableName())); + } + return buffer.toString(); +} +private String parametersAsShortString(MethodBinding method) { + TypeBinding[] params = method.parameters; + StringBuffer buffer = new StringBuffer(); + for (int i = 0, length = params.length; i < length; i++) { + if (i != 0) + buffer.append(", "); //$NON-NLS-1$ + buffer.append(new String(params[i].shortReadableName())); + } + return buffer.toString(); +} +public void parseError( + int startPosition, + int endPosition, + char[] currentTokenSource, + String errorTokenName, + String[] possibleTokens) { + + if (possibleTokens.length == 0) { //no suggestion available + if (isKeyword(currentTokenSource)) { + String[] arguments = new String[] {new String(currentTokenSource)}; + this.handle( + IProblem.ParsingErrorOnKeywordNoSuggestion, + arguments, + arguments, + // this is the current -invalid- token position + startPosition, + endPosition); + return; + } else { + String[] arguments = new String[] {errorTokenName}; + this.handle( + IProblem.ParsingErrorNoSuggestion, + arguments, + arguments, + // this is the current -invalid- token position + startPosition, + endPosition); + return; + } + } + + //build a list of probable right tokens + StringBuffer list = new StringBuffer(20); + for (int i = 0, max = possibleTokens.length; i < max; i++) { + if (i > 0) + list.append(", "); //$NON-NLS-1$ + list.append('"'); + list.append(possibleTokens[i]); + list.append('"'); + } + + if (isKeyword(currentTokenSource)) { + String[] arguments = new String[] {new String(currentTokenSource), list.toString()}; + this.handle( + IProblem.ParsingErrorOnKeyword, + arguments, + arguments, + // this is the current -invalid- token position + startPosition, + endPosition); + return; + } + //extract the literal when it's a literal + if ((errorTokenName.equals("IntegerLiteral")) || //$NON-NLS-1$ + (errorTokenName.equals("LongLiteral")) || //$NON-NLS-1$ + (errorTokenName.equals("FloatingPointLiteral")) || //$NON-NLS-1$ + (errorTokenName.equals("DoubleLiteral")) || //$NON-NLS-1$ + (errorTokenName.equals("StringLiteral")) || //$NON-NLS-1$ + (errorTokenName.equals("CharacterLiteral")) || //$NON-NLS-1$ + (errorTokenName.equals("Identifier"))) { //$NON-NLS-1$ + errorTokenName = new String(currentTokenSource); + } + + String[] arguments = new String[] {errorTokenName, list.toString()}; + this.handle( + IProblem.ParsingError, + arguments, + arguments, + // this is the current -invalid- token position + startPosition, + endPosition); +} +public void publicClassMustMatchFileName(CompilationUnitDeclaration compUnitDecl, TypeDeclaration typeDecl) { + this.referenceContext = typeDecl; // report the problem against the type not the entire compilation unit + String[] arguments = new String[] {new String(compUnitDecl.getFileName()), new String(typeDecl.name)}; + this.handle( + IProblem.PublicClassMustMatchFileName, + arguments, + arguments, + typeDecl.sourceStart, + typeDecl.sourceEnd, + compUnitDecl.compilationResult); +} +public void recursiveConstructorInvocation(ExplicitConstructorCall constructorCall) { + + this.handle( + IProblem.RecursiveConstructorInvocation, + new String[] { + new String(constructorCall.binding.declaringClass.readableName()), + parametersAsString(constructorCall.binding) + }, + new String[] { + new String(constructorCall.binding.declaringClass.shortReadableName()), + parametersAsShortString(constructorCall.binding) + }, + constructorCall.sourceStart, + constructorCall.sourceEnd); +} + +public void redefineArgument(Argument arg) { + String[] arguments = new String[] {new String(arg.name)}; + this.handle( + IProblem.RedefinedArgument, + arguments, + arguments, + arg.sourceStart, + arg.sourceEnd); +} +public void redefineLocal(LocalDeclaration localDecl) { + String[] arguments = new String[] {new String(localDecl.name)}; + this.handle( + IProblem.RedefinedLocal, + arguments, + arguments, + localDecl.sourceStart, + localDecl.sourceEnd); +} +public void referenceMustBeArrayTypeAt(TypeBinding arrayType, ArrayReference arrayRef) { + this.handle( + IProblem.ArrayReferenceRequired, + new String[] {new String(arrayType.readableName())}, + new String[] {new String(arrayType.shortReadableName())}, + arrayRef.sourceStart, + arrayRef.sourceEnd); +} +public void returnTypeCannotBeVoidArray(SourceTypeBinding type, MethodDeclaration methodDecl) { + String[] arguments = new String[] {new String(methodDecl.selector)}; + this.handle( + IProblem.ReturnTypeCannotBeVoidArray, + arguments, + arguments, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void returnTypeProblem(SourceTypeBinding type, MethodDeclaration methodDecl, TypeBinding expectedType) { + int problemId = expectedType.problemId(); + int id; + switch (problemId) { + case NotFound : // 1 + id = IProblem.ReturnTypeNotFound; + break; + case NotVisible : // 2 + id = IProblem.ReturnTypeNotVisible; + break; + case Ambiguous : // 3 + id = IProblem.ReturnTypeAmbiguous; + break; + case InternalNameProvided : // 4 + id = IProblem.ReturnTypeInternalNameProvided; + break; + case InheritedNameHidesEnclosingName : // 5 + id = IProblem.ReturnTypeInheritedNameHidesEnclosingName; + break; + case NoError : // 0 + default : + needImplementation(); // want to fail to see why we were here... + return; + } + this.handle( + id, + new String[] {new String(methodDecl.selector), new String(expectedType.readableName())}, + new String[] {new String(methodDecl.selector), new String(expectedType.shortReadableName())}, + methodDecl.returnType.sourceStart, + methodDecl.returnType.sourceEnd); +} +public void scannerError(Parser parser, String errorTokenName) { + Scanner scanner = parser.scanner; + + int flag = IProblem.ParsingErrorNoSuggestion; + int startPos = scanner.startPosition; + + //special treatment for recognized errors.... + if (errorTokenName.equals(Scanner.END_OF_SOURCE)) + flag = IProblem.EndOfSource; + else + if (errorTokenName.equals(Scanner.INVALID_HEXA)) + flag = IProblem.InvalidHexa; + else + if (errorTokenName.equals(Scanner.INVALID_OCTAL)) + flag = IProblem.InvalidOctal; + else + if (errorTokenName.equals(Scanner.INVALID_CHARACTER_CONSTANT)) + flag = IProblem.InvalidCharacterConstant; + else + if (errorTokenName.equals(Scanner.INVALID_ESCAPE)) + flag = IProblem.InvalidEscape; + else + if (errorTokenName.equals(Scanner.INVALID_UNICODE_ESCAPE)){ + flag = IProblem.InvalidUnicodeEscape; + // better locate the error message + char[] source = scanner.source; + int checkPos = scanner.currentPosition - 1; + if (checkPos >= source.length) checkPos = source.length - 1; + while (checkPos >= startPos){ + if (source[checkPos] == '\\') break; + checkPos --; + } + startPos = checkPos; + } else + if (errorTokenName.equals(Scanner.INVALID_FLOAT)) + flag = IProblem.InvalidFloat; + else + if (errorTokenName.equals(Scanner.UNTERMINATED_STRING)) + flag = IProblem.UnterminatedString; + else + if (errorTokenName.equals(Scanner.UNTERMINATED_COMMENT)) + flag = IProblem.UnterminatedComment; + else + if (errorTokenName.equals(Scanner.INVALID_CHAR_IN_STRING)) + flag = IProblem.UnterminatedString; + + String[] arguments = flag == IProblem.ParsingErrorNoSuggestion + ? new String[] {errorTokenName} + : NoArgument; + this.handle( + flag, + arguments, + arguments, + // this is the current -invalid- token position + startPos, + scanner.currentPosition - 1, + parser.compilationUnit.compilationResult); +} +public void shouldReturn(TypeBinding returnType, AstNode location) { + this.handle( + IProblem.ShouldReturnValue, + new String[] { new String (returnType.readableName())}, + new String[] { new String (returnType.shortReadableName())}, + location.sourceStart, + location.sourceEnd); +} +public void signalNoImplicitStringConversionForCharArrayExpression(Expression expression) { + this.handle( + IProblem.NoImplicitStringConversionForCharArrayExpression, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void staticAndInstanceConflict(MethodBinding currentMethod, MethodBinding inheritedMethod) { + if (currentMethod.isStatic()) + this.handle( + // This static method cannot hide the instance method from %1 + // 8.4.6.4 - If a class inherits more than one method with the same signature a static (non-abstract) method cannot hide an instance method. + IProblem.CannotHideAnInstanceMethodWithAStaticMethod, + new String[] {new String(inheritedMethod.declaringClass.readableName())}, + new String[] {new String(inheritedMethod.declaringClass.shortReadableName())}, + currentMethod.sourceStart(), + currentMethod.sourceEnd()); + else + this.handle( + // This instance method cannot override the static method from %1 + // 8.4.6.4 - If a class inherits more than one method with the same signature an instance (non-abstract) method cannot override a static method. + IProblem.CannotOverrideAStaticMethodWithAnInstanceMethod, + new String[] {new String(inheritedMethod.declaringClass.readableName())}, + new String[] {new String(inheritedMethod.declaringClass.shortReadableName())}, + currentMethod.sourceStart(), + currentMethod.sourceEnd()); +} +public void staticFieldAccessToNonStaticVariable(FieldReference fieldRef, FieldBinding field) { + String[] arguments = new String[] {new String(field.readableName())}; + this.handle( + IProblem.NonStaticFieldFromStaticInvocation, + arguments, + arguments, + fieldRef.sourceStart, + fieldRef.sourceEnd); +} +public void staticFieldAccessToNonStaticVariable(QualifiedNameReference nameRef, FieldBinding field){ + String[] arguments = new String[] {new String(field.readableName())}; + this.handle( + IProblem.NonStaticFieldFromStaticInvocation, + arguments, + arguments, + nameRef.sourceStart, + nameRef.sourceEnd); +} +public void staticFieldAccessToNonStaticVariable(SingleNameReference nameRef, FieldBinding field) { + String[] arguments = new String[] {new String(field.readableName())}; + this.handle( + IProblem.NonStaticFieldFromStaticInvocation, + arguments, + arguments, + nameRef.sourceStart, + nameRef.sourceEnd); +} +public void staticInheritedMethodConflicts(SourceTypeBinding type, MethodBinding concreteMethod, MethodBinding[] abstractMethods) { + this.handle( + // The static method %1 conflicts with the abstract method in %2 + // 8.4.6.4 - If a class inherits more than one method with the same signature it is an error for one to be static (non-abstract) and the other abstract. + IProblem.StaticInheritedMethodConflicts, + new String[] { + new String(concreteMethod.readableName()), + new String(abstractMethods[0].declaringClass.readableName())}, + new String[] { + new String(concreteMethod.readableName()), + new String(abstractMethods[0].declaringClass.shortReadableName())}, + type.sourceStart(), + type.sourceEnd()); +} +public void stringConstantIsExceedingUtf8Limit(AstNode location) { + this.handle( + IProblem.StringConstantIsExceedingUtf8Limit, + NoArgument, + NoArgument, + location.sourceStart, + location.sourceEnd); +} +public void superclassMustBeAClass(SourceTypeBinding type, TypeReference superclassRef, ReferenceBinding superType) { + this.handle( + IProblem.SuperclassMustBeAClass, + new String[] {new String(superType.readableName()), new String(type.sourceName())}, + new String[] {new String(superType.shortReadableName()), new String(type.sourceName())}, + superclassRef.sourceStart, + superclassRef.sourceEnd); +} +public void superinterfaceMustBeAnInterface(SourceTypeBinding type, TypeDeclaration typeDecl, ReferenceBinding superType) { + this.handle( + IProblem.SuperInterfaceMustBeAnInterface, + new String[] {new String(superType.readableName()), new String(type.sourceName())}, + new String[] {new String(superType.shortReadableName()), new String(type.sourceName())}, + typeDecl.sourceStart, + typeDecl.sourceEnd); +} +public void task(String tag, String message, String priority, int start, int end){ + this.handle( + IProblem.Task, + new String[] { tag, message, priority/*secret argument that is not surfaced in getMessage()*/}, + new String[] { tag, message, priority/*secret argument that is not surfaced in getMessage()*/}, + start, + end); +} +public void tooManyDimensions(AstNode expression) { + this.handle( + IProblem.TooManyArrayDimensions, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void tooManyFields(TypeDeclaration typeDeclaration) { + this.handle( + IProblem.TooManyFields, + new String[]{ new String(typeDeclaration.binding.readableName())}, + new String[]{ new String(typeDeclaration.binding.shortReadableName())}, + Abort | Error, + typeDeclaration.sourceStart, + typeDeclaration.sourceEnd); +} +public void tooManyMethods(TypeDeclaration typeDeclaration) { + this.handle( + IProblem.TooManyMethods, + new String[]{ new String(typeDeclaration.binding.readableName())}, + new String[]{ new String(typeDeclaration.binding.shortReadableName())}, + Abort | Error, + typeDeclaration.sourceStart, + typeDeclaration.sourceEnd); +} +public void typeCastError(CastExpression expression, TypeBinding leftType, TypeBinding rightType) { + String leftName = new String(leftType.readableName()); + String rightName = new String(rightType.readableName()); + String leftShortName = new String(leftType.shortReadableName()); + String rightShortName = new String(rightType.shortReadableName()); + if (leftShortName.equals(rightShortName)){ + leftShortName = leftName; + rightShortName = rightName; + } + this.handle( + IProblem.IllegalCast, + new String[] { rightName, leftName }, + new String[] { rightShortName, leftShortName }, + expression.sourceStart, + expression.sourceEnd); +} +public void typeCollidesWithPackage(CompilationUnitDeclaration compUnitDecl, TypeDeclaration typeDecl) { + this.referenceContext = typeDecl; // report the problem against the type not the entire compilation unit + String[] arguments = new String[] {new String(compUnitDecl.getFileName()), new String(typeDecl.name)}; + this.handle( + IProblem.TypeCollidesWithPackage, + arguments, + arguments, + typeDecl.sourceStart, + typeDecl.sourceEnd, + compUnitDecl.compilationResult); +} +public void typeMismatchError(TypeBinding resultType, TypeBinding expectedType, AstNode location) { + String resultTypeName = new String(resultType.readableName()); + String expectedTypeName = new String(expectedType.readableName()); + String resultTypeShortName = new String(resultType.shortReadableName()); + String expectedTypeShortName = new String(expectedType.shortReadableName()); + if (resultTypeShortName.equals(expectedTypeShortName)){ + resultTypeShortName = resultTypeName; + expectedTypeShortName = expectedTypeName; + } + this.handle( + IProblem.TypeMismatch, + new String[] {resultTypeName, expectedTypeName}, + new String[] {resultTypeShortName, expectedTypeShortName}, + location.sourceStart, + location.sourceEnd); +} +public void typeMismatchErrorActualTypeExpectedType(Expression expression, TypeBinding constantType, TypeBinding expectedType) { + String constantTypeName = new String(constantType.readableName()); + String expectedTypeName = new String(expectedType.readableName()); + String constantTypeShortName = new String(constantType.shortReadableName()); + String expectedTypeShortName = new String(expectedType.shortReadableName()); + if (constantTypeShortName.equals(expectedTypeShortName)){ + constantTypeShortName = constantTypeName; + expectedTypeShortName = expectedTypeName; + } + this.handle( + IProblem.TypeMismatch, + new String[] {constantTypeName, expectedTypeName}, + new String[] {constantTypeShortName, expectedTypeShortName}, + expression.sourceStart, + expression.sourceEnd); +} +public void undefinedLabel(BranchStatement statement) { + String[] arguments = new String[] {new String(statement.label)}; + this.handle( + IProblem.UndefinedLabel, + arguments, + arguments, + statement.sourceStart, + statement.sourceEnd); +} +public void unexpectedStaticModifierForField(SourceTypeBinding type, FieldDeclaration fieldDecl) { + String[] arguments = new String[] {fieldDecl.name()}; + this.handle( + IProblem.UnexpectedStaticModifierForField, + arguments, + arguments, + fieldDecl.sourceStart, + fieldDecl.sourceEnd); +} +public void unexpectedStaticModifierForMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) { + String[] arguments = new String[] {new String(type.sourceName()), new String(methodDecl.selector)}; + this.handle( + IProblem.UnexpectedStaticModifierForMethod, + arguments, + arguments, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void unhandledException(TypeBinding exceptionType, AstNode location) { + + boolean insideDefaultConstructor = + (referenceContext instanceof ConstructorDeclaration) + && ((ConstructorDeclaration)referenceContext).isDefaultConstructor(); + boolean insideImplicitConstructorCall = + (location instanceof ExplicitConstructorCall) + && (((ExplicitConstructorCall) location).accessMode == ExplicitConstructorCall.ImplicitSuper); + + this.handle( + insideDefaultConstructor + ? IProblem.UnhandledExceptionInDefaultConstructor + : (insideImplicitConstructorCall + ? IProblem.UndefinedConstructorInImplicitConstructorCall + : IProblem.UnhandledException), + new String[] {new String(exceptionType.readableName())}, + new String[] {new String(exceptionType.shortReadableName())}, + location.sourceStart, + location.sourceEnd); +} +public void uninitializedBlankFinalField(FieldBinding binding, AstNode location) { + String[] arguments = new String[] {new String(binding.readableName())}; + this.handle( + IProblem.UninitializedBlankFinalField, + arguments, + arguments, + location.sourceStart, + location.sourceEnd); +} +public void uninitializedLocalVariable(LocalVariableBinding binding, AstNode location) { + String[] arguments = new String[] {new String(binding.readableName())}; + this.handle( + IProblem.UninitializedLocalVariable, + arguments, + arguments, + location.sourceStart, + location.sourceEnd); +} +public void unmatchedBracket(int position, ReferenceContext context, CompilationResult compilationResult) { + + this.handle( + IProblem.UnmatchedBracket, + NoArgument, + NoArgument, + position, + position, + context, + compilationResult); +} +public void unnecessaryEnclosingInstanceSpecification(Expression expression, ReferenceBinding targetType) { + this.handle( + IProblem.IllegalEnclosingInstanceSpecification, + new String[]{ new String(targetType.readableName())}, + new String[]{ new String(targetType.shortReadableName())}, + expression.sourceStart, + expression.sourceEnd); +} +public void unnecessaryReceiverForStaticMethod(AstNode location, MethodBinding method) { + this.handle( + IProblem.NonStaticAccessToStaticMethod, + new String[] {new String(method.declaringClass.readableName()), new String(method.selector), parametersAsString(method)}, + new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), parametersAsShortString(method)}, + location.sourceStart, + location.sourceEnd); +} +public void unnecessaryReceiverForStaticField(AstNode location, FieldBinding field) { + this.handle( + IProblem.NonStaticAccessToStaticField, + new String[] {new String(field.declaringClass.readableName()), new String(field.name)}, + new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)}, + location.sourceStart, + location.sourceEnd); +} +public void unreachableCode(Statement statement) { + this.handle( + IProblem.CodeCannotBeReached, + NoArgument, + NoArgument, + statement.sourceStart, + statement.sourceEnd); +} +public void unreachableExceptionHandler(ReferenceBinding exceptionType, AstNode location) { + this.handle( + IProblem.UnreachableCatch, + NoArgument, + NoArgument, + location.sourceStart, + location.sourceEnd); +} +public void unresolvableReference(NameReference nameRef, Binding binding) { + int severity = Error; +/* also need to check that the searchedType is the receiver type + if (binding instanceof ProblemBinding) { + ProblemBinding problem = (ProblemBinding) binding; + if (problem.searchType != null && problem.searchType.isHierarchyInconsistent()) + severity = SecondaryError; + } +*/ + String[] arguments = new String[] {new String(binding.readableName())}; + this.handle( + IProblem.UndefinedName, + arguments, + arguments, + severity, + nameRef.sourceStart, + nameRef.sourceEnd); +} +public void unusedArgument(LocalDeclaration localDecl) { + + String[] arguments = new String[] {localDecl.name()}; + this.handle( + IProblem.ArgumentIsNeverUsed, + arguments, + arguments, + localDecl.sourceStart, + localDecl.sourceEnd); +} +public void unusedImport(ImportReference importRef) { + String[] arguments = new String[] { CharOperation.toString(importRef.tokens) }; + this.handle( + IProblem.UnusedImport, + arguments, + arguments, + importRef.sourceStart, + importRef.sourceEnd); +} +public void unusedLocalVariable(LocalDeclaration localDecl) { + String[] arguments = new String[] {localDecl.name()}; + this.handle( + IProblem.LocalVariableIsNeverUsed, + arguments, + arguments, + localDecl.sourceStart, + localDecl.sourceEnd); +} +public void unusedPrivateConstructor(ConstructorDeclaration constructorDecl) { + + if (computeSeverity(IProblem.UnusedPrivateConstructor) == Ignore) return; + + // no complaint for no-arg constructors (or default ones) - known pattern to block instantiation + if (constructorDecl.arguments == null || constructorDecl.arguments.length == 0) return; + + MethodBinding constructor = constructorDecl.binding; + this.handle( + IProblem.UnusedPrivateConstructor, + new String[] { + new String(constructor.declaringClass.readableName()), + parametersAsString(constructor) + }, + new String[] { + new String(constructor.declaringClass.shortReadableName()), + parametersAsShortString(constructor) + }, + constructorDecl.sourceStart, + constructorDecl.sourceEnd); +} +public void unusedPrivateField(FieldDeclaration fieldDecl) { + + if (computeSeverity(IProblem.UnusedPrivateField) == Ignore) return; + + FieldBinding field = fieldDecl.binding; + + if (CharOperation.equals(TypeConstants.SERIALVERSIONUID, field.name) + && field.isStatic() + && field.isFinal() + && TypeBinding.LongBinding == field.type) { + return; // do not report unused serialVersionUID field + } + this.handle( + IProblem.UnusedPrivateField, + new String[] { + new String(field.declaringClass.readableName()), + new String(field.name), + }, + new String[] { + new String(field.declaringClass.shortReadableName()), + new String(field.name), + }, + fieldDecl.sourceStart, + fieldDecl.sourceEnd); +} +public void unusedPrivateMethod(AbstractMethodDeclaration methodDecl) { + + if (computeSeverity(IProblem.UnusedPrivateMethod) == Ignore) return; + + MethodBinding method = methodDecl.binding; + + // no report for serialization support 'void readObject(ObjectInputStream)' + if (!method.isStatic() + && TypeBinding.VoidBinding == method.returnType + && method.parameters.length == 1 + && method.parameters[0].dimensions() == 0 + && CharOperation.equals(method.selector, TypeConstants.READOBJECT) + && CharOperation.equals(TypeConstants.CharArray_JAVA_IO_OBJECTINPUTSTREAM, method.parameters[0].readableName())) { + return; + } + // no report for serialization support 'void writeObject(ObjectOutputStream)' + if (!method.isStatic() + && TypeBinding.VoidBinding == method.returnType + && method.parameters.length == 1 + && method.parameters[0].dimensions() == 0 + && CharOperation.equals(method.selector, TypeConstants.WRITEOBJECT) + && CharOperation.equals(TypeConstants.CharArray_JAVA_IO_OBJECTOUTPUTSTREAM, method.parameters[0].readableName())) { + return; + } + // no report for serialization support 'Object readResolve()' + if (!method.isStatic() + && TypeBinding.T_Object == method.returnType.id + && method.parameters.length == 0 + && CharOperation.equals(method.selector, TypeConstants.READRESOLVE)) { + return; + } + // no report for serialization support 'Object writeReplace()' + if (!method.isStatic() + && TypeBinding.T_Object == method.returnType.id + && method.parameters.length == 0 + && CharOperation.equals(method.selector, TypeConstants.WRITEREPLACE)) { + return; + } + this.handle( + IProblem.UnusedPrivateMethod, + new String[] { + new String(method.declaringClass.readableName()), + new String(method.selector), + parametersAsString(method) + }, + new String[] { + new String(method.declaringClass.shortReadableName()), + new String(method.selector), + parametersAsShortString(method) + }, + methodDecl.sourceStart, + methodDecl.sourceEnd); +} +public void unusedPrivateType(TypeDeclaration typeDecl) { + + if (computeSeverity(IProblem.UnusedPrivateType) == Ignore) return; + + ReferenceBinding type = typeDecl.binding; + this.handle( + IProblem.UnusedPrivateType, + new String[] { + new String(type.readableName()), + }, + new String[] { + new String(type.shortReadableName()), + }, + typeDecl.sourceStart, + typeDecl.sourceEnd); +} +public void useAssertAsAnIdentifier(int sourceStart, int sourceEnd) { + this.handle( + IProblem.UseAssertAsAnIdentifier, + NoArgument, + NoArgument, + sourceStart, + sourceEnd); +} + +public void variableTypeCannotBeVoid(AbstractVariableDeclaration varDecl) { + String[] arguments = new String[] {new String(varDecl.name)}; + this.handle( + IProblem.VariableTypeCannotBeVoid, + arguments, + arguments, + varDecl.sourceStart, + varDecl.sourceEnd); +} +public void variableTypeCannotBeVoidArray(AbstractVariableDeclaration varDecl) { + String[] arguments = new String[] {new String(varDecl.name)}; + this.handle( + IProblem.VariableTypeCannotBeVoidArray, + arguments, + arguments, + varDecl.sourceStart, + varDecl.sourceEnd); +} +public void visibilityConflict(MethodBinding currentMethod, MethodBinding inheritedMethod) { + this.handle( + // Cannot reduce the visibility of the inherited method from %1 + // 8.4.6.3 - The access modifier of an hiding method must provide at least as much access as the hidden method. + // 8.4.6.3 - The access modifier of an overiding method must provide at least as much access as the overriden method. + IProblem.MethodReducesVisibility, + new String[] {new String(inheritedMethod.declaringClass.readableName())}, + new String[] {new String(inheritedMethod.declaringClass.shortReadableName())}, + currentMethod.sourceStart(), + currentMethod.sourceEnd()); +} +public void wrongSequenceOfExceptionTypesError(TryStatement statement, int under, int upper) { + //the two catch block under and upper are in an incorrect order. + //under should be define BEFORE upper in the source + + TypeReference typeRef = statement.catchArguments[under].type; + this.handle( + IProblem.UnreachableCatch, + NoArgument, + NoArgument, + typeRef.sourceStart, + typeRef.sourceEnd); +} + +public void nonExternalizedStringLiteral(AstNode location) { + this.handle( + IProblem.NonExternalizedStringLiteral, + NoArgument, + NoArgument, + location.sourceStart, + location.sourceEnd); +} + +public void noMoreAvailableSpaceForConstant(TypeDeclaration typeDeclaration) { + this.handle( + IProblem.TooManyBytesForStringConstant, + new String[]{ new String(typeDeclaration.binding.readableName())}, + new String[]{ new String(typeDeclaration.binding.shortReadableName())}, + Abort | Error, + typeDeclaration.sourceStart, + typeDeclaration.sourceEnd); +} + +public void noMoreAvailableSpaceInConstantPool(TypeDeclaration typeDeclaration) { + this.handle( + IProblem.TooManyConstantsInConstantPool, + new String[]{ new String(typeDeclaration.binding.readableName())}, + new String[]{ new String(typeDeclaration.binding.shortReadableName())}, + Abort | Error, + typeDeclaration.sourceStart, + typeDeclaration.sourceEnd); +} + +private boolean isKeyword(char[] tokenSource) { + /* + * This code is heavily grammar dependant + */ + + if (tokenSource == null) { + return false; + } + try { + Scanner scanner = new Scanner(); + scanner.setSource(tokenSource); + int token = scanner.getNextToken(); + char[] currentKeyword; + try { + currentKeyword = scanner.getCurrentIdentifierSource(); + } catch (ArrayIndexOutOfBoundsException e) { + return false; + } + int nextToken= scanner.getNextToken(); + if (nextToken == Scanner.TokenNameEOF + && scanner.startPosition == scanner.source.length) { // to handle case where we had an ArrayIndexOutOfBoundsException + // while reading the last token + switch(token) { + case Scanner.TokenNameERROR: + if (CharOperation.equals("goto".toCharArray(), currentKeyword) ||CharOperation.equals("const".toCharArray(), currentKeyword)) { //$NON-NLS-1$ //$NON-NLS-2$ + return true; + } else { + return false; + } + case Scanner.TokenNameabstract: +// case Scanner.TokenNameassert: +// case Scanner.TokenNamebyte: + case Scanner.TokenNamebreak: +// case Scanner.TokenNameboolean: + case Scanner.TokenNamecase: +// case Scanner.TokenNamechar: + case Scanner.TokenNamecatch: + case Scanner.TokenNameclass: + case Scanner.TokenNamecontinue: + case Scanner.TokenNamedo: +// case Scanner.TokenNamedouble: + case Scanner.TokenNamedefault: + case Scanner.TokenNameelse: + case Scanner.TokenNameextends: + case Scanner.TokenNamefor: +// case Scanner.TokenNamefinal: +// case Scanner.TokenNamefloat: + case Scanner.TokenNamefalse: + case Scanner.TokenNamefinally: + case Scanner.TokenNameif: +// case Scanner.TokenNameint: +// case Scanner.TokenNameimport: + case Scanner.TokenNameinterface: + case Scanner.TokenNameimplements: + case Scanner.TokenNameinstanceof: +// case Scanner.TokenNamelong: + case Scanner.TokenNamenew: + case Scanner.TokenNamenull: +// case Scanner.TokenNamenative: + case Scanner.TokenNamepublic: +// case Scanner.TokenNamepackage: + case Scanner.TokenNameprivate: + case Scanner.TokenNameprotected: + case Scanner.TokenNamereturn: +// case Scanner.TokenNameshort: + case Scanner.TokenNamesuper: + case Scanner.TokenNamestatic: + case Scanner.TokenNameswitch: +// case Scanner.TokenNamestrictfp: +// case Scanner.TokenNamesynchronized: + case Scanner.TokenNametry: + case Scanner.TokenNamethis: + case Scanner.TokenNametrue: + case Scanner.TokenNamethrow: +// case Scanner.TokenNamethrows: +// case Scanner.TokenNametransient: +// case Scanner.TokenNamevoid: +// case Scanner.TokenNamevolatile: + case Scanner.TokenNamewhile: + return true; + default: + return false; + } + } else { + return false; + } + } + catch (InvalidInputException e) { + return false; + } + +} +// jsurfer start +public void phpParsingError(String[] messageArguments, int problemStartPosition, int problemEndPosition, ReferenceContext context, CompilationResult compilationResult) { + + this.handle( + IProblem.PHPParsingError, + NoArgument, + messageArguments, + problemStartPosition, + problemEndPosition, + context, + compilationResult); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/ProblemSeverities.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/ProblemSeverities.java new file mode 100644 index 0000000..f6f20de --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/ProblemSeverities.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.problem; + +public interface ProblemSeverities { + + final int Ignore = -1; // during handling only + final int Warning = 0; // during handling only + + final int Error = 1; // when bit is set: problem is error, if not it is a warning + final int AbortCompilation = 2; + final int AbortCompilationUnit = 4; + final int AbortType = 8; + final int AbortMethod = 16; + final int Abort = 30; // 2r11110 + final int SecondaryError = 64; +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/ShouldNotImplement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/ShouldNotImplement.java new file mode 100644 index 0000000..2df4b5a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/ShouldNotImplement.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.problem; + +/* + * Special unchecked exception type used + * to denote implementation that should never be reached. + * + * (internal only) + */ +public class ShouldNotImplement extends RuntimeException { +public ShouldNotImplement(){ +} +public ShouldNotImplement(String message){ + super(message); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/messages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/messages.properties new file mode 100644 index 0000000..b4ea5fa --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/problem/messages.properties @@ -0,0 +1,300 @@ +############################################################################### +# Copyright (c) 2000, 2003 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Common Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/cpl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### +0 = {0} +1 = super cannot be used in java.lang.Object +2 = {0} cannot be resolved or is not a type +3 = The type {0} is not visible +4 = The type {0} is ambiguous +5 = The type {0} is deprecated +6 = The type {0} is an incorrectly specified nested type; replace the ''$'' with ''.'' +7 = The private type {0} is never used locally + +15 = Incompatible operand types {0} and {1} +16 = Incompatible conditional operand types {0} and {1} +17 = Type mismatch: cannot convert from {0} to {1} + +20 = No enclosing instance of type {0} is accessible to invoke the super constructor. Must define a constructor and explicitly qualify its super constructor invocation with an instance of {0} (e.g. x.super() where x is an instance of {0}). +21 = No enclosing instance of type {0} is accessible. Must qualify the allocation with an enclosing instance of type {0} (e.g. x.new A() where x is an instance of {0}). +22 = No enclosing instance of the type {0} is accessible in scope +23 = Illegal enclosing instance specification for type {0} +24 = Cannot define static initializer in inner type {0} +25 = Cannot refer to a non-final variable {0} inside an inner class defined in a different method +26 = The member interface {0} can only be defined inside a top-level class or interface +27 = Cannot use an expression of the type {0} as a valid enclosing instance +28 = No enclosing instance of type {0} is available due to some intermediate constructor invocation +29 = An anonymous class cannot subclass the final class {0} + +50 = {0} cannot be resolved +51 = The local variable {0} may not have been initialized +52 = void is an invalid type for the variable {0} +53 = An array of void is an invalid type for the variable {0} +54 = An array of void is an invalid type +55 = Duplicate local variable {0} +56 = Duplicate argument {0} +57 = The final local variable {0} may already have been assigned +58 = The final local variable {0} cannot be assigned. It must be blank and not using a compound assignment + +60 = The final local variable {0} cannot be assigned, since it is defined in an enclosing type +61 = The local variable {0} is never read +62 = The argument {0} is never read +63 = The code of method {0}({1}) is exceeding the 65535 bytes limit +64 = The code for the static initializer is exceeding the 65535 bytes limit +65 = Too many arguments, parameter {0} is exceeding the limit of 255 words eligible for method arguments +66 = Too many local variables, local variable {0} is exceeding the limit of 65535 words eligible for method local variables +67 = Too many synthetic arguments, emulated parameter {0} is exceeding the limit of 255 words eligible for method arguments +68 = Too many array dimensions. Maximum is 255 +69 = The code of constructor {0}({1}) is exceeding the 65535 bytes limit +70 = {0} cannot be resolved or is not a field +71 = The field {0} is not visible +72 = The field {0} is ambiguous +73 = The field {0}.{1} is deprecated +74 = Cannot make a static reference to the non-static field {0} +75 = Cannot reference a field before it is defined +76 = The static field {0}.{1} should be accessed in a static way +77 = The private field {0}.{1} is never used locally + +80 = The final field {0}.{1} cannot be assigned. It must be blank in this context, not qualified and not in compound assignment +81 = The blank final field {0} may not have been initialized +82 = The final field {0} may already have been assigned + +100 = The method {1}({2}) is undefined for the type {0} +101 = The method {1}({2}) from the type {0} is not visible +102 = The method {1}({2}) is ambiguous for the type {0} +103 = The method {1}({2}) from the type {0} is deprecated +104 = Cannot directly invoke the abstract method {1}({2}) for the type {0} +105 = Void methods cannot return a value +106 = Cannot return a void result +107 = This method requires a body instead of a semicolon +108 = This method must return a result of type {0} + +110 = This method has a constructor name +111 = Return type for the method is missing +112 = Native methods do not specify a body +113 = Abstract methods do not specify a body +114 = Cannot invoke {1}({2}) on the primitive type {0} +115 = The method {1}({2}) in the type {0} is not applicable for the arguments ({3}) +116 = Cannot invoke {1}({2}) on the array type {0} +117 = The static method {1}({2}) from the type {0} should be accessed in a static way +118 = The private method {1}({2}) from the type {0} is never used locally + +130 = The constructor {0}({1}) is undefined +131 = The constructor {0}({1}) is not visible +132 = The constructor {0}({1}) is ambiguous +133 = The constructor {0}({1}) is deprecated +134 = The private constructor {0}({1}) is never used locally +135 = Cannot refer to an instance field {0} while explicitly invoking a constructor +136 = Cannot refer to an instance method while explicitly invoking a constructor +137 = Recursive constructor invocation {0}({1}) +138 = Cannot refer to ''this'' nor ''super'' while explicitly invoking a constructor + +140 = Implicit super constructor {0}({1}) is undefined for default constructor. Must define an explicit constructor +141 = Implicit super constructor {0}({1}) is not visible for default constructor. Must define an explicit constructor +142 = Implicit super constructor {0}({1}) is ambiguous for default constructor. Must define an explicit constructor +143 = Implicit super constructor {0}({1}) is undefined. Must explicitly invoke another constructor +144 = Implicit super constructor {0}({1}) is not visible. Must explicitly invoke another constructor +145 = Implicit super constructor {0}({1}) is ambiguous. Must explicitly invoke another constructor +146 = Default constructor cannot handle exception type {0} thrown by implicit super constructor. Must define an explicit constructor +147 = Unhandled exception type {0} thrown by implicit super constructor + +150 = The type of the expression must be an array type but it resolved to {0} +151 = Must explicitly convert the char[] to a String +152 = String constant is exceeding the limit of 65535 bytes of UTF8 encoding +153 = case expressions must be constant expressions +154 = {0} is out of range +156 = Cannot cast from {0} to {1} +157 = The type {0} cannot be instantiated +158 = Cannot define dimension expressions when an array initializer is provided +159 = Variable must provide either dimension expressions or an array initializer +160 = The operator {0} is undefined for the argument type(s) {1} +161 = Unreachable code +162 = Cannot return from within an initializer +163 = Initializer does not complete normally +164 = Expression must return a value +165 = Catch block is hidden by another one in the same try statement +166 = The default case is already defined +167 = Unreachable catch block +168 = Unhandled exception type {0} +169 = case constant must be a char, byte, short, or int instead of {0} +170 = Duplicate case {0} +171 = Duplicate label {0} +172 = break cannot be used outside of a loop or a switch +173 = continue cannot be used outside of a loop +174 = The label {0} is missing +175 = {0} is not a valid type''s argument for the synchronized statement +176 = null is not a valid argument for the synchronized statement +177 = Cannot throw null +178 = The assignment to variable {0} has no effect + +190 = Read access to enclosing field {0}.{1} is emulated by a synthetic accessor method. Increasing its visibility will improve your performance +191 = Write access to enclosing field {0}.{1} is emulated by a synthetic accessor method. Increasing its visibility will improve your performance +192 = Access to enclosing method {1}({2}) from the type {0} is emulated by a synthetic accessor method. Increasing its visibility will improve your performance +193 = Access to enclosing constructor {0}({1}) is emulated by a synthetic accessor method. Increasing its visibility will improve your performance +195 = The method {1} is defined in an inherited type and an enclosing scope +196 = The field {0} is defined in an inherited type and an enclosing scope +197 = The type {0} is defined in an inherited type and an enclosing scope + +200 = Cannot use {0} in a static context +201 = The method {1}({2}) from the type {0} is not static +202 = Cannot specify an array dimension after an empty dimension +203 = Invalid cast type expression +204 = Syntax error on token "{0}", {1} expected +205 = Syntax error on token "{0}", no accurate correction available +206 = Invalid argument to operation ++/-- +207 = Interfaces cannot have constructors +208 = Array constants can only be used in initializers +209 = Syntax error on keyword "{0}"; {1} expected +210 = Syntax error on keyword "{0}", no accurate correction available +211 = Parse error "{0}" + +220 = Unmatched bracket +221 = The primitive type {0} of {1} does not have a field {2} +222 = Invalid expression as statement +223 = The left-hand side of an assignment must be a variable +224 = Missing semicolon +225 = Invalid parenthesized expression + +250 = Unexpected end of file +251 = Invalid hex literal number +252 = Invalid octal literal number +253 = Invalid character constant +254 = Invalid escape sequence (valid ones are \\b \\t \\n \\f \\r \\" \\'' \\\\ ) +255 = Invalid input +256 = Invalid unicode +257 = Invalid float literal number +258 = Null source string +259 = String literal is not properly closed by a double-quote +260 = Unexpected end of comment +261 = Non-externalized string literal; it should be followed by //$NON-NLS-$ + +300 = The interface {0} cannot define an initializer +301 = Duplicate modifier for the type {0} +302 = Illegal modifier for the class {0}; only public, abstract & final are permitted +303 = Illegal modifier for the interface {0}; only public & abstract are permitted +304 = Illegal modifier for the member class {0}; only public, protected, private, static, abstract & final are permitted +305 = Illegal modifier for the member interface {0}; only public, protected, private, static & abstract are permitted +306 = Illegal modifier for the local class {0}; only one of abstract or final is permitted +308 = The class {0} can be either abstract or final, not both +309 = The interface member type {0} can only be public +310 = The member type {0} can only set one of public / protected / private +311 = The member type {0} cannot be declared static; static types can only be declared in static or top level types +312 = The interface {0} cannot be the superclass of {1}; a superclass must be a class +313 = The type {1} cannot subclass the final class {0} +314 = Duplicate interface {0} for the type {1} +315 = The class {0} cannot be a superinterface of {1}; a superinterface must be an interface +316 = {1} causes a cycle - the type {0} cannot extend/implement itself or one of its own member types +317 = A cycle exists in the type hierarchy between {0} and {1} +318 = Nested type {0} hides an enclosing type +319 = Duplicate nested type {0} +320 = Cannot throw the type {0} +321 = The package {0} collides with a type +322 = The type {1} collides with a package +323 = The type {1} is already defined +324 = This compilation unit indirectly references the missing type {0} (typically some required class file is referencing a type outside the classpath) +325 = The public type {1} must be defined in its own file +326 = A package must be specified in {0} or a default package created +327 = The hierarchy of the type {0} is inconsistent +328 = The declared package does not match the expected package {0} +329 = The type java.lang.Object cannot have a superclass or superinterfaces + +330 = {0} cannot be resolved or is not a valid superclass +331 = Superclass {0} is not visible +332 = Superclass {0} is ambiguous +333 = Superclass {0} is an incorrectly specified nested type; replace the ''$'' with ''.'' +334 = Superclass {0} is defined in an inherited type and an enclosing scope +335 = {0} cannot be resolved or is not a valid superinterface +336 = Superinterface {0} is not visible +337 = Superinterface {0} is ambiguous +338 = Superinterface {0} is an incorrectly specified nested type; replace the ''$'' with ''.'' +339 = Superinterface {0} is defined in an inherited type and an enclosing scope +340 = Duplicate field {0}.{1} +341 = Duplicate modifier for the field {0} +342 = Illegal modifier for the field {0}; only public, protected, private, static, final, transient & volatile are permitted +343 = Illegal modifier for the interface field {0}; only public, static & final are permitted +344 = The field {0} can only set one of public / protected / private +345 = The field {0} can be either final or volatile, not both +346 = The field {0} cannot be declared static; static fields can only be declared in static or top level types + +350 = {2} cannot be resolved (or is not a valid type) for the field {1}.{0} +351 = The type {2} is not visible for the field {1}.{0} +352 = The type {2} is ambiguous for the field {1}.{0} +353 = The field type {2} is an incorrectly specified nested type; replace the ''$'' with ''.'' +354 = The field type {2} is defined in an inherited type and an enclosing scope +355 = Duplicate method {0} in type {1} +356 = Illegal modifier for argument {0}; only final is permitted +357 = Duplicate modifier for the method {1} in type {0} +358 = Illegal modifier for the method {1} in type {0} +359 = Illegal modifier for the interface method {1} in type {0}; only public & abstract are permitted +360 = The method {1} in type {0} can only set one of public / protected / private +361 = The method {1} cannot be declared static; static methods can only be declared in a static or top level type +362 = The abstract method {1} in type {0} can only set a visibility modifier, one of public or protected +363 = The abstract method {1} in type {0} can only be defined by an abstract class +364 = void is an invalid type for the argument {1} of the method {0} +365 = An array of void is an invalid type for the argument {1} of the method {0} +366 = An array of void is an invalid return type for the method {0} +367 = The native method {1} cannot also be declared strictfp +368 = Duplicate modifier for argument {0} + +370 = {2} cannot be resolved (or is not a valid type) for the argument {1} of the method {0} +371 = The type {2} is not visible for the argument {1} of the method {0} +372 = The type {2} is ambiguous for the argument {1} of the method {0} +373 = The argument type {2} is an incorrectly specified nested type; replace the ''$'' with ''.'' +374 = The argument type {2} is defined in an inherited type and an enclosing scope +375 = {1} cannot be resolved (or is not an exception type) for the method {0} +376 = The exception type {1} is not visible for the method {0} +377 = The exception type {1} is ambiguous for the method {0} +378 = The exception type {1} is an incorrectly specified nested type; replace the ''$'' with ''.'' +379 = The exception type {1} is defined in an inherited type and an enclosing scope +380 = {1} cannot be resolved (or is not a valid return type) for the method {0} +381 = The return type {1} is not visible for the method {0} +382 = The return type {1} is ambiguous for the method {0} +383 = The return type {1} is an incorrectly specified nested type; replace the ''$'' with ''.'' +384 = The return type {1} is defined in an inherited type and an enclosing scope +385 = The import {0} conflicts with a type defined in the same file +386 = The import {0} collides with another imported type +387 = Only a type can be imported. {0} resolves to a package +388 = The import {0} is never used +390 = The import {0} cannot be resolved +391 = The imported type {0} is not visible +392 = The imported type {0} is ambiguous +393 = The type {0} is an incorrectly specified nested type; replace the ''$'' with ''.'' +394 = The type {0} is defined in an inherited type and an enclosing scope +395 = Duplicate modifier for the variable {0} +396 = Illegal modifier for the variable {0}; only final is permitted + +400 = Class must implement the inherited abstract method {0} +401 = Cannot override the final method from {0} +402 = Exception {0} is not compatible with throws clause in {1} +403 = Exception {0} in throws clause of {1} is not compatible with {2} +404 = The return type is incompatible with {0} +405 = The inherited method {0} cannot hide the public abstract method in {1} +406 = This instance method cannot override the static method from {0} +407 = This static method cannot hide the instance method from {0} +408 = The static method {0} conflicts with the abstract method in {1} +409 = Cannot reduce the visibility of the inherited method from {0} +410 = The method {0} does not override the inherited method from {1} since it is private to a different package. +411 = This class must implement the inherited abstract method {1}, but cannot override it since it is not visible from {0}. Either make the type abstract or make the inherited method visible. +412 = The method {0} overrides a deprecated method from {1} +413 = The return type is incompatible with {0}, thus this interface cannot be implemented +414 = Exception {0} is not compatible with throws clause in {1}, thus this interface cannot be implemented + +420 = Code snippet support cannot find the class {0} +421 = Code snippet support cannot find the method {0}.{1}({2}) +422 = super cannot be used in the code snippet code + +430 = Too many constants, the constant pool for {0} would exceed 65536 entries +431 = The type generates a string that requires more than 65535 bytes to encode in Utf8 format in the constant pool + +432 = Too many fields for type {0}. Maximum is 65535 +433 = Too many methods for type {0}. Maximum is 65535 + +440 = ''assert'' should not be used as an identifier, since it is a reserved keyword from source level 1.4 on + +450 = {0} {1} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/CompoundNameVector.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/CompoundNameVector.java new file mode 100644 index 0000000..10832b6 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/CompoundNameVector.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.util; + +import net.sourceforge.phpdt.core.compiler.CharOperation; + +public final class CompoundNameVector { + static int INITIAL_SIZE = 10; + + public int size; + int maxSize; + char[][][] elements; +public CompoundNameVector() { + maxSize = INITIAL_SIZE; + size = 0; + elements = new char[maxSize][][]; +} +public void add(char[][] newElement) { + if (size == maxSize) // knows that size starts <= maxSize + System.arraycopy(elements, 0, (elements = new char[maxSize *= 2][][]), 0, size); + elements[size++] = newElement; +} +public void addAll(char[][][] newElements) { + if (size + newElements.length >= maxSize) { + maxSize = size + newElements.length; // assume no more elements will be added + System.arraycopy(elements, 0, (elements = new char[maxSize][][]), 0, size); + } + System.arraycopy(newElements, 0, elements, size, newElements.length); + size += newElements.length; +} +public boolean contains(char[][] element) { + for (int i = size; --i >= 0;) + if (CharOperation.equals(element, elements[i])) + return true; + return false; +} +public char[][] elementAt(int index) { + return elements[index]; +} +public char[][] remove(char[][] element) { + // assumes only one occurrence of the element exists + for (int i = size; --i >= 0;) + if (element == elements[i]) { + // shift the remaining elements down one spot + System.arraycopy(elements, i + 1, elements, i, --size - i); + elements[size] = null; + return element; + } + return null; +} +public void removeAll() { + for (int i = size; --i >= 0;) + elements[i] = null; + size = 0; +} +public String toString() { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < size; i++) { + buffer.append(CharOperation.toString(elements[i])).append("\n"); //$NON-NLS-1$ + } + return buffer.toString(); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfInt.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfInt.java new file mode 100644 index 0000000..cf20807 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfInt.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.util; + + /** + * Hashtable for non-zero int keys. + */ + +public final class HashtableOfInt { + // to avoid using Enumerations, walk the individual tables skipping nulls + public int[] keyTable; + public Object[] valueTable; + + int elementSize; // number of elements in the table + int threshold; +public HashtableOfInt() { + this(13); +} +public HashtableOfInt(int size) { + this.elementSize = 0; + this.threshold = size; // size represents the expected number of elements + int extraRoom = (int) (size * 1.75f); + if (this.threshold == extraRoom) + extraRoom++; + this.keyTable = new int[extraRoom]; + this.valueTable = new Object[extraRoom]; +} +public boolean containsKey(int key) { + int index = key % valueTable.length; + int currentKey; + while ((currentKey = keyTable[index]) != 0) { + if (currentKey == key) + return true; + index = (index + 1) % keyTable.length; + } + return false; +} +public Object get(int key) { + int index = key % valueTable.length; + int currentKey; + while ((currentKey = keyTable[index]) != 0) { + if (currentKey == key) return valueTable[index]; + index = (index + 1) % keyTable.length; + } + return null; +} +public Object put(int key, Object value) { + int index = key % valueTable.length; + int currentKey; + while ((currentKey = keyTable[index]) != 0) { + if (currentKey == key) return valueTable[index] = value; + index = (index + 1) % keyTable.length; + } + keyTable[index] = key; + valueTable[index] = value; + + // assumes the threshold is never equal to the size of the table + if (++elementSize > threshold) + rehash(); + return value; +} +private void rehash() { + HashtableOfInt newHashtable = new HashtableOfInt(elementSize * 2); // double the number of expected elements + int currentKey; + for (int i = keyTable.length; --i >= 0;) + if ((currentKey = keyTable[i]) != 0) + newHashtable.put(currentKey, valueTable[i]); + + this.keyTable = newHashtable.keyTable; + this.valueTable = newHashtable.valueTable; + this.threshold = newHashtable.threshold; +} +public int size() { + return elementSize; +} +public String toString() { + String s = ""; //$NON-NLS-1$ + Object object; + for (int i = 0, length = valueTable.length; i < length; i++) + if ((object = valueTable[i]) != null) + s += keyTable[i] + " -> " + object.toString() + "\n"; //$NON-NLS-2$ //$NON-NLS-1$ + return s; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfLong.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfLong.java new file mode 100644 index 0000000..833a631 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfLong.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.util; + + /** + * Hashtable for non-zero long keys. + */ + +public final class HashtableOfLong { + // to avoid using Enumerations, walk the individual tables skipping nulls + public long[] keyTable; + public Object[] valueTable; + + int elementSize; // number of elements in the table + int threshold; +public HashtableOfLong() { + this(13); +} +public HashtableOfLong(int size) { + this.elementSize = 0; + this.threshold = size; // size represents the expected number of elements + int extraRoom = (int) (size * 1.75f); + if (this.threshold == extraRoom) + extraRoom++; + this.keyTable = new long[extraRoom]; + this.valueTable = new Object[extraRoom]; +} +public boolean containsKey(long key) { + int index = ((int)(key >>> 32)) % valueTable.length; + long currentKey; + while ((currentKey = keyTable[index]) != 0) { + if (currentKey == key) + return true; + index = (index + 1) % keyTable.length; + } + return false; +} +public Object get(long key) { + int index = ((int)(key >>> 32)) % valueTable.length; + long currentKey; + while ((currentKey = keyTable[index]) != 0) { + if (currentKey == key) return valueTable[index]; + index = (index + 1) % keyTable.length; + } + return null; +} +public Object put(long key, Object value) { + int index = ((int)(key >>> 32)) % valueTable.length; + long currentKey; + while ((currentKey = keyTable[index]) != 0) { + if (currentKey == key) return valueTable[index] = value; + index = (index + 1) % keyTable.length; + } + keyTable[index] = key; + valueTable[index] = value; + + // assumes the threshold is never equal to the size of the table + if (++elementSize > threshold) + rehash(); + return value; +} +private void rehash() { + HashtableOfLong newHashtable = new HashtableOfLong(elementSize * 2); // double the number of expected elements + long currentKey; + for (int i = keyTable.length; --i >= 0;) + if ((currentKey = keyTable[i]) != 0) + newHashtable.put(currentKey, valueTable[i]); + + this.keyTable = newHashtable.keyTable; + this.valueTable = newHashtable.valueTable; + this.threshold = newHashtable.threshold; +} +public int size() { + return elementSize; +} +public String toString() { + String s = ""; //$NON-NLS-1$ + Object object; + for (int i = 0, length = valueTable.length; i < length; i++) + if ((object = valueTable[i]) != null) + s += keyTable[i] + " -> " + object.toString() + "\n"; //$NON-NLS-2$ //$NON-NLS-1$ + return s; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfObject.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfObject.java new file mode 100644 index 0000000..a739830 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfObject.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.util; + +import net.sourceforge.phpdt.core.compiler.CharOperation; + +/** + * Hashtable of {char[] --> Object } + */ +public final class HashtableOfObject implements Cloneable { + + // to avoid using Enumerations, walk the individual tables skipping nulls + public char[] keyTable[]; + public Object valueTable[]; + + public int elementSize; // number of elements in the table + int threshold; + + public HashtableOfObject() { + this(13); + } + + public HashtableOfObject(int size) { + + this.elementSize = 0; + this.threshold = size; // size represents the expected number of elements + int extraRoom = (int) (size * 1.75f); + if (this.threshold == extraRoom) + extraRoom++; + this.keyTable = new char[extraRoom][]; + this.valueTable = new Object[extraRoom]; + } + + public Object clone() throws CloneNotSupportedException { + HashtableOfObject result = (HashtableOfObject) super.clone(); + result.elementSize = this.elementSize; + result.threshold = this.threshold; + + int length = this.keyTable.length; + result.keyTable = new char[length][]; + System.arraycopy(this.keyTable, 0, result.keyTable, 0, length); + + length = this.valueTable.length; + result.valueTable = new Object[length]; + System.arraycopy(this.valueTable, 0, result.valueTable, 0, length); + return result; + } + + public boolean containsKey(char[] key) { + + int index = CharOperation.hashCode(key) % valueTable.length; + int keyLength = key.length; + char[] currentKey; + while ((currentKey = keyTable[index]) != null) { + if (currentKey.length == keyLength + && CharOperation.prefixEquals(currentKey, key)) + return true; + index = (index + 1) % keyTable.length; + } + return false; + } + + public Object get(char[] key) { + + int index = CharOperation.hashCode(key) % valueTable.length; + int keyLength = key.length; + char[] currentKey; + while ((currentKey = keyTable[index]) != null) { + if (currentKey.length == keyLength + && CharOperation.prefixEquals(currentKey, key)) + return valueTable[index]; + index = (index + 1) % keyTable.length; + } + return null; + } + + public Object put(char[] key, Object value) { + + int index = CharOperation.hashCode(key) % valueTable.length; + int keyLength = key.length; + char[] currentKey; + while ((currentKey = keyTable[index]) != null) { + if (currentKey.length == keyLength + && CharOperation.prefixEquals(currentKey, key)) + return valueTable[index] = value; + index = (index + 1) % keyTable.length; + } + keyTable[index] = key; + valueTable[index] = value; + + // assumes the threshold is never equal to the size of the table + if (++elementSize > threshold) + rehash(); + return value; + } + + public Object removeKey(char[] key) { + + int index = CharOperation.hashCode(key) % valueTable.length; + int keyLength = key.length; + char[] currentKey; + while ((currentKey = keyTable[index]) != null) { + if (currentKey.length == keyLength + && CharOperation.prefixEquals(currentKey, key)) { + Object value = valueTable[index]; + elementSize--; + keyTable[index] = null; + valueTable[index] = null; + rehash(); + return value; + } + index = (index + 1) % keyTable.length; + } + return null; + } + + private void rehash() { + + HashtableOfObject newHashtable = new HashtableOfObject(elementSize * 2); // double the number of expected elements + char[] currentKey; + for (int i = keyTable.length; --i >= 0;) + if ((currentKey = keyTable[i]) != null) + newHashtable.put(currentKey, valueTable[i]); + + this.keyTable = newHashtable.keyTable; + this.valueTable = newHashtable.valueTable; + this.threshold = newHashtable.threshold; + } + + public int size() { + return elementSize; + } + + public String toString() { + String s = ""; //$NON-NLS-1$ + Object object; + for (int i = 0, length = valueTable.length; i < length; i++) + if ((object = valueTable[i]) != null) + s += new String(keyTable[i]) + " -> " + object.toString() + "\n"; //$NON-NLS-2$ //$NON-NLS-1$ + return s; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfPackage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfPackage.java new file mode 100644 index 0000000..8dab8c3 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfPackage.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.util; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding; + +public final class HashtableOfPackage { + // to avoid using Enumerations, walk the individual tables skipping nulls + public char[] keyTable[]; + public PackageBinding valueTable[]; + + int elementSize; // number of elements in the table + int threshold; +public HashtableOfPackage() { + this(3); // usually not very large +} +public HashtableOfPackage(int size) { + this.elementSize = 0; + this.threshold = size; // size represents the expected number of elements + int extraRoom = (int) (size * 1.75f); + if (this.threshold == extraRoom) + extraRoom++; + this.keyTable = new char[extraRoom][]; + this.valueTable = new PackageBinding[extraRoom]; +} +public boolean containsKey(char[] key) { + int index = CharOperation.hashCode(key) % valueTable.length; + int keyLength = key.length; + char[] currentKey; + while ((currentKey = keyTable[index]) != null) { + if (currentKey.length == keyLength && CharOperation.prefixEquals(currentKey, key)) + return true; + index = (index + 1) % keyTable.length; + } + return false; +} +public PackageBinding get(char[] key) { + int index = CharOperation.hashCode(key) % valueTable.length; + int keyLength = key.length; + char[] currentKey; + while ((currentKey = keyTable[index]) != null) { + if (currentKey.length == keyLength && CharOperation.prefixEquals(currentKey, key)) + return valueTable[index]; + index = (index + 1) % keyTable.length; + } + return null; +} +public PackageBinding put(char[] key, PackageBinding value) { + int index = CharOperation.hashCode(key) % valueTable.length; + int keyLength = key.length; + char[] currentKey; + while ((currentKey = keyTable[index]) != null) { + if (currentKey.length == keyLength && CharOperation.prefixEquals(currentKey, key)) + return valueTable[index] = value; + index = (index + 1) % keyTable.length; + } + keyTable[index] = key; + valueTable[index] = value; + + // assumes the threshold is never equal to the size of the table + if (++elementSize > threshold) + rehash(); + return value; +} +private void rehash() { + HashtableOfPackage newHashtable = new HashtableOfPackage(elementSize * 2); // double the number of expected elements + char[] currentKey; + for (int i = keyTable.length; --i >= 0;) + if ((currentKey = keyTable[i]) != null) + newHashtable.put(currentKey, valueTable[i]); + + this.keyTable = newHashtable.keyTable; + this.valueTable = newHashtable.valueTable; + this.threshold = newHashtable.threshold; +} +public int size() { + return elementSize; +} +public String toString() { + String s = ""; //$NON-NLS-1$ + PackageBinding pkg; + for (int i = 0, length = valueTable.length; i < length; i++) + if ((pkg = valueTable[i]) != null) + s += pkg.toString() + "\n"; //$NON-NLS-1$ + return s; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfType.java new file mode 100644 index 0000000..fbeec53 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/HashtableOfType.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.util; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; + +public final class HashtableOfType { + // to avoid using Enumerations, walk the individual tables skipping nulls + public char[] keyTable[]; + public ReferenceBinding valueTable[]; + + int elementSize; // number of elements in the table + int threshold; +public HashtableOfType() { + this(3); +} +public HashtableOfType(int size) { + this.elementSize = 0; + this.threshold = size; // size represents the expected number of elements + int extraRoom = (int) (size * 1.75f); + if (this.threshold == extraRoom) + extraRoom++; + this.keyTable = new char[extraRoom][]; + this.valueTable = new ReferenceBinding[extraRoom]; +} +public boolean containsKey(char[] key) { + int index = CharOperation.hashCode(key) % valueTable.length; + int keyLength = key.length; + char[] currentKey; + while ((currentKey = keyTable[index]) != null) { + if (currentKey.length == keyLength && CharOperation.prefixEquals(currentKey, key)) + return true; + index = (index + 1) % keyTable.length; + } + return false; +} +public ReferenceBinding get(char[] key) { + int index = CharOperation.hashCode(key) % valueTable.length; + int keyLength = key.length; + char[] currentKey; + while ((currentKey = keyTable[index]) != null) { + if (currentKey.length == keyLength && CharOperation.prefixEquals(currentKey, key)) + return valueTable[index]; + index = (index + 1) % keyTable.length; + } + return null; +} +public ReferenceBinding put(char[] key, ReferenceBinding value) { + int index = CharOperation.hashCode(key) % valueTable.length; + int keyLength = key.length; + char[] currentKey; + while ((currentKey = keyTable[index]) != null) { + if (currentKey.length == keyLength && CharOperation.prefixEquals(currentKey, key)) + return valueTable[index] = value; + index = (index + 1) % keyTable.length; + } + keyTable[index] = key; + valueTable[index] = value; + + // assumes the threshold is never equal to the size of the table + if (++elementSize > threshold) + rehash(); + return value; +} +private void rehash() { + HashtableOfType newHashtable = new HashtableOfType(elementSize < 100 ? 100 : elementSize * 2); // double the number of expected elements + char[] currentKey; + for (int i = keyTable.length; --i >= 0;) + if ((currentKey = keyTable[i]) != null) + newHashtable.put(currentKey, valueTable[i]); + + this.keyTable = newHashtable.keyTable; + this.valueTable = newHashtable.valueTable; + this.threshold = newHashtable.threshold; +} +public int size() { + return elementSize; +} +public String toString() { + String s = ""; //$NON-NLS-1$ + ReferenceBinding type; + for (int i = 0, length = valueTable.length; i < length; i++) + if ((type = valueTable[i]) != null) + s += type.toString() + "\n"; //$NON-NLS-1$ + return s; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/ObjectVector.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/ObjectVector.java new file mode 100644 index 0000000..40dd438 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/ObjectVector.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.util; + +public final class ObjectVector { + + static int INITIAL_SIZE = 10; + + public int size; + int maxSize; + Object[] elements; + + public ObjectVector() { + + this.maxSize = INITIAL_SIZE; + this.size = 0; + this.elements = new Object[this.maxSize]; + } + + public void add(Object newElement) { + + if (this.size == this.maxSize) // knows that size starts <= maxSize + System.arraycopy(this.elements, 0, (this.elements = new Object[this.maxSize *= 2]), 0, this.size); + this.elements[this.size++] = newElement; + } + + public void addAll(Object[] newElements) { + + if (this.size + newElements.length >= this.maxSize) { + maxSize = this.size + newElements.length; // assume no more elements will be added + System.arraycopy(this.elements, 0, (this.elements = new Object[this.maxSize]), 0, this.size); + } + System.arraycopy(newElements, 0, this.elements, size, newElements.length); + this.size += newElements.length; + } + + public void addAll(ObjectVector newVector) { + + if (this.size + newVector.size >= this.maxSize) { + maxSize = this.size + newVector.size; // assume no more elements will be added + System.arraycopy(this.elements, 0, (this.elements = new Object[this.maxSize]), 0, this.size); + } + System.arraycopy(newVector.elements, 0, this.elements, size, newVector.size); + this.size += newVector.size; + } + + /** + * Identity check + */ + public boolean containsIdentical(Object element) { + + for (int i = this.size; --i >= 0;) + if (element == this.elements[i]) + return true; + return false; + } + + /** + * Equality check + */ + public boolean contains(Object element) { + + for (int i = this.size; --i >= 0;) + if (element.equals(this.elements[i])) + return true; + return false; + } + + public void copyInto(Object[] targetArray){ + + this.copyInto(targetArray, 0); + } + + public void copyInto(Object[] targetArray, int index){ + + System.arraycopy(this.elements, 0, targetArray, index, this.size); + } + + public Object elementAt(int index) { + + return this.elements[index]; + } + + public Object find(Object element) { + + for (int i = this.size; --i >= 0;) + if (element.equals(this.elements[i])) + return element; + return null; + } + + public Object remove(Object element) { + + // assumes only one occurrence of the element exists + for (int i = this.size; --i >= 0;) + if (element.equals(this.elements[i])) { + // shift the remaining elements down one spot + System.arraycopy(this.elements, i + 1, this.elements, i, --this.size - i); + this.elements[this.size] = null; + return element; + } + return null; + } + + public void removeAll() { + + for (int i = this.size; --i >= 0;) + this.elements[i] = null; + this.size = 0; + } + + public int size(){ + + return this.size; + } + + public String toString() { + + String s = ""; //$NON-NLS-1$ + for (int i = 0; i < this.size; i++) + s += this.elements[i].toString() + "\n"; //$NON-NLS-1$ + return s; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/SimpleNameVector.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/SimpleNameVector.java new file mode 100644 index 0000000..1814923 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/SimpleNameVector.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.util; + +import net.sourceforge.phpdt.core.compiler.CharOperation; + +public final class SimpleNameVector { + + static int INITIAL_SIZE = 10; + + public int size; + int maxSize; + char[][] elements; + + public SimpleNameVector() { + + this.maxSize = INITIAL_SIZE; + this.size = 0; + this.elements = new char[this.maxSize][]; + } + + public void add(char[] newElement) { + + if (this.size == this.maxSize) // knows that size starts <= maxSize + System.arraycopy(this.elements, 0, (this.elements = new char[this.maxSize *= 2][]), 0, this.size); + this.elements[size++] = newElement; + } + + public void addAll(char[][] newElements) { + + if (this.size + newElements.length >= this.maxSize) { + this.maxSize = this.size + newElements.length; // assume no more elements will be added + System.arraycopy(this.elements, 0, (this.elements = new char[this.maxSize][]), 0, this.size); + } + System.arraycopy(newElements, 0, this.elements, this.size, newElements.length); + this.size += newElements.length; + } + + public void copyInto(Object[] targetArray){ + + System.arraycopy(this.elements, 0, targetArray, 0, this.size); + } + + public boolean contains(char[] element) { + + for (int i = this.size; --i >= 0;) + if (CharOperation.equals(element, this.elements[i])) + return true; + return false; + } + + public char[] elementAt(int index) { + return this.elements[index]; + } + + public char[] remove(char[] element) { + + // assumes only one occurrence of the element exists + for (int i = this.size; --i >= 0;) + if (element == this.elements[i]) { + // shift the remaining elements down one spot + System.arraycopy(this.elements, i + 1, this.elements, i, --this.size - i); + this.elements[this.size] = null; + return element; + } + return null; + } + + public void removeAll() { + + for (int i = this.size; --i >= 0;) + this.elements[i] = null; + this.size = 0; + } + + public int size(){ + + return this.size; + } + + public String toString() { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < this.size; i++) { + buffer.append(this.elements[i]).append("\n"); //$NON-NLS-1$ + } + return buffer.toString(); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BasicCompilationUnit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BasicCompilationUnit.java new file mode 100644 index 0000000..f0176e0 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BasicCompilationUnit.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.io.File; +import java.io.IOException; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; +import net.sourceforge.phpdt.internal.compiler.util.Util; + +import org.eclipse.core.resources.IResource; + +/** + * A basic implementation of ICompilationUnit + * for use in the SourceMapper. + * @see ICompilationUnit + */ +public class BasicCompilationUnit implements ICompilationUnit { + protected char[] contents; + protected char[] fileName; + protected char[][] packageName; + protected char[] mainTypeName; + protected String encoding; + + public BasicCompilationUnit(char[] contents, char[][] packageName, String fileName, String encoding) { + this.contents = contents; + this.fileName = fileName.toCharArray(); + this.packageName = packageName; + + int start = fileName.lastIndexOf("/") + 1; //$NON-NLS-1$ + if (start == 0 || start < fileName.lastIndexOf("\\")) //$NON-NLS-1$ + start = fileName.lastIndexOf("\\") + 1; //$NON-NLS-1$ + + int end = fileName.lastIndexOf("."); //$NON-NLS-1$ + if (end == -1) + end = fileName.length(); + + this.mainTypeName = fileName.substring(start, end).toCharArray(); + this.encoding = encoding; + } + 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(fileName)), this.encoding); + } catch (IOException e) { + } + return CharOperation.NO_CHAR; + } + public char[] getFileName() { + return this.fileName; + } + public char[] getMainTypeName() { + return this.mainTypeName; + } + public char[][] getPackageName() { + return this.packageName; + } + public String toString() { + return "CompilationUnit: " + new String(fileName); //$NON-NLS-1$ + } + + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BufferCache.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BufferCache.java index 62ad8f0..7413c26 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BufferCache.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BufferCache.java @@ -11,7 +11,7 @@ package net.sourceforge.phpdt.internal.core; import net.sourceforge.phpdt.core.IBuffer; -import net.sourceforge.phpdt.core.util.LRUCache; +import net.sourceforge.phpdt.internal.core.util.LRUCache; /** * An LRU cache of IBuffers. diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BufferManager.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BufferManager.java index 993c2a7..511d041 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BufferManager.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BufferManager.java @@ -14,8 +14,12 @@ import java.util.Enumeration; import net.sourceforge.phpdt.core.IBuffer; import net.sourceforge.phpdt.core.IBufferFactory; +import net.sourceforge.phpdt.core.IJavaElement; import net.sourceforge.phpdt.core.IOpenable; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; + /** * The buffer manager manages the set of open buffers. @@ -45,15 +49,15 @@ protected void addBuffer(IBuffer buffer) { /** * @see IBufferFactory#createBuffer(IOpenable) */ -//public IBuffer createBuffer(IOpenable owner) { -// IJavaElement element = (IJavaElement)owner; -// IResource resource = element.getResource(); -// return -// new Buffer( -// resource instanceof IFile ? (IFile)resource : null, -// owner, -// element.isReadOnly()); -//} +public IBuffer createBuffer(IOpenable owner) { + IJavaElement element = (IJavaElement)owner; + IResource resource = element.getResource(); + return + new Buffer( + resource instanceof IFile ? (IFile)resource : null, + owner, + element.isReadOnly()); +} /** * Returns the open buffer associated with the given owner, diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/ClasspathEntry.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/ClasspathEntry.java new file mode 100644 index 0000000..bdb0401 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/ClasspathEntry.java @@ -0,0 +1,587 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.IClasspathEntry; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.corext.Assert; +import net.sourceforge.phpeclipse.PHPCore; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * @see IClasspathEntry + */ +public class ClasspathEntry implements IClasspathEntry { + + /** + * Describes the kind of classpath entry - one of + * CPE_PROJECT, CPE_LIBRARY, CPE_SOURCE, CPE_VARIABLE or CPE_CONTAINER + */ + public int entryKind; + + /** + * Describes the kind of package fragment roots found on + * this classpath entry - either K_BINARY or K_SOURCE or + * K_OUTPUT. + */ + public int contentKind; + + /** + * The meaning of the path of a classpath entry depends on its entry kind:
      + *
    • Source code in the current project (CPE_SOURCE) - + * The path associated with this entry is the absolute path to the root folder.
    • + *
    • A binary library in the current project (CPE_LIBRARY) - the path + * associated with this entry is the absolute path to the JAR (or root folder), and + * in case it refers to an external JAR, then there is no associated resource in + * the workbench. + *
    • A required project (CPE_PROJECT) - the path of the entry denotes the + * path to the corresponding project resource.
    • + *
    • A variable entry (CPE_VARIABLE) - the first segment of the path + * is the name of a classpath variable. If this classpath variable + * is bound to the path P, the path of the corresponding classpath entry + * is computed by appending to P the segments of the returned + * path without the variable.
    • + *
    • A container entry (CPE_CONTAINER) - the first segment of the path is denoting + * the unique container identifier (for which a ClasspathContainerInitializer could be + * registered), and the remaining segments are used as additional hints for resolving the container entry to + * an actual IClasspathContainer.
    • + */ + public IPath path; + + /** + * Patterns allowing to exclude portions of the resource tree denoted by this entry path. + */ + + public IPath[] exclusionPatterns; + private char[][] fullCharExclusionPatterns; + private final static char[][] UNINIT_PATTERNS = new char[][] { "Non-initialized yet".toCharArray() }; //$NON-NLS-1$ + + private String rootID; + + /** + * Default exclusion pattern set + */ + public final static IPath[] NO_EXCLUSION_PATTERNS = {}; + + /** + * Describes the path to the source archive associated with this + * classpath entry, or null if this classpath entry has no + * source attachment. + *

      + * Only library and variable classpath entries may have source attachments. + * For library classpath entries, the result path (if present) locates a source + * archive. For variable classpath entries, the result path (if present) has + * an analogous form and meaning as the variable path, namely the first segment + * is the name of a classpath variable. + */ + public IPath sourceAttachmentPath; + + /** + * Describes the path within the source archive where package fragments + * are located. An empty path indicates that packages are located at + * the root of the source archive. Returns a non-null value + * if and only if getSourceAttachmentPath returns + * a non-null value. + */ + public IPath sourceAttachmentRootPath; + + /** + * Specific output location (for this source entry) + */ + public IPath specificOutputLocation; + + /** + * A constant indicating an output location. + */ + public static final int K_OUTPUT = 10; + + /** + * The export flag + */ + public boolean isExported; + + /** + * Creates a class path entry of the specified kind with the given path. + */ + public ClasspathEntry( + int contentKind, + int entryKind, + IPath path, + IPath[] exclusionPatterns, + IPath sourceAttachmentPath, + IPath sourceAttachmentRootPath, + IPath specificOutputLocation, + boolean isExported) { + + this.contentKind = contentKind; + this.entryKind = entryKind; + this.path = path; + this.exclusionPatterns = exclusionPatterns; + if (exclusionPatterns.length > 0) { + this.fullCharExclusionPatterns = UNINIT_PATTERNS; + } + this.sourceAttachmentPath = sourceAttachmentPath; + this.sourceAttachmentRootPath = sourceAttachmentRootPath; + this.specificOutputLocation = specificOutputLocation; + this.isExported = isExported; + } + + /* + * Returns a char based representation of the exclusions patterns full path. + */ + public char[][] fullExclusionPatternChars() { + + if (this.fullCharExclusionPatterns == UNINIT_PATTERNS) { + int length = this.exclusionPatterns.length; + this.fullCharExclusionPatterns = new char[length][]; + IPath prefixPath = path.removeTrailingSeparator(); + for (int i = 0; i < length; i++) { + this.fullCharExclusionPatterns[i] = + prefixPath.append(this.exclusionPatterns[i]).toString().toCharArray(); + } + } + return this.fullCharExclusionPatterns; + } + + /** + * Returns the XML encoding of the class path. + */ + public Element elementEncode( + Document document, + IPath projectPath) + throws JavaModelException { + + Element element = document.createElement("classpathentry"); //$NON-NLS-1$ + element.setAttribute("kind", kindToString(this.entryKind)); //$NON-NLS-1$ + IPath xmlPath = this.path; + if (this.entryKind != IClasspathEntry.CPE_VARIABLE && this.entryKind != IClasspathEntry.CPE_CONTAINER) { + // translate to project relative from absolute (unless a device path) + if (xmlPath.isAbsolute()) { + if (projectPath != null && projectPath.isPrefixOf(xmlPath)) { + if (xmlPath.segment(0).equals(projectPath.segment(0))) { + xmlPath = xmlPath.removeFirstSegments(1); + xmlPath = xmlPath.makeRelative(); + } else { + xmlPath = xmlPath.makeAbsolute(); + } + } + } + } + element.setAttribute("path", xmlPath.toString()); //$NON-NLS-1$ + if (this.sourceAttachmentPath != null) { + element.setAttribute("sourcepath", this.sourceAttachmentPath.toString()); //$NON-NLS-1$ + } + if (this.sourceAttachmentRootPath != null) { + element.setAttribute("rootpath", this.sourceAttachmentRootPath.toString()); //$NON-NLS-1$ + } + if (this.isExported) { + element.setAttribute("exported", "true"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + if (this.exclusionPatterns.length > 0) { + StringBuffer excludeRule = new StringBuffer(10); + for (int i = 0, max = this.exclusionPatterns.length; i < max; i++){ + if (i > 0) excludeRule.append('|'); + excludeRule.append(this.exclusionPatterns[i]); + } + element.setAttribute("excluding", excludeRule.toString()); //$NON-NLS-1$ + } + + if (this.specificOutputLocation != null) { + IPath outputLocation = this.specificOutputLocation.removeFirstSegments(1); + outputLocation = outputLocation.makeRelative(); + element.setAttribute("output", outputLocation.toString()); //$NON-NLS-1$ + } + return element; + } + + public static IClasspathEntry elementDecode(Element element, IJavaProject project) { + + IPath projectPath = project.getProject().getFullPath(); + String kindAttr = element.getAttribute("kind"); //$NON-NLS-1$ + String pathAttr = element.getAttribute("path"); //$NON-NLS-1$ + + // ensure path is absolute + IPath path = new Path(pathAttr); + int kind = kindFromString(kindAttr); + if (kind != IClasspathEntry.CPE_VARIABLE && kind != IClasspathEntry.CPE_CONTAINER && !path.isAbsolute()) { + path = projectPath.append(path); + } + // source attachment info (optional) + IPath sourceAttachmentPath = + element.hasAttribute("sourcepath") //$NON-NLS-1$ + ? new Path(element.getAttribute("sourcepath")) //$NON-NLS-1$ + : null; + IPath sourceAttachmentRootPath = + element.hasAttribute("rootpath") //$NON-NLS-1$ + ? new Path(element.getAttribute("rootpath")) //$NON-NLS-1$ + : null; + + // exported flag (optional) + boolean isExported = element.getAttribute("exported").equals("true"); //$NON-NLS-1$ //$NON-NLS-2$ + + // exclusion patterns (optional) + String exclusion = element.getAttribute("excluding"); //$NON-NLS-1$ + IPath[] exclusionPatterns = ClasspathEntry.NO_EXCLUSION_PATTERNS; + if (!exclusion.equals("")) { //$NON-NLS-1$ + char[][] patterns = CharOperation.splitOn('|', exclusion.toCharArray()); + int patternCount; + if ((patternCount = patterns.length) > 0) { + exclusionPatterns = new IPath[patternCount]; + for (int j = 0; j < patterns.length; j++){ + exclusionPatterns[j] = new Path(new String(patterns[j])); + } + } + } + + // custom output location + IPath outputLocation = element.hasAttribute("output") ? projectPath.append(element.getAttribute("output")) : null; //$NON-NLS-1$ //$NON-NLS-2$ + + // recreate the CP entry + switch (kind) { + + case IClasspathEntry.CPE_PROJECT : + return PHPCore.newProjectEntry(path, isExported); + +// case IClasspathEntry.CPE_LIBRARY : +// return JavaCore.newLibraryEntry( +// path, +// sourceAttachmentPath, +// sourceAttachmentRootPath, +// isExported); + + case IClasspathEntry.CPE_SOURCE : + // must be an entry in this project or specify another project + String projSegment = path.segment(0); + if (projSegment != null && projSegment.equals(project.getElementName())) { // this project + return PHPCore.newSourceEntry(path, exclusionPatterns, outputLocation); + } else { // another project + return PHPCore.newProjectEntry(path, isExported); + } + +// case IClasspathEntry.CPE_VARIABLE : +// return PHPCore.newVariableEntry( +// path, +// sourceAttachmentPath, +// sourceAttachmentRootPath, +// isExported); + + case IClasspathEntry.CPE_CONTAINER : + return PHPCore.newContainerEntry( + path, + isExported); + + case ClasspathEntry.K_OUTPUT : + if (!path.isAbsolute()) return null; + return new ClasspathEntry( + ClasspathEntry.K_OUTPUT, + IClasspathEntry.CPE_LIBRARY, + path, + ClasspathEntry.NO_EXCLUSION_PATTERNS, + null, // source attachment + null, // source attachment root + null, // custom output location + false); + default : + throw new Assert.AssertionFailedException(Util.bind("classpath.unknownKind", kindAttr)); //$NON-NLS-1$ + } + } + + /** + * Returns true if the given object is a classpath entry + * with equivalent attributes. + */ + public boolean equals(Object object) { + if (this == object) + return true; + if (object instanceof IClasspathEntry) { + IClasspathEntry otherEntry = (IClasspathEntry) object; + + if (this.contentKind != otherEntry.getContentKind()) + return false; + + if (this.entryKind != otherEntry.getEntryKind()) + return false; + + if (this.isExported != otherEntry.isExported()) + return false; + + if (!this.path.equals(otherEntry.getPath())) + return false; + + IPath otherPath = otherEntry.getSourceAttachmentPath(); + if (this.sourceAttachmentPath == null) { + if (otherPath != null) + return false; + } else { + if (!this.sourceAttachmentPath.equals(otherPath)) + return false; + } + + otherPath = otherEntry.getSourceAttachmentRootPath(); + if (this.sourceAttachmentRootPath == null) { + if (otherPath != null) + return false; + } else { + if (!this.sourceAttachmentRootPath.equals(otherPath)) + return false; + } + + IPath[] otherExcludes = otherEntry.getExclusionPatterns(); + if (this.exclusionPatterns != otherExcludes){ + int excludeLength = this.exclusionPatterns.length; + if (otherExcludes.length != excludeLength) + return false; + for (int i = 0; i < excludeLength; i++) { + // compare toStrings instead of IPaths + // since IPath.equals is specified to ignore trailing separators + if (!this.exclusionPatterns[i].toString().equals(otherExcludes[i].toString())) + return false; + } + } + + otherPath = otherEntry.getOutputLocation(); + if (this.specificOutputLocation == null) { + if (otherPath != null) + return false; + } else { + if (!this.specificOutputLocation.equals(otherPath)) + return false; + } + return true; + } else { + return false; + } + } + + /** + * @see IClasspathEntry + */ + public int getContentKind() { + return this.contentKind; + } + + /** + * @see IClasspathEntry + */ + public int getEntryKind() { + return this.entryKind; + } + + /** + * @see IClasspathEntry#getExclusionPatterns() + */ + public IPath[] getExclusionPatterns() { + return this.exclusionPatterns; + } + + /** + * @see IClasspathEntry#getOutputLocation() + */ + public IPath getOutputLocation() { + return this.specificOutputLocation; + } + + /** + * @see IClasspathEntry + */ + public IPath getPath() { + return this.path; + } + + /** + * @see IClasspathEntry + */ + public IPath getSourceAttachmentPath() { + return this.sourceAttachmentPath; + } + + /** + * @see IClasspathEntry + */ + public IPath getSourceAttachmentRootPath() { + return this.sourceAttachmentRootPath; + } + + /** + * Returns the hash code for this classpath entry + */ + public int hashCode() { + return this.path.hashCode(); + } + + /** + * @see IClasspathEntry#isExported() + */ + public boolean isExported() { + return this.isExported; + } + + /** + * Returns the kind of a PackageFragmentRoot from its String form. + */ + static int kindFromString(String kindStr) { + + if (kindStr.equalsIgnoreCase("prj")) //$NON-NLS-1$ + return IClasspathEntry.CPE_PROJECT; + if (kindStr.equalsIgnoreCase("var")) //$NON-NLS-1$ + return IClasspathEntry.CPE_VARIABLE; + if (kindStr.equalsIgnoreCase("con")) //$NON-NLS-1$ + return IClasspathEntry.CPE_CONTAINER; + if (kindStr.equalsIgnoreCase("src")) //$NON-NLS-1$ + return IClasspathEntry.CPE_SOURCE; + if (kindStr.equalsIgnoreCase("lib")) //$NON-NLS-1$ + return IClasspathEntry.CPE_LIBRARY; + if (kindStr.equalsIgnoreCase("output")) //$NON-NLS-1$ + return ClasspathEntry.K_OUTPUT; + return -1; + } + + /** + * Returns a String for the kind of a class path entry. + */ + static String kindToString(int kind) { + + switch (kind) { + case IClasspathEntry.CPE_PROJECT : + return "src"; // backward compatibility //$NON-NLS-1$ + case IClasspathEntry.CPE_SOURCE : + return "src"; //$NON-NLS-1$ + case IClasspathEntry.CPE_LIBRARY : + return "lib"; //$NON-NLS-1$ + case IClasspathEntry.CPE_VARIABLE : + return "var"; //$NON-NLS-1$ + case IClasspathEntry.CPE_CONTAINER : + return "con"; //$NON-NLS-1$ + case ClasspathEntry.K_OUTPUT : + return "output"; //$NON-NLS-1$ + default : + return "unknown"; //$NON-NLS-1$ + } + } + + /** + * Returns a printable representation of this classpath entry. + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(getPath().toString()); + buffer.append('['); + switch (getEntryKind()) { + case IClasspathEntry.CPE_LIBRARY : + buffer.append("CPE_LIBRARY"); //$NON-NLS-1$ + break; + case IClasspathEntry.CPE_PROJECT : + buffer.append("CPE_PROJECT"); //$NON-NLS-1$ + break; + case IClasspathEntry.CPE_SOURCE : + buffer.append("CPE_SOURCE"); //$NON-NLS-1$ + break; + case IClasspathEntry.CPE_VARIABLE : + buffer.append("CPE_VARIABLE"); //$NON-NLS-1$ + break; + case IClasspathEntry.CPE_CONTAINER : + buffer.append("CPE_CONTAINER"); //$NON-NLS-1$ + break; + } + buffer.append("]["); //$NON-NLS-1$ + switch (getContentKind()) { + case IPackageFragmentRoot.K_BINARY : + buffer.append("K_BINARY"); //$NON-NLS-1$ + break; + case IPackageFragmentRoot.K_SOURCE : + buffer.append("K_SOURCE"); //$NON-NLS-1$ + break; + case ClasspathEntry.K_OUTPUT : + buffer.append("K_OUTPUT"); //$NON-NLS-1$ + break; + } + buffer.append(']'); + if (getSourceAttachmentPath() != null) { + buffer.append("[sourcePath:"); //$NON-NLS-1$ + buffer.append(getSourceAttachmentPath()); + buffer.append(']'); + } + if (getSourceAttachmentRootPath() != null) { + buffer.append("[rootPath:"); //$NON-NLS-1$ + buffer.append(getSourceAttachmentRootPath()); + buffer.append(']'); + } + buffer.append("[isExported:"); //$NON-NLS-1$ + buffer.append(this.isExported); + buffer.append(']'); + IPath[] patterns = getExclusionPatterns(); + int length; + if ((length = patterns.length) > 0) { + buffer.append("[excluding:"); //$NON-NLS-1$ + for (int i = 0; i < length; i++) { + buffer.append(patterns[i]); + if (i != length-1) { + buffer.append('|'); + } + } + buffer.append(']'); + } + if (getOutputLocation() != null) { + buffer.append("[output:"); //$NON-NLS-1$ + buffer.append(getOutputLocation()); + buffer.append(']'); + } + return buffer.toString(); + } + + /** + * Answers an ID which is used to distinguish entries during package + * fragment root computations + */ + public String rootID(){ + + if (this.rootID == null) { + switch(this.entryKind){ + case IClasspathEntry.CPE_LIBRARY : + this.rootID = "[LIB]"+this.path; //$NON-NLS-1$ + break; + case IClasspathEntry.CPE_PROJECT : + this.rootID = "[PRJ]"+this.path; //$NON-NLS-1$ + break; + case IClasspathEntry.CPE_SOURCE : + this.rootID = "[SRC]"+this.path; //$NON-NLS-1$ + break; + case IClasspathEntry.CPE_VARIABLE : + this.rootID = "[VAR]"+this.path; //$NON-NLS-1$ + break; + case IClasspathEntry.CPE_CONTAINER : + this.rootID = "[CON]"+this.path; //$NON-NLS-1$ + break; + default : + this.rootID = ""; //$NON-NLS-1$ + break; + } + } + return this.rootID; + } + + /** + * @see IClasspathEntry + * @deprecated + */ + public IClasspathEntry getResolvedEntry() { + + return PHPCore.getResolvedClasspathEntry(this); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CommitWorkingCopyOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CommitWorkingCopyOperation.java new file mode 100644 index 0000000..743484c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CommitWorkingCopyOperation.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.IBuffer; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelStatus; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; +import net.sourceforge.phpdt.core.JavaModelException; + +import org.eclipse.core.resources.IResource; + + +/** + * Commits the contents of a working copy compilation + * unit to its original element and resource, bringing + * the Java Model up-to-date with the current contents of the working + * copy. + * + *

      It is possible that the contents of the + * original resource have changed since the working copy was created, + * in which case there is an update conflict. This operation allows + * for two settings to resolve conflict set by the fForce flag:

        + *
      • force flag is false - in this case an JavaModelException + * is thrown
      • + *
      • force flag is true - in this case the contents of + * the working copy are applied to the underlying resource even though + * the working copy was created before a subsequent change in the + * resource
      • + *
      + * + *

      The default conflict resolution setting is the force flag is false + * + * A JavaModelOperation exception is thrown either if the commit could not + * be performed or if the new content of the compilation unit violates some Java Model + * constraint (e.g. if the new package declaration doesn't match the name of the folder + * containing the compilation unit). + */ +public class CommitWorkingCopyOperation extends JavaModelOperation { + /** + * Constructs an operation to commit the contents of a working copy + * to its original compilation unit. + */ + public CommitWorkingCopyOperation(ICompilationUnit element, boolean force) { + super(new IJavaElement[] {element}, force); + } + /** + * @exception JavaModelException if setting the source + * of the original compilation unit fails + */ + protected void executeOperation() throws JavaModelException { + try { + beginTask(Util.bind("workingCopy.commit"), 2); //$NON-NLS-1$ + WorkingCopy copy = (WorkingCopy)getCompilationUnit(); + ICompilationUnit original = (ICompilationUnit) copy.getOriginalElement(); + + + // creates the delta builder (this remembers the content of the cu) + if (!original.isOpen()) { + // force opening so that the delta builder can get the old info + original.open(null); + } + JavaElementDeltaBuilder deltaBuilder; + if (Util.isExcluded(original)) { + deltaBuilder = null; + } else { + deltaBuilder = new JavaElementDeltaBuilder(original); + } + + // save the cu + IBuffer originalBuffer = original.getBuffer(); + if (originalBuffer == null) return; + char[] originalContents = originalBuffer.getCharacters(); + boolean hasSaved = false; + try { + IBuffer copyBuffer = copy.getBuffer(); + if (copyBuffer == null) return; + originalBuffer.setContents(copyBuffer.getCharacters()); + original.save(fMonitor, fForce); + this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); + hasSaved = true; + } finally { + if (!hasSaved){ + // restore original buffer contents since something went wrong + originalBuffer.setContents(originalContents); + } + } + // make sure working copy is in sync + copy.updateTimeStamp((CompilationUnit)original); + copy.makeConsistent(this); + worked(1); + + if (deltaBuilder != null) { + // build the deltas + deltaBuilder.buildDeltas(); + + // add the deltas to the list of deltas created during this operation + if (deltaBuilder.delta != null) { + addDelta(deltaBuilder.delta); + } + } + worked(1); + } finally { + done(); + } + } + /** + * Returns the compilation unit this operation is working on. + */ + protected ICompilationUnit getCompilationUnit() { + return (ICompilationUnit)getElementToProcess(); + } + /** + * Possible failures:

        + *
      • INVALID_ELEMENT_TYPES - the compilation unit supplied to this + * operation is not a working copy + *
      • ELEMENT_NOT_PRESENT - the compilation unit the working copy is + * based on no longer exists. + *
      • UPDATE_CONFLICT - the original compilation unit has changed since + * the working copy was created and the operation specifies no force + *
      • READ_ONLY - the original compilation unit is in read-only mode + *
      + */ + public IJavaModelStatus verify() { + ICompilationUnit cu = getCompilationUnit(); + if (!cu.isWorkingCopy()) { + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, cu); + } + ICompilationUnit original= (ICompilationUnit)cu.getOriginalElement(); + IResource resource = original.getResource(); + if (!cu.isBasedOn(resource) && !fForce) { + return new JavaModelStatus(IJavaModelStatusConstants.UPDATE_CONFLICT); + } + // no read-only check, since some repository adapters can change the flag on save + // operation. + return JavaModelStatus.VERIFIED_OK; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnit.java index 5a56373..3c07bac 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnit.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnit.java @@ -10,25 +10,46 @@ *******************************************************************************/ package net.sourceforge.phpdt.internal.core; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + import net.sourceforge.phpdt.core.IBuffer; +import net.sourceforge.phpdt.core.IBufferFactory; import net.sourceforge.phpdt.core.ICompilationUnit; import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IMethod; +import net.sourceforge.phpdt.core.IPackageDeclaration; import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; +import net.sourceforge.phpdt.core.IProblemRequestor; +import net.sourceforge.phpdt.core.ISourceRange; +import net.sourceforge.phpdt.core.IType; import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.Signature; import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.IProblemFactory; +import net.sourceforge.phpdt.internal.compiler.SourceElementParser; +import net.sourceforge.phpdt.internal.compiler.problem.DefaultProblemFactory; import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; -/** +/** * @see ICompilationUnit */ -public class CompilationUnit extends Openable implements ICompilationUnit { +public class CompilationUnit extends Openable implements ICompilationUnit, net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit { public static boolean SHARED_WC_VERBOSE = false; @@ -44,9 +65,9 @@ public class CompilationUnit extends Openable implements ICompilationUnit { */ protected CompilationUnit(IPackageFragment parent, String name) { super(COMPILATION_UNIT, parent, name); -// if (!Util.isJavaFileName(name)) { -// throw new IllegalArgumentException(org.eclipse.jdt.internal.core.Util.bind("convention.unit.notJavaName")); //$NON-NLS-1$ -// } + if (!Util.isJavaFileName(name)) { + throw new IllegalArgumentException(net.sourceforge.phpdt.internal.core.Util.bind("convention.unit.notJavaName")); //$NON-NLS-1$ + } } /** * Accepts the given visitor onto the parsed tree of this compilation unit, after @@ -65,67 +86,67 @@ protected CompilationUnit(IPackageFragment parent, String name) { //public void accept(IAbstractSyntaxTreeVisitor visitor) throws JavaModelException { // CompilationUnitVisitor.visit(this, visitor); //} -// -//protected void buildStructure(OpenableElementInfo info, IProgressMonitor monitor) throws JavaModelException { -// -// if (monitor != null && monitor.isCanceled()) return; -// -// // remove existing (old) infos -// removeInfo(); -// -// HashMap newElements = new HashMap(11); -// info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource())); -// JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this); -// for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) { -// IJavaElement key = (IJavaElement) iter.next(); -// Object value = newElements.get(key); -// JavaModelManager.getJavaModelManager().putInfo(key, value); -// } -// // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs -// // to be flushed. Might lead to performance issues. -// // see PR 1G2K5S7: ITPJCORE:ALL - NPE when accessing source for a binary type -// JavaModelManager.getJavaModelManager().putInfo(this, info); -//} -// + +protected void buildStructure(OpenableElementInfo info, IProgressMonitor monitor) throws JavaModelException { + + if (monitor != null && monitor.isCanceled()) return; + + // remove existing (old) infos + removeInfo(); + + HashMap newElements = new HashMap(11); + info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource())); + JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this); + for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) { + IJavaElement key = (IJavaElement) iter.next(); + Object value = newElements.get(key); + JavaModelManager.getJavaModelManager().putInfo(key, value); + } + // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs + // to be flushed. Might lead to performance issues. + // see PR 1G2K5S7: ITPJCORE:ALL - NPE when accessing source for a binary type + JavaModelManager.getJavaModelManager().putInfo(this, info); +} + ///** // * @see ICodeAssist#codeComplete(int, ICompletionRequestor) // */ //public void codeComplete(int offset, ICompletionRequestor requestor) throws JavaModelException { // codeComplete(this, isWorkingCopy() ? (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) getOriginalElement() : this, offset, requestor); //} -///** -// * @see ICodeAssist#codeSelect(int, int) -// */ +/** + * @see ICodeAssist#codeSelect(int, int) + */ //public IJavaElement[] codeSelect(int offset, int length) throws JavaModelException { // return super.codeSelect(this, offset, length); //} -///** -// * @see IWorkingCopy#commit(boolean, IProgressMonitor) -// */ -//public void commit(boolean force, IProgressMonitor monitor) throws JavaModelException { -// throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this)); -//} +/** + * @see IWorkingCopy#commit(boolean, IProgressMonitor) + */ +public void commit(boolean force, IProgressMonitor monitor) throws JavaModelException { + throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this)); +} /** * @see ISourceManipulation#copy(IJavaElement, IJavaElement, String, boolean, IProgressMonitor) */ -//public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException { -// if (container == null) { -// throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$ -// } -// IJavaElement[] elements = new IJavaElement[] {this}; -// IJavaElement[] containers = new IJavaElement[] {container}; -// String[] renamings = null; -// if (rename != null) { -// renamings = new String[] {rename}; -// } -// getJavaModel().copy(elements, containers, null, renamings, force, monitor); -//} +public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException { + if (container == null) { + throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$ + } + IJavaElement[] elements = new IJavaElement[] {this}; + IJavaElement[] containers = new IJavaElement[] {container}; + String[] renamings = null; + if (rename != null) { + renamings = new String[] {rename}; + } + getJavaModel().copy(elements, containers, null, renamings, force, monitor); +} /** * Returns a new element info for this element. */ -//protected OpenableElementInfo createElementInfo() { -// return new CompilationUnitElementInfo(); -//} +protected OpenableElementInfo createElementInfo() { + return new CompilationUnitElementInfo(); +} ///** // * @see ICompilationUnit#createImport(String, IJavaElement, IProgressMonitor) // */ @@ -140,12 +161,12 @@ protected CompilationUnit(IPackageFragment parent, String name) { /** * @see ICompilationUnit#createPackageDeclaration(String, IProgressMonitor) */ -//public IPackageDeclaration createPackageDeclaration(String name, IProgressMonitor monitor) throws JavaModelException { -// -// CreatePackageDeclarationOperation op= new CreatePackageDeclarationOperation(name, this); -// runOperation(op, monitor); -// return getPackageDeclaration(name); -//} +public IPackageDeclaration createPackageDeclaration(String name, IProgressMonitor monitor) throws JavaModelException { + + CreatePackageDeclarationOperation op= new CreatePackageDeclarationOperation(name, this); + runOperation(op, monitor); + return getPackageDeclaration(name); +} ///** // * @see ICompilationUnit#createType(String, IJavaElement, boolean, IProgressMonitor) // */ @@ -171,10 +192,10 @@ protected CompilationUnit(IPackageFragment parent, String name) { /** * @see ISourceManipulation#delete(boolean, IProgressMonitor) */ -//public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException { -// IJavaElement[] elements= new IJavaElement[] {this}; -// getJavaModel().delete(elements, force, monitor); -//} +public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException { + IJavaElement[] elements= new IJavaElement[] {this}; + getJavaModel().delete(elements, force, monitor); +} /** * This is not a working copy, do nothing. * @@ -192,46 +213,46 @@ public void destroy() { * * @see Object#equals(java.lang.Object) */ -//public boolean equals(Object o) { -// return super.equals(o) && !((ICompilationUnit)o).isWorkingCopy(); -//} -///** -// * @see JavaElement#equalsDOMNode(IDOMNode) -// */ -//protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException { -// String name = getElementName(); -// if (node.getNodeType() == IDOMNode.COMPILATION_UNIT && name != null ) { -// String nodeName = node.getName(); -// if (nodeName == null) return false; -// if (name.equals(nodeName)) { -// return true; -// } else { -// // iterate through all the types inside the receiver and see if one of them can fit -// IType[] types = getTypes(); -// String typeNodeName = nodeName.substring(0, nodeName.indexOf(".java")); //$NON-NLS-1$ -// for (int i = 0, max = types.length; i < max; i++) { -// if (types[i].getElementName().equals(typeNodeName)) { -// return true; -// } -// } -// } -// } -// return false; -//} +public boolean equals(Object o) { + return super.equals(o) && !((ICompilationUnit)o).isWorkingCopy(); +} +/** + * @see JavaElement#equalsDOMNode(IDOMNode) + */ +protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException { + String name = getElementName(); + if (node.getNodeType() == IDOMNode.COMPILATION_UNIT && name != null ) { + String nodeName = node.getName(); + if (nodeName == null) return false; + if (name.equals(nodeName)) { + return true; + } else { + // iterate through all the types inside the receiver and see if one of them can fit + IType[] types = getTypes(); + String typeNodeName = nodeName.substring(0, nodeName.indexOf(".java")); //$NON-NLS-1$ + for (int i = 0, max = types.length; i < max; i++) { + if (types[i].getElementName().equals(typeNodeName)) { + return true; + } + } + } + } + return false; +} /** * @see IWorkingCopy#findElements(IJavaElement) */ -//public IJavaElement[] findElements(IJavaElement element) { -// ArrayList children = new ArrayList(); -// while (element != null && element.getElementType() != IJavaElement.COMPILATION_UNIT) { -// children.add(element); -// element = element.getParent(); -// } -// if (element == null) return null; -// IJavaElement currentElement = this; -// for (int i = children.size()-1; i >= 0; i--) { -// IJavaElement child = (IJavaElement)children.get(i); -// switch (child.getElementType()) { +public IJavaElement[] findElements(IJavaElement element) { + ArrayList children = new ArrayList(); + while (element != null && element.getElementType() != IJavaElement.COMPILATION_UNIT) { + children.add(element); + element = element.getParent(); + } + if (element == null) return null; + IJavaElement currentElement = this; + for (int i = children.size()-1; i >= 0; i--) { + IJavaElement child = (IJavaElement)children.get(i); + switch (child.getElementType()) { // case IJavaElement.PACKAGE_DECLARATION: // currentElement = ((ICompilationUnit)currentElement).getPackageDeclaration(child.getElementName()); // break; @@ -241,108 +262,109 @@ public void destroy() { // case IJavaElement.IMPORT_DECLARATION: // currentElement = ((IImportContainer)currentElement).getImport(child.getElementName()); // break; -// case IJavaElement.TYPE: -// if (currentElement.getElementType() == IJavaElement.COMPILATION_UNIT) { -// currentElement = ((ICompilationUnit)currentElement).getType(child.getElementName()); -// } else { -// currentElement = ((IType)currentElement).getType(child.getElementName()); -// } -// break; + case IJavaElement.TYPE: + if (currentElement.getElementType() == IJavaElement.COMPILATION_UNIT) { + currentElement = ((ICompilationUnit)currentElement).getType(child.getElementName()); + } else { + currentElement = ((IType)currentElement).getType(child.getElementName()); + } + break; // case IJavaElement.INITIALIZER: // currentElement = ((IType)currentElement).getInitializer(((JavaElement)child).getOccurrenceCount()); // break; -// case IJavaElement.FIELD: -// currentElement = ((IType)currentElement).getField(child.getElementName()); -// break; -// case IJavaElement.METHOD: -// return ((IType)currentElement).findMethods((IMethod)child); -// } -// -// } -// if (currentElement != null && currentElement.exists()) { -// return new IJavaElement[] {currentElement}; -// } else { -// return null; -// } -//} + case IJavaElement.FIELD: + currentElement = ((IType)currentElement).getField(child.getElementName()); + break; + case IJavaElement.METHOD: + return ((IType)currentElement).findMethods((IMethod)child); + } + + } + if (currentElement != null && currentElement.exists()) { + return new IJavaElement[] {currentElement}; + } else { + return null; + } +} /** * @see IWorkingCopy#findPrimaryType() */ -//public IType findPrimaryType() { -// String typeName = Signature.getQualifier(this.getElementName()); -// IType primaryType= this.getType(typeName); -// if (primaryType.exists()) { -// return primaryType; -// } -// return null; -//} +public IType findPrimaryType() { + String typeName = Signature.getQualifier(this.getElementName()); + IType primaryType= this.getType(typeName); + if (primaryType.exists()) { + return primaryType; + } + return null; +} /** * @see IWorkingCopy#findSharedWorkingCopy(IBufferFactory) */ -//public IJavaElement findSharedWorkingCopy(IBufferFactory factory) { -// -// // if factory is null, default factory must be used -// if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory(); -// -// // In order to be shared, working copies have to denote the same compilation unit -// // AND use the same buffer factory. -// // Assuming there is a little set of buffer factories, then use a 2 level Map cache. -// Map sharedWorkingCopies = JavaModelManager.getJavaModelManager().sharedWorkingCopies; -// -// Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory); -// if (perFactoryWorkingCopies == null) return null; -// return (WorkingCopy)perFactoryWorkingCopies.get(this); -//} +public IJavaElement findSharedWorkingCopy(IBufferFactory factory) { + + // if factory is null, default factory must be used + if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory(); + + // In order to be shared, working copies have to denote the same compilation unit + // AND use the same buffer factory. + // Assuming there is a little set of buffer factories, then use a 2 level Map cache. + Map sharedWorkingCopies = JavaModelManager.getJavaModelManager().sharedWorkingCopies; + + Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory); + if (perFactoryWorkingCopies == null) return null; + return (WorkingCopy)perFactoryWorkingCopies.get(this); +} + +protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException { -//protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException { -// // if (getParent() instanceof JarPackageFragment) { // // ignore .java files in jar // throw newNotPresentException(); // } else { -// // put the info now, because getting the contents requires it -// JavaModelManager.getJavaModelManager().putInfo(this, info); -// CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info; -// -// // generate structure -// CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(this, unitInfo, newElements); -// IProblemFactory factory = new DefaultProblemFactory(); + // put the info now, because getting the contents requires it + JavaModelManager.getJavaModelManager().putInfo(this, info); + CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info; + + // generate structure + CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(this, unitInfo, newElements); + IProblemFactory factory = new DefaultProblemFactory(); // SourceElementParser parser = new SourceElementParser(requestor, factory, new CompilerOptions(getJavaProject().getOptions(true))); -// requestor.parser = parser; -// parser.parseCompilationUnit(this, false); -// if (isWorkingCopy()) { -// CompilationUnit original = (CompilationUnit) getOriginalElement(); -// // might be IResource.NULL_STAMP if original does not exist -// unitInfo.fTimestamp = ((IFile) original.getResource()).getModificationStamp(); -// } -// return unitInfo.isStructureKnown(); + SourceElementParser parser = new SourceElementParser(requestor, factory); + requestor.parser = parser; + parser.parseCompilationUnit(this, false); + if (isWorkingCopy()) { + CompilationUnit original = (CompilationUnit) getOriginalElement(); + // might be IResource.NULL_STAMP if original does not exist + unitInfo.fTimestamp = ((IFile) original.getResource()).getModificationStamp(); + } + return unitInfo.isStructureKnown(); // } -//} +} /** * @see ICompilationUnit#getAllTypes() */ -//public IType[] getAllTypes() throws JavaModelException { -// IJavaElement[] types = getTypes(); -// int i; -// ArrayList allTypes = new ArrayList(types.length); -// ArrayList typesToTraverse = new ArrayList(types.length); -// for (i = 0; i < types.length; i++) { -// typesToTraverse.add(types[i]); -// } -// while (!typesToTraverse.isEmpty()) { -// IType type = (IType) typesToTraverse.get(0); -// typesToTraverse.remove(type); -// allTypes.add(type); -// types = type.getTypes(); -// for (i = 0; i < types.length; i++) { -// typesToTraverse.add(types[i]); -// } -// } -// IType[] arrayOfAllTypes = new IType[allTypes.size()]; -// allTypes.toArray(arrayOfAllTypes); -// return arrayOfAllTypes; -//} +public IType[] getAllTypes() throws JavaModelException { + IJavaElement[] types = getTypes(); + int i; + ArrayList allTypes = new ArrayList(types.length); + ArrayList typesToTraverse = new ArrayList(types.length); + for (i = 0; i < types.length; i++) { + typesToTraverse.add(types[i]); + } + while (!typesToTraverse.isEmpty()) { + IType type = (IType) typesToTraverse.get(0); + typesToTraverse.remove(type); + allTypes.add(type); + types = type.getTypes(); + for (i = 0; i < types.length; i++) { + typesToTraverse.add(types[i]); + } + } + IType[] arrayOfAllTypes = new IType[allTypes.size()]; + allTypes.toArray(arrayOfAllTypes); + return arrayOfAllTypes; +} /** * @see IMember#getCompilationUnit() */ @@ -366,26 +388,26 @@ public char[] getContents() { * * @see IJavaElement#getCorrespondingResource() */ -//public IResource getCorrespondingResource() throws JavaModelException { -// IPackageFragmentRoot root= (IPackageFragmentRoot)getParent().getParent(); -// if (root.isArchive()) { -// return null; -// } else { -// return getUnderlyingResource(); -// } -//} -///** -// * @see ICompilationUnit#getElementAt(int) -// */ -//public IJavaElement getElementAt(int position) throws JavaModelException { -// -// IJavaElement e= getSourceElementAt(position); -// if (e == this) { -// return null; -// } else { -// return e; -// } -//} +public IResource getCorrespondingResource() throws JavaModelException { + IPackageFragmentRoot root= (IPackageFragmentRoot)getParent().getParent(); + if (root.isArchive()) { + return null; + } else { + return getUnderlyingResource(); + } +} +/** + * @see ICompilationUnit#getElementAt(int) + */ +public IJavaElement getElementAt(int position) throws JavaModelException { + + IJavaElement e= getSourceElementAt(position); + if (e == this) { + return null; + } else { + return e; + } +} public char[] getFileName(){ return getElementName().toCharArray(); } @@ -454,18 +476,18 @@ public IJavaElement getOriginalElement() { /** * @see ICompilationUnit#getPackageDeclaration(String) */ -//public IPackageDeclaration getPackageDeclaration(String name) { -// return new PackageDeclaration(this, name); -//} -///** -// * @see ICompilationUnit#getPackageDeclarations() -// */ -//public IPackageDeclaration[] getPackageDeclarations() throws JavaModelException { -// ArrayList list = getChildrenOfType(PACKAGE_DECLARATION); -// IPackageDeclaration[] array= new IPackageDeclaration[list.size()]; -// list.toArray(array); -// return array; -//} +public IPackageDeclaration getPackageDeclaration(String name) { + return new PackageDeclaration(this, name); +} +/** + * @see ICompilationUnit#getPackageDeclarations() + */ +public IPackageDeclaration[] getPackageDeclarations() throws JavaModelException { + ArrayList list = getChildrenOfType(PACKAGE_DECLARATION); + IPackageDeclaration[] array= new IPackageDeclaration[list.size()]; + list.toArray(array); + return array; +} /** * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getPackageName() */ @@ -475,14 +497,14 @@ public char[][] getPackageName() { /** * @see IJavaElement#getPath() */ -//public IPath getPath() { -// PackageFragmentRoot root = this.getPackageFragmentRoot(); -// if (root.isArchive()) { -// return root.getPath(); -// } else { -// return this.getParent().getPath().append(this.getElementName()); -// } -//} +public IPath getPath() { + PackageFragmentRoot root = this.getPackageFragmentRoot(); + if (root.isArchive()) { + return root.getPath(); + } else { + return this.getParent().getPath().append(this.getElementName()); + } +} /** * @see IJavaElement#getResource() */ @@ -506,81 +528,81 @@ public String getSource() throws JavaModelException { /** * @see ISourceReference#getSourceRange() */ -//public ISourceRange getSourceRange() throws JavaModelException { -// return ((CompilationUnitElementInfo) getElementInfo()).getSourceRange(); -//} -///** -// * @see ICompilationUnit#getType(String) -// */ -//public IType getType(String name) { -// return new SourceType(this, name); -//} -///** -// * @see ICompilationUnit#getTypes() -// */ -//public IType[] getTypes() throws JavaModelException { -// ArrayList list = getChildrenOfType(TYPE); -// IType[] array= new IType[list.size()]; -// list.toArray(array); -// return array; -//} -//public IResource getUnderlyingResource() throws JavaModelException { -// if (FIX_BUG25184) { -// return super.getUnderlyingResource(); -// } else { -// return getResource(); -// } -//} -///** -// * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor) -// */ -//public IJavaElement getSharedWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException { -// -// // if factory is null, default factory must be used -// if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory(); -// -// JavaModelManager manager = JavaModelManager.getJavaModelManager(); -// -// // In order to be shared, working copies have to denote the same compilation unit -// // AND use the same buffer factory. -// // Assuming there is a little set of buffer factories, then use a 2 level Map cache. -// Map sharedWorkingCopies = manager.sharedWorkingCopies; -// -// Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory); -// if (perFactoryWorkingCopies == null){ -// perFactoryWorkingCopies = new HashMap(); -// sharedWorkingCopies.put(factory, perFactoryWorkingCopies); -// } -// WorkingCopy workingCopy = (WorkingCopy)perFactoryWorkingCopies.get(this); -// if (workingCopy != null) { -// workingCopy.useCount++; -// -// if (SHARED_WC_VERBOSE) { -// System.out.println("Incrementing use count of shared working copy " + workingCopy.toStringWithAncestors()); //$NON-NLS-1$ -// } -// -// return workingCopy; -// } else { -// CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, perFactoryWorkingCopies, factory, problemRequestor); -// runOperation(op, pm); -// return op.getResultElements()[0]; -// } -//} +public ISourceRange getSourceRange() throws JavaModelException { + return ((CompilationUnitElementInfo) getElementInfo()).getSourceRange(); +} +/** + * @see ICompilationUnit#getType(String) + */ +public IType getType(String name) { + return new SourceType(this, name); +} +/** + * @see ICompilationUnit#getTypes() + */ +public IType[] getTypes() throws JavaModelException { + ArrayList list = getChildrenOfType(TYPE); + IType[] array= new IType[list.size()]; + list.toArray(array); + return array; +} +public IResource getUnderlyingResource() throws JavaModelException { + if (FIX_BUG25184) { + return super.getUnderlyingResource(); + } else { + return getResource(); + } +} +/** + * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor) + */ +public IJavaElement getSharedWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException { + + // if factory is null, default factory must be used + if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory(); + + JavaModelManager manager = JavaModelManager.getJavaModelManager(); + + // In order to be shared, working copies have to denote the same compilation unit + // AND use the same buffer factory. + // Assuming there is a little set of buffer factories, then use a 2 level Map cache. + Map sharedWorkingCopies = manager.sharedWorkingCopies; + + Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory); + if (perFactoryWorkingCopies == null){ + perFactoryWorkingCopies = new HashMap(); + sharedWorkingCopies.put(factory, perFactoryWorkingCopies); + } + WorkingCopy workingCopy = (WorkingCopy)perFactoryWorkingCopies.get(this); + if (workingCopy != null) { + workingCopy.useCount++; + + if (SHARED_WC_VERBOSE) { + System.out.println("Incrementing use count of shared working copy " + workingCopy.toStringWithAncestors()); //$NON-NLS-1$ + } + + return workingCopy; + } else { + CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, perFactoryWorkingCopies, factory, problemRequestor); + runOperation(op, pm); + return op.getResultElements()[0]; + } +} /** * @see IWorkingCopy#getWorkingCopy() */ -//public IJavaElement getWorkingCopy() throws JavaModelException { -// return this.getWorkingCopy(null, null, null); -//} +public IJavaElement getWorkingCopy() throws JavaModelException { + return this.getWorkingCopy(null, null, null); +} /** * @see IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor) */ -//public IJavaElement getWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException { -// CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, null, factory, problemRequestor); -// runOperation(op, pm); -// return op.getResultElements()[0]; -//} +public IJavaElement getWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException { + CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, null, factory, problemRequestor); + runOperation(op, pm); + return op.getResultElements()[0]; +} /** * @see Openable#hasBuffer() @@ -612,9 +634,9 @@ public boolean isBasedOn(IResource resource) { /** * @see IOpenable#isConsistent() */ -//public boolean isConsistent() throws JavaModelException { -// return JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().get(this) == null; -//} +public boolean isConsistent() throws JavaModelException { + return JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().get(this) == null; +} /** * @see Openable#isSourceElement() */ @@ -630,77 +652,77 @@ public boolean isWorkingCopy() { /** * @see IOpenable#makeConsistent(IProgressMonitor) */ -//public void makeConsistent(IProgressMonitor monitor) throws JavaModelException { -// if (!isConsistent()) { // TODO: this code isn't synchronized with regular opening of a working copy -// // create a new info and make it the current info -// OpenableElementInfo info = createElementInfo(); -// buildStructure(info, monitor); -// } -//} +public void makeConsistent(IProgressMonitor monitor) throws JavaModelException { + if (!isConsistent()) { // TODO: this code isn't synchronized with regular opening of a working copy + // create a new info and make it the current info + OpenableElementInfo info = createElementInfo(); + buildStructure(info, monitor); + } +} /** * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor) */ -//public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException { -// if (container == null) { -// throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$ -// } -// IJavaElement[] elements= new IJavaElement[] {this}; -// IJavaElement[] containers= new IJavaElement[] {container}; -// -// String[] renamings= null; -// if (rename != null) { -// renamings= new String[] {rename}; -// } -// getJavaModel().move(elements, containers, null, renamings, force, monitor); -//} +public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException { + if (container == null) { + throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$ + } + IJavaElement[] elements= new IJavaElement[] {this}; + IJavaElement[] containers= new IJavaElement[] {container}; + + String[] renamings= null; + if (rename != null) { + renamings= new String[] {rename}; + } + getJavaModel().move(elements, containers, null, renamings, force, monitor); +} /** * @see Openable#openBuffer(IProgressMonitor) */ -//protected IBuffer openBuffer(IProgressMonitor pm) throws JavaModelException { -// -// // create buffer - compilation units only use default buffer factory -// BufferManager bufManager = getBufferManager(); -// IBuffer buffer = getBufferFactory().createBuffer(this); -// if (buffer == null) return null; -// -// // set the buffer source -// if (buffer.getCharacters() == null){ -// IFile file = (IFile)this.getResource(); -// if (file == null || !file.exists()) throw newNotPresentException(); -// buffer.setContents(Util.getResourceContentsAsCharArray(file)); -// } -// -// // add buffer to buffer cache -// bufManager.addBuffer(buffer); -// -// // listen to buffer changes -// buffer.addBufferChangedListener(this); -// -// return buffer; -//} -//protected void openParent(IProgressMonitor pm) throws JavaModelException { -// if (FIX_BUG25184) { -// super.openParent(pm); -// } else { -// try { -// super.openParent(pm); -// } catch(JavaModelException e){ -// // allow parent to not exist for compilation units defined outside classpath -// if (!e.isDoesNotExist()){ -// throw e; -// } -// } -// } -//} -//protected boolean parentExists() { -// if (FIX_BUG25184) { -// return super.parentExists(); -// } else { -// return true; // tolerate units outside classpath -// } -//} +protected IBuffer openBuffer(IProgressMonitor pm) throws JavaModelException { + + // create buffer - compilation units only use default buffer factory + BufferManager bufManager = getBufferManager(); + IBuffer buffer = getBufferFactory().createBuffer(this); + if (buffer == null) return null; + + // set the buffer source + if (buffer.getCharacters() == null){ + IFile file = (IFile)this.getResource(); + if (file == null || !file.exists()) throw newNotPresentException(); + buffer.setContents(Util.getResourceContentsAsCharArray(file)); + } + + // add buffer to buffer cache + bufManager.addBuffer(buffer); + + // listen to buffer changes + buffer.addBufferChangedListener(this); + + return buffer; +} +protected void openParent(IProgressMonitor pm) throws JavaModelException { + if (FIX_BUG25184) { + super.openParent(pm); + } else { + try { + super.openParent(pm); + } catch(JavaModelException e){ + // allow parent to not exist for compilation units defined outside classpath + if (!e.isDoesNotExist()){ + throw e; + } + } + } +} +protected boolean parentExists() { + if (FIX_BUG25184) { + return super.parentExists(); + } else { + return true; // tolerate units outside classpath + } +} /** * @see IWorkingCopy#reconcile() @@ -723,15 +745,15 @@ public void reconcile( /** * @see ISourceManipulation#rename(String, boolean, IProgressMonitor) */ -//public void rename(String name, boolean force, IProgressMonitor monitor) throws JavaModelException { -// if (name == null) { -// throw new IllegalArgumentException(Util.bind("operation.nullName")); //$NON-NLS-1$ -// } -// IJavaElement[] elements= new IJavaElement[] {this}; -// IJavaElement[] dests= new IJavaElement[] {this.getParent()}; -// String[] renamings= new String[] {name}; -// getJavaModel().rename(elements, dests, renamings, force, monitor); -//} +public void rename(String name, boolean force, IProgressMonitor monitor) throws JavaModelException { + if (name == null) { + throw new IllegalArgumentException(Util.bind("operation.nullName")); //$NON-NLS-1$ + } + IJavaElement[] elements= new IJavaElement[] {this}; + IJavaElement[] dests= new IJavaElement[] {this.getParent()}; + String[] renamings= new String[] {name}; + getJavaModel().rename(elements, dests, renamings, force, monitor); +} /** * Does nothing - this is not a working copy. * diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnitElementInfo.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnitElementInfo.java new file mode 100644 index 0000000..4ae1585 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnitElementInfo.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.ISourceRange; + + +/* package */ class CompilationUnitElementInfo extends OpenableElementInfo { + + /** + * The length of this compilation unit's source code String + */ + protected int fSourceLength; + + /** + * Timestamp of original resource at the time this element + * was opened or last updated. + */ + protected long fTimestamp; +/** + * Returns the length of the source string. + */ +public int getSourceLength() { + return fSourceLength; +} +protected ISourceRange getSourceRange() { + return new SourceRange(0, fSourceLength); +} +/** + * Sets the length of the source string. + */ +public void setSourceLength(int newSourceLength) { + fSourceLength = newSourceLength; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnitProblemFinder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnitProblemFinder.java new file mode 100644 index 0000000..6cfb4c4 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnitProblemFinder.java @@ -0,0 +1,233 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.util.Locale; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IProblemRequestor; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.Compiler; +import net.sourceforge.phpdt.internal.compiler.DefaultErrorHandlingPolicies; +import net.sourceforge.phpdt.internal.compiler.ICompilerRequestor; +import net.sourceforge.phpdt.internal.compiler.IErrorHandlingPolicy; +import net.sourceforge.phpdt.internal.compiler.IProblemFactory; +import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment; +import net.sourceforge.phpdt.internal.compiler.env.ISourceType; +import net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding; +import net.sourceforge.phpdt.internal.compiler.parser.SourceTypeConverter; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; +import net.sourceforge.phpdt.internal.compiler.problem.DefaultProblemFactory; +import net.sourceforge.phpeclipse.PHPCore; +import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; + +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * Responsible for resolving types inside a compilation unit being reconciled, + * reporting the discovered problems to a given IProblemRequestor. + */ +public class CompilationUnitProblemFinder extends Compiler { + + /** + * Answer a new CompilationUnitVisitor using the given name environment and compiler options. + * The environment and options will be in effect for the lifetime of the compiler. + * When the compiler is run, compilation results are sent to the given requestor. + * + * @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment + * Environment used by the compiler in order to resolve type and package + * names. The name environment implements the actual connection of the compiler + * to the outside world (e.g. in batch mode the name environment is performing + * pure file accesses, reuse previous build state or connection to repositories). + * Note: the name environment is responsible for implementing the actual classpath + * rules. + * + * @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy + * Configurable part for problem handling, allowing the compiler client to + * specify the rules for handling problems (stop on first error or accumulate + * them all) and at the same time perform some actions such as opening a dialog + * in UI when compiling interactively. + * @see org.eclipse.jdt.internal.compiler.api.problem.DefaultErrorHandlingPolicies + * + * @param settings The settings to use for the resolution. + * + * @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor + * Component which will receive and persist all compilation results and is intended + * to consume them as they are produced. Typically, in a batch compiler, it is + * responsible for writing out the actual .class files to the file system. + * @see org.eclipse.jdt.internal.compiler.api.CompilationResult + * + * @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory + * Factory used inside the compiler to create problem descriptors. It allows the + * compiler client to supply its own representation of compilation problems in + * order to avoid object conversions. Note that the factory is not supposed + * to accumulate the created problems, the compiler will gather them all and hand + * them back as part of the compilation unit result. + */ + protected CompilationUnitProblemFinder( + INameEnvironment environment, + IErrorHandlingPolicy policy, +// Map settings, + ICompilerRequestor requestor, + IProblemFactory problemFactory) { + + super(environment, policy, requestor, problemFactory, true);//settings, requestor, problemFactory, true); + } + + /** + * Add additional source types + */ + public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding) { + // ensure to jump back to toplevel type for first one (could be a member) +// while (sourceTypes[0].getEnclosingType() != null) +// sourceTypes[0] = sourceTypes[0].getEnclosingType(); + + CompilationResult result = + new CompilationResult(sourceTypes[0].getFileName(), 1, 1, 10); //this.options.maxProblemsPerUnit); + + // need to hold onto this + CompilationUnitDeclaration unit = + SourceTypeConverter.buildCompilationUnit( + sourceTypes,//sourceTypes[0] is always toplevel here + true, // need field and methods + true, // need member types + true, // need field initialization + lookupEnvironment.problemReporter, + result); + + if (unit != null) { + this.lookupEnvironment.buildTypeBindings(unit); + this.lookupEnvironment.completeTypeBindings(unit, true); + } + } + + /* + * Low-level API performing the actual compilation + */ + protected static IErrorHandlingPolicy getHandlingPolicy() { + return DefaultErrorHandlingPolicies.proceedWithAllProblems(); + } + + protected static INameEnvironment getNameEnvironment(ICompilationUnit sourceUnit) + throws JavaModelException { + return (SearchableEnvironment) ((JavaProject) sourceUnit.getJavaProject()) + .getSearchableNameEnvironment(); + } + + /* + * Answer the component to which will be handed back compilation results from the compiler + */ + protected static ICompilerRequestor getRequestor() { + return new ICompilerRequestor() { + public void acceptResult(CompilationResult compilationResult) { + } + }; + } + + protected static IProblemFactory getProblemFactory( + final char[] fileName, + final IProblemRequestor problemRequestor, + final IProgressMonitor monitor) { + + return new DefaultProblemFactory(Locale.getDefault()) { + public IProblem createProblem( + char[] originatingFileName, + int problemId, + String[] problemArguments, + String[] messageArguments, + int severity, + int startPosition, + int endPosition, + int lineNumber) { + + if (monitor != null && monitor.isCanceled()){ + throw new AbortCompilation(true, null); // silent abort + } + + IProblem problem = + super.createProblem( + originatingFileName, + problemId, + problemArguments, + messageArguments, + severity, + startPosition, + endPosition, + lineNumber); + // only report local problems + if (CharOperation.equals(originatingFileName, fileName)){ + if (JavaModelManager.VERBOSE){ + System.out.println("PROBLEM FOUND while reconciling : "+problem.getMessage());//$NON-NLS-1$ + } + problemRequestor.acceptProblem(problem); + } + if (monitor != null && monitor.isCanceled()){ + throw new AbortCompilation(true, null); // silent abort + } + + return problem; + } + }; + } + + public static CompilationUnitDeclaration process( + ICompilationUnit unitElement, + IProblemRequestor problemRequestor, + IProgressMonitor monitor) + throws JavaModelException { + + char[] fileName = unitElement.getElementName().toCharArray(); + + IJavaProject project = unitElement.getJavaProject(); + CompilationUnitProblemFinder problemFinder = + new CompilationUnitProblemFinder( + getNameEnvironment(unitElement), + getHandlingPolicy(), + getRequestor(), + getProblemFactory(fileName, problemRequestor, monitor)); +// project.getOptions(true), +// getRequestor(), +// getProblemFactory(fileName, problemRequestor, monitor)); + + CompilationUnitDeclaration unit = null; + try { + String encoding = project.getOption(PHPCore.CORE_ENCODING, true); + + IPackageFragment packageFragment = (IPackageFragment)unitElement.getAncestor(IJavaElement.PACKAGE_FRAGMENT); + char[][] expectedPackageName = null; + if (packageFragment != null){ + expectedPackageName = CharOperation.splitOn('.', packageFragment.getElementName().toCharArray()); + } + unit = problemFinder.resolve( + new BasicCompilationUnit( + unitElement.getSource().toCharArray(), + expectedPackageName, + new String(fileName), + encoding), + true, // verify methods + true); // analyze code +// true); // generate code + return unit; + } finally { + if (unit != null) { + unit.cleanUp(); + } + problemFinder.lookupEnvironment.reset(); + } + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnitStructureRequestor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnitStructureRequestor.java new file mode 100644 index 0000000..ce3680d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnitStructureRequestor.java @@ -0,0 +1,587 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.util.Map; +import java.util.Stack; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IField; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IMethod; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.Signature; +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.ISourceElementRequestor; +import net.sourceforge.phpdt.internal.compiler.parser.Parser; +import net.sourceforge.phpdt.internal.compiler.util.HashtableOfObject; +import net.sourceforge.phpdt.internal.core.util.ReferenceInfoAdapter; +import net.sourceforge.phpdt.internal.corext.Assert; + +/** + * A requestor for the fuzzy parser, used to compute the children of an ICompilationUnit. + */ +public class CompilationUnitStructureRequestor extends ReferenceInfoAdapter implements ISourceElementRequestor { + + /** + * The handle to the compilation unit being parsed + */ + protected ICompilationUnit fUnit; + + /** + * The info object for the compilation unit being parsed + */ + protected CompilationUnitElementInfo fUnitInfo; + + /** + * The import container info - null until created + */ + protected JavaElementInfo fImportContainerInfo = null; + + /** + * Hashtable of children elements of the compilation unit. + * Children are added to the table as they are found by + * the parser. Keys are handles, values are corresponding + * info objects. + */ + protected Map fNewElements; + + /** + * Stack of parent scope info objects. The info on the + * top of the stack is the parent of the next element found. + * For example, when we locate a method, the parent info object + * will be the type the method is contained in. + */ + protected Stack fInfoStack; + + /** + * Stack of parent handles, corresponding to the info stack. We + * keep both, since info objects do not have back pointers to + * handles. + */ + protected Stack fHandleStack; + + /** + * The name of the source file being parsed. + */ + protected char[] fSourceFileName = null; + + /** + * The dot-separated name of the package the compilation unit + * is contained in - based on the package statement in the + * compilation unit, and initialized by #acceptPackage. + * Initialized to null for the default package. + */ + protected char[] fPackageName = null; + + /** + * The number of references reported thus far. Used to + * expand the arrays of reference kinds and names. + */ + protected int fRefCount = 0; + + /** + * The initial size of the reference kind and name + * arrays. If the arrays fill, they are doubled in + * size + */ + protected static int fgReferenceAllocation = 50; + + /** + * Problem requestor which will get notified of discovered problems + */ + protected boolean hasSyntaxErrors = false; + + /* + * The parser this requestor is using. + */ + // protected Parser parser; + protected Parser parser; + + /** + * Empty collections used for efficient initialization + */ + protected static String[] fgEmptyStringArray = new String[0]; + protected static byte[] fgEmptyByte = new byte[] { + }; + protected static char[][] fgEmptyCharChar = new char[][] { + }; + protected static char[] fgEmptyChar = new char[] { + }; + + protected HashtableOfObject fieldRefCache; + protected HashtableOfObject messageRefCache; + protected HashtableOfObject typeRefCache; + protected HashtableOfObject unknownRefCache; + + protected CompilationUnitStructureRequestor(ICompilationUnit unit, CompilationUnitElementInfo unitInfo, Map newElements) + throws JavaModelException { + this.fUnit = unit; + this.fUnitInfo = unitInfo; + this.fNewElements = newElements; + this.fSourceFileName = unit.getElementName().toCharArray(); + } + /** + * @see ISourceElementRequestor + */ + //public void acceptImport(int declarationStart, int declarationEnd, char[] name, boolean onDemand) { + // JavaElementInfo parentInfo = (JavaElementInfo) fInfoStack.peek(); + // JavaElement parentHandle= (JavaElement)fHandleStack.peek(); + // if (!(parentHandle.getElementType() == IJavaElement.COMPILATION_UNIT)) { + // Assert.isTrue(false); // Should not happen + // } + // + // ICompilationUnit parentCU= (ICompilationUnit)parentHandle; + // //create the import container and its info + // IImportContainer importContainer= parentCU.getImportContainer(); + // if (fImportContainerInfo == null) { + // fImportContainerInfo= new JavaElementInfo(); + // fImportContainerInfo.setIsStructureKnown(true); + // parentInfo.addChild(importContainer); + // fNewElements.put(importContainer, fImportContainerInfo); + // } + // + // // tack on the '.*' if it is onDemand + // String importName; + // if (onDemand) { + // importName= new String(name) + ".*"; //$NON-NLS-1$ + // } else { + // importName= new String(name); + // } + // + // ImportDeclaration handle = new ImportDeclaration(importContainer, importName); + // resolveDuplicates(handle); + // + // SourceRefElementInfo info = new SourceRefElementInfo(); + // info.setSourceRangeStart(declarationStart); + // info.setSourceRangeEnd(declarationEnd); + // + // fImportContainerInfo.addChild(handle); + // fNewElements.put(handle, info); + //} + /* + * Table of line separator position. This table is passed once at the end + * of the parse action, so as to allow computation of normalized ranges. + * + * A line separator might corresponds to several characters in the source, + * + */ + public void acceptLineSeparatorPositions(int[] positions) { + } + /** + * @see ISourceElementRequestor + */ + //public void acceptPackage(int declarationStart, int declarationEnd, char[] name) { + // + // JavaElementInfo parentInfo = (JavaElementInfo) fInfoStack.peek(); + // JavaElement parentHandle= (JavaElement)fHandleStack.peek(); + // IPackageDeclaration handle = null; + // fPackageName= name; + // + // if (parentHandle.getElementType() == IJavaElement.COMPILATION_UNIT) { + // handle = new PackageDeclaration((ICompilationUnit) parentHandle, new String(name)); + // } + // else { + // Assert.isTrue(false); // Should not happen + // } + // resolveDuplicates(handle); + // + // SourceRefElementInfo info = new SourceRefElementInfo(); + // info.setSourceRangeStart(declarationStart); + // info.setSourceRangeEnd(declarationEnd); + // + // parentInfo.addChild(handle); + // fNewElements.put(handle, info); + // + //} + public void acceptProblem(IProblem problem) { + if ((problem.getID() & IProblem.Syntax) != 0) { + this.hasSyntaxErrors = true; + } + } + /** + * Convert these type names to signatures. + * @see Signature. + */ + /* default */ + static String[] convertTypeNamesToSigs(char[][] typeNames) { + if (typeNames == null) + return fgEmptyStringArray; + int n = typeNames.length; + if (n == 0) + return fgEmptyStringArray; + String[] typeSigs = new String[n]; + for (int i = 0; i < n; ++i) { + typeSigs[i] = Signature.createTypeSignature(typeNames[i], false); + } + return typeSigs; + } + /** + * @see ISourceElementRequestor + */ + public void enterClass( + int declarationStart, + int modifiers, + char[] name, + int nameSourceStart, + int nameSourceEnd, + char[] superclass, + char[][] superinterfaces) { + + enterType(declarationStart, modifiers, name, nameSourceStart, nameSourceEnd, superclass, superinterfaces); + + } + /** + * @see ISourceElementRequestor + */ + public void enterCompilationUnit() { + fInfoStack = new Stack(); + fHandleStack = new Stack(); + fInfoStack.push(fUnitInfo); + fHandleStack.push(fUnit); + } + /** + * @see ISourceElementRequestor + */ + public void enterConstructor( + int declarationStart, + int modifiers, + char[] name, + int nameSourceStart, + int nameSourceEnd, + char[][] parameterTypes, + char[][] parameterNames, + char[][] exceptionTypes) { + + enterMethod( + declarationStart, + modifiers, + null, + name, + nameSourceStart, + nameSourceEnd, + parameterTypes, + parameterNames, + exceptionTypes, + true); + } + /** + * @see ISourceElementRequestor + */ + public void enterField(int declarationStart, int modifiers, char[] type, char[] name, int nameSourceStart, int nameSourceEnd) { + + SourceTypeElementInfo parentInfo = (SourceTypeElementInfo) fInfoStack.peek(); + JavaElement parentHandle = (JavaElement) fHandleStack.peek(); + IField handle = null; + + if (parentHandle.getElementType() == IJavaElement.TYPE) { + handle = new SourceField((IType) parentHandle, new String(name)); + } else { + Assert.isTrue(false); // Should not happen + } + resolveDuplicates(handle); + + SourceFieldElementInfo info = new SourceFieldElementInfo(); + info.setName(name); + info.setNameSourceStart(nameSourceStart); + info.setNameSourceEnd(nameSourceEnd); + info.setSourceRangeStart(declarationStart); + info.setFlags(modifiers); + info.setTypeName(type); + + parentInfo.addChild(handle); + fNewElements.put(handle, info); + + fInfoStack.push(info); + fHandleStack.push(handle); + } + /** + * @see ISourceElementRequestor + */ + //public void enterInitializer( + // int declarationSourceStart, + // int modifiers) { + // JavaElementInfo parentInfo = (JavaElementInfo) fInfoStack.peek(); + // JavaElement parentHandle= (JavaElement)fHandleStack.peek(); + // IInitializer handle = null; + // + // if (parentHandle.getElementType() == IJavaElement.TYPE) { + // handle = ((IType) parentHandle).getInitializer(1); + // } + // else { + // Assert.isTrue(false); // Should not happen + // } + // resolveDuplicates(handle); + // + // InitializerElementInfo info = new InitializerElementInfo(); + // info.setSourceRangeStart(declarationSourceStart); + // info.setFlags(modifiers); + // + // parentInfo.addChild(handle); + // fNewElements.put(handle, info); + // + // fInfoStack.push(info); + // fHandleStack.push(handle); + //} + /** + * @see ISourceElementRequestor + */ + public void enterInterface( + int declarationStart, + int modifiers, + char[] name, + int nameSourceStart, + int nameSourceEnd, + char[][] superinterfaces) { + + enterType(declarationStart, modifiers, name, nameSourceStart, nameSourceEnd, null, superinterfaces); + + } + /** + * @see ISourceElementRequestor + */ + public void enterMethod( + int declarationStart, + int modifiers, + char[] returnType, + char[] name, + int nameSourceStart, + int nameSourceEnd, + char[][] parameterTypes, + char[][] parameterNames, + char[][] exceptionTypes) { + + enterMethod( + declarationStart, + modifiers, + returnType, + name, + nameSourceStart, + nameSourceEnd, + parameterTypes, + parameterNames, + exceptionTypes, + false); + } + /** + * @see ISourceElementRequestor + */ + protected void enterMethod( + int declarationStart, + int modifiers, + char[] returnType, + char[] name, + int nameSourceStart, + int nameSourceEnd, + char[][] parameterTypes, + char[][] parameterNames, + char[][] exceptionTypes, + boolean isConstructor) { + SourceTypeElementInfo parentInfo = null; + try { + parentInfo = (SourceTypeElementInfo) fInfoStack.peek(); + } catch (ClassCastException e) { + // parentInfo = null; + } + JavaElement parentHandle = (JavaElement) fHandleStack.peek(); + IMethod handle = null; + + // translate nulls to empty arrays + if (parameterTypes == null) { + parameterTypes = fgEmptyCharChar; + } + if (parameterNames == null) { + parameterNames = fgEmptyCharChar; + } + if (exceptionTypes == null) { + exceptionTypes = fgEmptyCharChar; + } + + String[] parameterTypeSigs = convertTypeNamesToSigs(parameterTypes); + if (parentHandle.getElementType() == IJavaElement.TYPE) { + handle = new SourceMethod((IType) parentHandle, new String(name), parameterTypeSigs); + } else if (parentHandle.getElementType() == IJavaElement.COMPILATION_UNIT) { + handle = new SourceMethod((ICompilationUnit) parentHandle, name==null?"":new String(name), parameterTypeSigs); + } else { + Assert.isTrue(false); // Should not happen + } + resolveDuplicates(handle); + + SourceMethodElementInfo info = new SourceMethodElementInfo(); + info.setSourceRangeStart(declarationStart); + int flags = modifiers; + info.setName(name); + info.setNameSourceStart(nameSourceStart); + info.setNameSourceEnd(nameSourceEnd); + info.setConstructor(isConstructor); + info.setFlags(flags); + info.setArgumentNames(parameterNames); + info.setArgumentTypeNames(parameterTypes); + info.setReturnType(returnType == null ? new char[] { 'v', 'o', 'i', 'd' } + : returnType); + info.setExceptionTypeNames(exceptionTypes); + + if (parentInfo == null) { + fUnitInfo.addChild(handle); + } else { + parentInfo.addChild(handle); + } + fNewElements.put(handle, info); + fInfoStack.push(info); + fHandleStack.push(handle); + } + /** + * Common processing for classes and interfaces. + */ + protected void enterType( + int declarationStart, + int modifiers, + char[] name, + int nameSourceStart, + int nameSourceEnd, + char[] superclass, + char[][] superinterfaces) { + + char[] enclosingTypeName = null; + char[] qualifiedName = null; + + JavaElementInfo parentInfo = (JavaElementInfo) fInfoStack.peek(); + JavaElement parentHandle = (JavaElement) fHandleStack.peek(); + IType handle = null; + String nameString = new String(name); + + if (parentHandle.getElementType() == IJavaElement.COMPILATION_UNIT) { + handle = ((ICompilationUnit) parentHandle).getType(nameString); + if (fPackageName == null) { + qualifiedName = nameString.toCharArray(); + } else { + qualifiedName = (new String(fPackageName) + "." + nameString).toCharArray(); //$NON-NLS-1$ + } + } else if (parentHandle.getElementType() == IJavaElement.TYPE) { + handle = ((IType) parentHandle).getType(nameString); + enclosingTypeName = ((SourceTypeElementInfo) parentInfo).getName(); + qualifiedName = (new String(((SourceTypeElementInfo) parentInfo).getQualifiedName()) + "." + nameString).toCharArray(); //$NON-NLS-1$ + } else { + Assert.isTrue(false); // Should not happen + } + resolveDuplicates(handle); + + SourceTypeElementInfo info = new SourceTypeElementInfo(); + info.setHandle(handle); + info.setSourceRangeStart(declarationStart); + info.setFlags(modifiers); + info.setName(name); + info.setNameSourceStart(nameSourceStart); + info.setNameSourceEnd(nameSourceEnd); + info.setSuperclassName(superclass); + info.setSuperInterfaceNames(superinterfaces); + info.setEnclosingTypeName(enclosingTypeName); + info.setSourceFileName(fSourceFileName); + info.setPackageName(fPackageName); + info.setQualifiedName(qualifiedName); + // for (Iterator iter = fNewElements.keySet().iterator(); iter.hasNext();){ + // Object object = iter.next(); + // if (object instanceof IImportDeclaration) + // info.addImport(((IImportDeclaration)object).getElementName().toCharArray()); + // } + + parentInfo.addChild(handle); + fNewElements.put(handle, info); + + fInfoStack.push(info); + fHandleStack.push(handle); + + } + /** + * @see ISourceElementRequestor + */ + public void exitClass(int declarationEnd) { + + exitMember(declarationEnd); + } + /** + * @see ISourceElementRequestor + */ + public void exitCompilationUnit(int declarationEnd) { + fUnitInfo.setSourceLength(declarationEnd + 1); + + // determine if there were any parsing errors + fUnitInfo.setIsStructureKnown(!this.hasSyntaxErrors); + } + /** + * @see ISourceElementRequestor + */ + public void exitConstructor(int declarationEnd) { + exitMember(declarationEnd); + } + ///** + // * @see ISourceElementRequestor + // */ + //public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) { + // SourceFieldElementInfo info = (SourceFieldElementInfo) fInfoStack.pop(); + // info.setSourceRangeEnd(declarationSourceEnd); + // + // // remember initializer source if field is a constant + // if (initializationStart != -1) { + // int flags = info.flags; + // Object typeInfo; + // if (Flags.isStatic(flags) && Flags.isFinal(flags) + // || ((typeInfo = fInfoStack.peek()) instanceof SourceTypeElementInfo + // && (Flags.isInterface(((SourceTypeElementInfo)typeInfo).flags)))) { + // int length = declarationEnd - initializationStart; + // if (length > 0) { + // char[] initializer = new char[length]; + // System.arraycopy(this.parser.scanner.source, initializationStart, initializer, 0, length); + // info.initializationSource = initializer; + // } + // } + // } + // fHandleStack.pop(); + //} + /** + * @see ISourceElementRequestor + */ + public void exitInitializer(int declarationEnd) { + exitMember(declarationEnd); + } + /** + * @see ISourceElementRequestor + */ + public void exitInterface(int declarationEnd) { + exitMember(declarationEnd); + } + /** + * common processing for classes and interfaces + */ + protected void exitMember(int declarationEnd) { + SourceRefElementInfo info = (SourceRefElementInfo) fInfoStack.pop(); + info.setSourceRangeEnd(declarationEnd); + fHandleStack.pop(); + } + /** + * @see ISourceElementRequestor + */ + public void exitMethod(int declarationEnd) { + exitMember(declarationEnd); + } + + /** + * Resolves duplicate handles by incrementing the occurrence count + * of the handle being created until there is no conflict. + */ + protected void resolveDuplicates(IJavaElement handle) { + while (fNewElements.containsKey(handle)) { + JavaElement h = (JavaElement) handle; + h.setOccurrenceCount(h.getOccurrenceCount() + 1); + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CopyElementsOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CopyElementsOperation.java new file mode 100644 index 0000000..ba92d34 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CopyElementsOperation.java @@ -0,0 +1,262 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelStatus; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; +import net.sourceforge.phpdt.core.IMember; +import net.sourceforge.phpdt.core.IParent; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.jdom.DOMFactory; +import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit; +import net.sourceforge.phpdt.core.jdom.IDOMNode; + +/** + * This operation copies/moves a collection of elements from their current + * container to a new container, optionally renaming the + * elements. + *

      Notes:

        + *
      • If there is already an element with the same name in + * the new container, the operation either overwrites or aborts, + * depending on the collision policy setting. The default setting is + * abort. + * + *
      • When constructors are copied to a type, the constructors + * are automatically renamed to the name of the destination + * type. + * + *
      • When main types are renamed (move within the same parent), + * the compilation unit and constructors are automatically renamed + * + *
      • The collection of elements being copied must all share the + * same type of container (for example, must all be type members). + * + *
      • The elements are inserted in the new container in the order given. + * + *
      • The elements can be positioned in the new container - see #setInsertBefore. + * By default, the elements are inserted based on the default positions as specified in + * the creation operation for that element type. + * + *
      • This operation can be used to copy and rename elements within + * the same container. + * + *
      • This operation only copies elements contained within compilation units. + *
      + * + */ +public class CopyElementsOperation extends MultiOperation { + + + private Map fSources = new HashMap(); +/** + * When executed, this operation will copy the given elements to the + * given containers. The elements and destination containers must be in + * the correct order. If there is > 1 destination, the number of destinations + * must be the same as the number of elements being copied/moved/renamed. + */ +public CopyElementsOperation(IJavaElement[] elementsToCopy, IJavaElement[] destContainers, boolean force) { + super(elementsToCopy, destContainers, force); +} +/** + * When executed, this operation will copy the given elements to the + * given container. + */ +public CopyElementsOperation(IJavaElement[] elementsToCopy, IJavaElement destContainer, boolean force) { + this(elementsToCopy, new IJavaElement[]{destContainer}, force); +} +/** + * Returns the String to use as the main task name + * for progress monitoring. + */ +protected String getMainTaskName() { + return Util.bind("operation.copyElementProgress"); //$NON-NLS-1$ +} +/** + * Returns the nested operation to use for processing this element + */ +protected JavaModelOperation getNestedOperation(IJavaElement element) { + return null; +// try { +// IJavaElement dest = getDestinationParent(element); +// switch (element.getElementType()) { +// case IJavaElement.PACKAGE_DECLARATION : +// return new CreatePackageDeclarationOperation(element.getElementName(), (ICompilationUnit) dest); +// case IJavaElement.IMPORT_DECLARATION : +// return new CreateImportOperation(element.getElementName(), (ICompilationUnit) dest); +// case IJavaElement.TYPE : +// if (isRenamingMainType(element, dest)) { +// return new RenameResourceElementsOperation(new IJavaElement[] {dest}, new IJavaElement[] {dest.getParent()}, new String[]{getNewNameFor(element) + ".php"}, fForce); //$NON-NLS-1$ +// } else { +// return new CreateTypeOperation(dest, getSourceFor(element) + Util.LINE_SEPARATOR, fForce); +// } +// case IJavaElement.METHOD : +// return new CreateMethodOperation((IType) dest, getSourceFor(element) + Util.LINE_SEPARATOR, fForce); +// case IJavaElement.FIELD : +// return new CreateFieldOperation((IType) dest, getSourceFor(element) + Util.LINE_SEPARATOR, fForce); +// case IJavaElement.INITIALIZER : +// return new CreateInitializerOperation((IType) dest, getSourceFor(element) + Util.LINE_SEPARATOR); +// default : +// return null; +// } +// } catch (JavaModelException npe) { +// return null; +// } +} +/** + * Returns the cached source for this element or compute it if not already cached. + */ +private String getSourceFor(IJavaElement element) throws JavaModelException { + String source = (String) fSources.get(element); + if (source == null && element instanceof IMember) { + IMember member = (IMember)element; + ICompilationUnit cu = member.getCompilationUnit(); + String cuSource = cu.getSource(); + IDOMCompilationUnit domCU = new DOMFactory().createCompilationUnit(cuSource, cu.getElementName()); + IDOMNode node = ((JavaElement)element).findNode(domCU); + source = new String(node.getCharacters()); + fSources.put(element, source); + } + return source; +} +/** + * Returns true if this element is the main type of its compilation unit. + */ +protected boolean isRenamingMainType(IJavaElement element, IJavaElement dest) { + if ((isRename() || getNewNameFor(element) != null) + && dest.getElementType() == IJavaElement.COMPILATION_UNIT) { + String typeName = dest.getElementName(); + typeName = typeName.substring(0, typeName.length() - 5); + return element.getElementName().equals(typeName) && element.getParent().equals(dest); + } + return false; +} +/** + * Copy/move the element from the source to destination, renaming + * the elements as specified, honoring the collision policy. + * + * @exception JavaModelException if the operation is unable to + * be completed + */ +protected void processElement(IJavaElement element) throws JavaModelException { + JavaModelOperation op = getNestedOperation(element); + boolean createElementInCUOperation =op instanceof CreateElementInCUOperation; + if (op == null) { + return; + } + if (createElementInCUOperation) { + IJavaElement sibling = (IJavaElement) fInsertBeforeElements.get(element); + if (sibling != null) { + ((CreateElementInCUOperation) op).setRelativePosition(sibling, CreateElementInCUOperation.INSERT_BEFORE); + } else + if (isRename()) { + IJavaElement anchor = resolveRenameAnchor(element); + if (anchor != null) { + ((CreateElementInCUOperation) op).setRelativePosition(anchor, CreateElementInCUOperation.INSERT_AFTER); // insert after so that the anchor is found before when deleted below + } + } + String newName = getNewNameFor(element); + if (newName != null) { + ((CreateElementInCUOperation) op).setAlteredName(newName); + } + } + executeNestedOperation(op, 1); + + JavaElement destination = (JavaElement) getDestinationParent(element); + ICompilationUnit unit= destination.getCompilationUnit(); + if (!unit.isWorkingCopy()) { + unit.close(); + } + + if (createElementInCUOperation && isMove() && !isRenamingMainType(element, destination)) { + DeleteElementsOperation deleteOp = new DeleteElementsOperation(new IJavaElement[] { element }, fForce); + executeNestedOperation(deleteOp, 1); + } +} +/** + * Returns the anchor used for positioning in the destination for + * the element being renamed. For renaming, if no anchor has + * explicitly been provided, the element is anchored in the same position. + */ +private IJavaElement resolveRenameAnchor(IJavaElement element) throws JavaModelException { + IParent parent = (IParent) element.getParent(); + IJavaElement[] children = parent.getChildren(); + for (int i = 0; i < children.length; i++) { + IJavaElement child = children[i]; + if (child.equals(element)) { + return child; + } + } + return null; +} +/** + * Possible failures: + *
        + *
      • NO_ELEMENTS_TO_PROCESS - no elements supplied to the operation + *
      • INDEX_OUT_OF_BOUNDS - the number of renamings supplied to the operation + * does not match the number of elements that were supplied. + *
      + */ +protected IJavaModelStatus verify() { + IJavaModelStatus status = super.verify(); + if (!status.isOK()) { + return status; + } + if (fRenamingsList != null && fRenamingsList.length != fElementsToProcess.length) { + return new JavaModelStatus(IJavaModelStatusConstants.INDEX_OUT_OF_BOUNDS); + } + return JavaModelStatus.VERIFIED_OK; +} +/** + * @see MultiOperation + * + * Possible failure codes: + *
        + * + *
      • ELEMENT_DOES_NOT_EXIST - element or its specified destination is + * is null or does not exist. If a null element is + * supplied, no element is provided in the status, otherwise, the non-existant element + * is supplied in the status. + *
      • INVALID_ELEMENT_TYPES - element is not contained within a compilation unit. + * This operation only operates on elements contained within compilation units. + *
      • READ_ONLY - element is read only. + *
      • INVALID_DESTINATION - The destination parent specified for element + * is of an incompatible type. The destination for a package declaration or import declaration must + * be a compilation unit; the destination for a type must be a type or compilation + * unit; the destinaion for any type member (other than a type) must be a type. When + * this error occurs, the element provided in the operation status is the element. + *
      • INVALID_NAME - the new name for element does not have valid syntax. + * In this case the element and name are provided in the status. + + *
      + */ +protected void verify(IJavaElement element) throws JavaModelException { + if (element == null || !element.exists()) + error(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, element); + + if (element.getElementType() < IJavaElement.TYPE) + error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element); + + if (element.isReadOnly()) + error(IJavaModelStatusConstants.READ_ONLY, element); + + IJavaElement dest = getDestinationParent(element); + verifyDestination(element, dest); + verifySibling(element, dest); + if (fRenamingsList != null) { + verifyRenaming(element); + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CopyResourceElementsOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CopyResourceElementsOperation.java new file mode 100644 index 0000000..2e30065 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CopyResourceElementsOperation.java @@ -0,0 +1,648 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import net.sourceforge.phpdt.core.IBuffer; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaElementDelta; +import net.sourceforge.phpdt.core.IJavaModelStatus; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.jdom.DOMException; +import net.sourceforge.phpdt.core.jdom.DOMFactory; +import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.core.jdom.IDOMPackage; +import net.sourceforge.phpeclipse.PHPCore; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * This operation copies/moves/renames a collection of resources from their current + * container to a new container, optionally renaming the + * elements. + *

      Notes:

        + *
      • If there is already an resource with the same name in + * the new container, the operation either overwrites or aborts, + * depending on the collision policy setting. The default setting is + * abort. + * + *
      • When a compilation unit is copied to a new package, the + * package declaration in the compilation unit is automatically updated. + * + *
      • The collection of elements being copied must all share the + * same type of container. + * + *
      • This operation can be used to copy and rename elements within + * the same container. + * + *
      • This operation only copies compilation units and package fragments. + * It does not copy package fragment roots - a platform operation must be used for that. + *
      + * + */ +public class CopyResourceElementsOperation extends MultiOperation { + /** + * A collection of renamed compilation units. These cus do + * not need to be saved as they no longer exist. + */ + protected ArrayList fRenamedCompilationUnits = null; + /** + * Table specifying deltas for elements being + * copied/moved/renamed. Keyed by elements' project(s), and + * values are the corresponding deltas. + */ + protected Map fDeltasPerProject= new HashMap(1); + /** + * The DOMFactory used to manipulate the source code of + * ICompilationUnit. + */ + protected DOMFactory fFactory; + /** + * The list of new resources created during this operation. + */ + protected ArrayList fCreatedElements; + /** + * When executed, this operation will copy the given resources to the + * given containers. The resources and destination containers must be in + * the correct order. If there is > 1 destination, the number of destinations + * must be the same as the number of resources being copied/moved. + */ + public CopyResourceElementsOperation(IJavaElement[] resourcesToCopy, IJavaElement[] destContainers, boolean force) { + super(resourcesToCopy, destContainers, force); + fFactory = new DOMFactory(); + } + /** + * When executed, this operation will copy the given resources to the + * given container. + */ + public CopyResourceElementsOperation(IJavaElement[] resourcesToCopy, IJavaElement destContainer, boolean force) { + this(resourcesToCopy, new IJavaElement[]{destContainer}, force); + } + /** + * Returns the children of source which are affected by this operation. + * If source is a K_SOURCE, these are the .java + * files, if it is a K_BINARY, they are the .class files. + */ + private IResource[] collectResourcesOfInterest(IPackageFragment source) throws JavaModelException { + IJavaElement[] children = source.getChildren(); + int childOfInterest = IJavaElement.COMPILATION_UNIT; +// if (source.getKind() == IPackageFragmentRoot.K_BINARY) { +// childOfInterest = IJavaElement.CLASS_FILE; +// } + ArrayList correctKindChildren = new ArrayList(children.length); + for (int i = 0; i < children.length; i++) { + IJavaElement child = children[i]; + if (child.getElementType() == childOfInterest) { + correctKindChildren.add(child.getResource()); + } + } + // Gather non-java resources +// Object[] nonJavaResources = source.getNonJavaResources(); +// int actualNonJavaResourceCount = 0; +// for (int i = 0, max = nonJavaResources.length; i < max; i++){ +// if (nonJavaResources[i] instanceof IResource) actualNonJavaResourceCount++; +// } +// IResource[] actualNonJavaResources = new IResource[actualNonJavaResourceCount]; +// for (int i = 0, max = nonJavaResources.length, index = 0; i < max; i++){ +// if (nonJavaResources[i] instanceof IResource) actualNonJavaResources[index++] = (IResource)nonJavaResources[i]; +// } + +// if (actualNonJavaResourceCount != 0) { +// int correctKindChildrenSize = correctKindChildren.size(); +// IResource[] result = new IResource[correctKindChildrenSize + actualNonJavaResourceCount]; +// correctKindChildren.toArray(result); +// System.arraycopy(actualNonJavaResources, 0, result, correctKindChildrenSize, actualNonJavaResourceCount); +// return result; +// } else { + IResource[] result = new IResource[correctKindChildren.size()]; + correctKindChildren.toArray(result); + return result; +// } + } + /** + * Creates any destination package fragment(s) which do not exists yet. + */ + private void createNeededPackageFragments(IContainer sourceFolder, IPackageFragmentRoot root, String newFragName, boolean moveFolder) throws JavaModelException { + IContainer parentFolder = (IContainer) root.getResource(); + JavaElementDelta projectDelta = null; + String[] names = net.sourceforge.phpdt.internal.core.Util.getTrimmedSimpleNames(newFragName); + StringBuffer sideEffectPackageName = new StringBuffer(); + char[][] exclusionsPatterns = ((PackageFragmentRoot)root).fullExclusionPatternChars(); + for (int i = 0; i < names.length; i++) { + String subFolderName = names[i]; + sideEffectPackageName.append(subFolderName); + IResource subFolder = parentFolder.findMember(subFolderName); + if (subFolder == null) { + // create deepest folder only if not a move (folder will be moved in processPackageFragmentResource) + if (!(moveFolder && i == names.length-1)) { + createFolder(parentFolder, subFolderName, fForce); + } + parentFolder = parentFolder.getFolder(new Path(subFolderName)); + sourceFolder = sourceFolder.getFolder(new Path(subFolderName)); + if (sourceFolder.isReadOnly()) { + parentFolder.setReadOnly(true); + } + IPackageFragment sideEffectPackage = root.getPackageFragment(sideEffectPackageName.toString()); + if (i < names.length - 1 // all but the last one are side effect packages + && !net.sourceforge.phpdt.internal.core.Util.isExcluded(parentFolder, exclusionsPatterns)) { + if (projectDelta == null) { + projectDelta = getDeltaFor(root.getJavaProject()); + } + projectDelta.added(sideEffectPackage); + } + fCreatedElements.add(sideEffectPackage); + } else { + parentFolder = (IContainer) subFolder; + } + sideEffectPackageName.append('.'); + } + } + /** + * Returns the JavaElementDelta for javaProject, + * creating it and putting it in fDeltasPerProject if + * it does not exist yet. + */ + private JavaElementDelta getDeltaFor(IJavaProject javaProject) { + JavaElementDelta delta = (JavaElementDelta) fDeltasPerProject.get(javaProject); + if (delta == null) { + delta = new JavaElementDelta(javaProject); + fDeltasPerProject.put(javaProject, delta); + } + return delta; + } + /** + * @see MultiOperation + */ + protected String getMainTaskName() { + return net.sourceforge.phpdt.internal.core.Util.bind("operation.copyResourceProgress"); //$NON-NLS-1$ + } + /** + * Sets the deltas to register the changes resulting from this operation + * for this source element and its destination. + * If the operation is a cross project operation
        + *
      • On a copy, the delta should be rooted in the dest project + *
      • On a move, two deltas are generated
          + *
        • one rooted in the source project + *
        • one rooted in the destination project
      + * If the operation is rooted in a single project, the delta is rooted in that project + * + */ + protected void prepareDeltas(IJavaElement sourceElement, IJavaElement destinationElement, boolean isMove) { + if (net.sourceforge.phpdt.internal.core.Util.isExcluded(sourceElement) || net.sourceforge.phpdt.internal.core.Util.isExcluded(destinationElement)) return; + IJavaProject destProject = destinationElement.getJavaProject(); + if (isMove) { + IJavaProject sourceProject = sourceElement.getJavaProject(); + getDeltaFor(sourceProject).movedFrom(sourceElement, destinationElement); + getDeltaFor(destProject).movedTo(destinationElement, sourceElement); + } else { + getDeltaFor(destProject).added(destinationElement); + } + } + /** + * Copies/moves a compilation unit with the name newCUName + * to the destination package.
      + * The package statement in the compilation unit is updated if necessary. + * The main type of the compilation unit is renamed if necessary. + * + * @exception JavaModelException if the operation is unable to + * complete + */ + private void processCompilationUnitResource(ICompilationUnit source, IPackageFragment dest) throws JavaModelException { + String newCUName = getNewNameFor(source); + String destName = (newCUName != null) ? newCUName : source.getElementName(); + String newContent = updatedContent(source, dest, newCUName); // null if unchanged + + // copy resource + IFile sourceResource = (IFile)(source.isWorkingCopy() ? source.getOriginalElement() : source).getResource(); + IContainer destFolder = (IContainer)dest.getResource(); // can be an IFolder or an IProject + IFile destFile = destFolder.getFile(new Path(destName)); + if (!destFile.equals(sourceResource)) { + try { + if (destFile.exists()) { + if (fForce) { + // we can remove it + deleteResource(destFile, IResource.KEEP_HISTORY); + } else { + // abort + throw new JavaModelException(new JavaModelStatus( + IJavaModelStatusConstants.NAME_COLLISION, + Util.bind("status.nameCollision", destFile.getFullPath().toString()))); //$NON-NLS-1$ + } + } + int flags = fForce ? IResource.FORCE : IResource.NONE; + if (this.isMove()) { + flags |= IResource.KEEP_HISTORY; + sourceResource.move(destFile.getFullPath(), flags, getSubProgressMonitor(1)); + } else { + if (newContent != null) flags |= IResource.KEEP_HISTORY; + sourceResource.copy(destFile.getFullPath(), flags, getSubProgressMonitor(1)); + } + this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); + } catch (JavaModelException e) { + throw e; + } catch (CoreException e) { + throw new JavaModelException(e); + } + + // update new resource content + try { + if (newContent != null){ + String encoding = source.getJavaProject().getOption(PHPCore.CORE_ENCODING, true); + destFile.setContents( + new ByteArrayInputStream(encoding == null ? newContent.getBytes() : newContent.getBytes(encoding)), + fForce ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY, + getSubProgressMonitor(1)); + } + } catch(IOException e) { + throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); + } catch (CoreException e) { + throw new JavaModelException(e); + } + + // register the correct change deltas + ICompilationUnit destCU = dest.getCompilationUnit(destName); + prepareDeltas(source, destCU, isMove()); + if (newCUName != null) { + //the main type has been renamed + String oldName = source.getElementName(); + oldName = oldName.substring(0, oldName.length() - 5); + String newName = newCUName; + newName = newName.substring(0, newName.length() - 5); + prepareDeltas(source.getType(oldName), destCU.getType(newName), isMove()); + } + } else { + if (!fForce) { + throw new JavaModelException(new JavaModelStatus( + IJavaModelStatusConstants.NAME_COLLISION, + Util.bind("status.nameCollision", destFile.getFullPath().toString()))); //$NON-NLS-1$ + } + // update new resource content + // in case we do a saveas on the same resource we have to simply update the contents + // see http://dev.eclipse.org/bugs/show_bug.cgi?id=9351 + try { + if (newContent != null){ + String encoding = source.getJavaProject().getOption(PHPCore.CORE_ENCODING, true); + destFile.setContents( + new ByteArrayInputStream(encoding == null ? newContent.getBytes() : newContent.getBytes(encoding)), + fForce ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY, + getSubProgressMonitor(1)); + } + } catch(IOException e) { + throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); + } catch (CoreException e) { + throw new JavaModelException(e); + } + } + } + /** + * Process all of the changed deltas generated by this operation. + */ + protected void processDeltas() { + for (Iterator deltas = this.fDeltasPerProject.values().iterator(); deltas.hasNext();){ + addDelta((IJavaElementDelta) deltas.next()); + } + } + /** + * @see MultiOperation + * This method delegates to processCompilationUnitResource or + * processPackageFragmentResource, depending on the type of + * element. + */ + protected void processElement(IJavaElement element) throws JavaModelException { + IJavaElement dest = getDestinationParent(element); + switch (element.getElementType()) { + case IJavaElement.COMPILATION_UNIT : + processCompilationUnitResource((ICompilationUnit) element, (IPackageFragment) dest); + fCreatedElements.add(((IPackageFragment) dest).getCompilationUnit(element.getElementName())); + break; + case IJavaElement.PACKAGE_FRAGMENT : + processPackageFragmentResource((IPackageFragment) element, (IPackageFragmentRoot) dest, getNewNameFor(element)); + break; + default : + throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element)); + } + } + /** + * @see MultiOperation + * Overridden to allow special processing of JavaElementDeltas + * and fResultElements. + */ + protected void processElements() throws JavaModelException { + fCreatedElements = new ArrayList(fElementsToProcess.length); + try { + super.processElements(); + } catch (JavaModelException jme) { + throw jme; + } finally { + fResultElements = new IJavaElement[fCreatedElements.size()]; + fCreatedElements.toArray(fResultElements); + processDeltas(); + } + } + /** + * Copies/moves a package fragment with the name newName + * to the destination package.
      + * + * @exception JavaModelException if the operation is unable to + * complete + */ + private void processPackageFragmentResource(IPackageFragment source, IPackageFragmentRoot root, String newName) throws JavaModelException { + try { + String newFragName = (newName == null) ? source.getElementName() : newName; + IPackageFragment newFrag = root.getPackageFragment(newFragName); + IResource[] resources = collectResourcesOfInterest(source); + + // if isMove() can we move the folder itself ? (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=22458) + boolean shouldMoveFolder = isMove() && !newFrag.getResource().exists(); // if new pkg fragment exists, it is an override + IFolder srcFolder = (IFolder)source.getResource(); + IPath destPath = newFrag.getPath(); + if (shouldMoveFolder) { + // check if destination is not included in source + if (srcFolder.getFullPath().isPrefixOf(destPath)) { + shouldMoveFolder = false; + } else { + // check if there are no sub-packages + IResource[] members = srcFolder.members(); + for (int i = 0; i < members.length; i++) { + if ( members[i] instanceof IFolder) { + shouldMoveFolder = false; + break; + } + } + } + } + createNeededPackageFragments((IContainer) source.getParent().getResource(), root, newFragName, shouldMoveFolder); + + // Process resources + if (shouldMoveFolder) { + // move underlying resource + srcFolder.move(destPath, fForce, true /* keep history */, getSubProgressMonitor(1)); + this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); + } else { + // process the leaf resources + if (resources.length > 0) { + if (isRename()) { + if (! destPath.equals(source.getPath())) { + moveResources(resources, destPath); + } + } else if (isMove()) { + // we need to delete this resource if this operation wants to override existing resources + for (int i = 0, max = resources.length; i < max; i++) { + IResource destinationResource = ResourcesPlugin.getWorkspace().getRoot().findMember(destPath.append(resources[i].getName())); + if (destinationResource != null) { + if (fForce) { + deleteResource(destinationResource, IResource.KEEP_HISTORY); + } else { + throw new JavaModelException(new JavaModelStatus( + IJavaModelStatusConstants.NAME_COLLISION, + Util.bind("status.nameCollision", destinationResource.getFullPath().toString()))); //$NON-NLS-1$ + } + } + } + moveResources(resources, destPath); + } else { + // we need to delete this resource if this operation wants to override existing resources + for (int i = 0, max = resources.length; i < max; i++) { + IResource destinationResource = ResourcesPlugin.getWorkspace().getRoot().findMember(destPath.append(resources[i].getName())); + if (destinationResource != null) { + if (fForce) { + // we need to delete this resource if this operation wants to override existing resources + deleteResource(destinationResource, IResource.KEEP_HISTORY); + } else { + throw new JavaModelException(new JavaModelStatus( + IJavaModelStatusConstants.NAME_COLLISION, + Util.bind("status.nameCollision", destinationResource.getFullPath().toString()))); //$NON-NLS-1$ + } + } + } + copyResources(resources, destPath); + } + } + } + + // Discard empty old package (if still empty after the rename) + boolean isEmpty = true; + if (isMove()) { + // delete remaining files in this package (.class file in the case where Proj=src=bin) + if (srcFolder.exists()) { + IResource[] remaingFiles = srcFolder.members(); + for (int i = 0, length = remaingFiles.length; i < length; i++) { + IResource file = remaingFiles[i]; + if (file instanceof IFile) { + this.deleteResource(file, IResource.FORCE | IResource.KEEP_HISTORY); + } else { + isEmpty = false; + } + } + } + if (isEmpty) { + IResource rootResource; + // check if source is included in destination + if (destPath.isPrefixOf(srcFolder.getFullPath())) { + rootResource = newFrag.getResource(); + } else { + rootResource = source.getParent().getResource(); + } + + // delete recursively empty folders + deleteEmptyPackageFragment(source, false, rootResource); + } + } + + // Update package statement in compilation unit if needed + if (!newFrag.getElementName().equals(source.getElementName())) { // if package has been renamed, update the compilation units + for (int i = 0; i < resources.length; i++) { + if (resources[i].getName().endsWith(".java")) { //$NON-NLS-1$ + // we only consider potential compilation units + ICompilationUnit cu = newFrag.getCompilationUnit(resources[i].getName()); + IDOMCompilationUnit domCU = fFactory.createCompilationUnit(cu.getSource(), cu.getElementName()); + if (domCU != null) { + updatePackageStatement(domCU, newFragName); + IBuffer buffer = cu.getBuffer(); + if (buffer == null) continue; + String bufferContents = buffer.getContents(); + if (bufferContents == null) continue; + String domCUContents = domCU.getContents(); + String cuContents = null; + if (domCUContents != null) { + cuContents = net.sourceforge.phpdt.internal.core.Util.normalizeCRs(domCU.getContents(), bufferContents); + } else { + // See PR http://dev.eclipse.org/bugs/show_bug.cgi?id=11285 + cuContents = bufferContents;//$NON-NLS-1$ + } + buffer.setContents(cuContents); + cu.save(null, false); + } + } + } + } + + //register the correct change deltas + prepareDeltas(source, newFrag, isMove() && isEmpty); + } catch (DOMException dom) { + throw new JavaModelException(dom, IJavaModelStatusConstants.DOM_EXCEPTION); + } catch (JavaModelException e) { + throw e; + } catch (CoreException ce) { + throw new JavaModelException(ce); + } + } + /** + * Updates the content of cu, modifying the type name and/or package + * declaration as necessary. + * + * @return the new source + */ + private String updatedContent(ICompilationUnit cu, IPackageFragment dest, String newName) throws JavaModelException { + String currPackageName = cu.getParent().getElementName(); + String destPackageName = dest.getElementName(); + if (currPackageName.equals(destPackageName) && newName == null) { + return null; //nothing to change + } else { + String typeName = cu.getElementName(); + typeName = typeName.substring(0, typeName.length() - 5); + IDOMCompilationUnit cuDOM = null; + IBuffer buffer = cu.getBuffer(); + if (buffer == null) return null; + char[] contents = buffer.getCharacters(); + if (contents == null) return null; + cuDOM = fFactory.createCompilationUnit(contents, typeName); + updateTypeName(cu, cuDOM, cu.getElementName(), newName); + updatePackageStatement(cuDOM, destPackageName); + return cuDOM.getContents(); + } + } + /** + * Makes sure that cu declares to be in the pkgName package. + */ + private void updatePackageStatement(IDOMCompilationUnit domCU, String pkgName) throws JavaModelException { + boolean defaultPackage = pkgName.equals(IPackageFragment.DEFAULT_PACKAGE_NAME); + boolean seenPackageNode = false; + Enumeration enum = domCU.getChildren(); + while (enum.hasMoreElements()) { + IDOMNode node = (IDOMNode) enum.nextElement(); + if (node.getNodeType() == IDOMNode.PACKAGE) { + if (! defaultPackage) { + node.setName(pkgName); + } else { + node.remove(); + } + seenPackageNode = true; + break; + } + } + if (!seenPackageNode && !defaultPackage) { + //the cu was in a default package...no package declaration + //create the new package declaration as the first child of the cu +// IDOMPackage pkg = fFactory.createPackage("package " + pkgName + ";" + net.sourceforge.phpdt.internal.compiler.util.Util.LINE_SEPARATOR); //$NON-NLS-1$ //$NON-NLS-2$ +// IDOMNode firstChild = domCU.getFirstChild(); +// if (firstChild != null) { +// firstChild.insertSibling(pkg); +// } // else the cu was empty: leave it empty + } + } + /** + * Renames the main type in cu. + */ + private void updateTypeName(ICompilationUnit cu, IDOMCompilationUnit domCU, String oldName, String newName) throws JavaModelException { + if (newName != null) { + if (fRenamedCompilationUnits == null) { + fRenamedCompilationUnits= new ArrayList(1); + } + fRenamedCompilationUnits.add(cu); + String oldTypeName= oldName.substring(0, oldName.length() - 5); + String newTypeName= newName.substring(0, newName.length() - 5); + // update main type name + IType[] types = cu.getTypes(); + for (int i = 0, max = types.length; i < max; i++) { + IType currentType = types[i]; + if (currentType.getElementName().equals(oldTypeName)) { + IDOMNode typeNode = ((JavaElement) currentType).findNode(domCU); + if (typeNode != null) { + typeNode.setName(newTypeName); + } + } + } + } + } + /** + * Possible failures: + *
        + *
      • NO_ELEMENTS_TO_PROCESS - no elements supplied to the operation + *
      • INDEX_OUT_OF_BOUNDS - the number of renamings supplied to the operation + * does not match the number of elements that were supplied. + *
      + */ + protected IJavaModelStatus verify() { + IJavaModelStatus status = super.verify(); + if (!status.isOK()) { + return status; + } + + if (fRenamingsList != null && fRenamingsList.length != fElementsToProcess.length) { + return new JavaModelStatus(IJavaModelStatusConstants.INDEX_OUT_OF_BOUNDS); + } + return JavaModelStatus.VERIFIED_OK; + } + /** + * @see MultiOperation + */ + protected void verify(IJavaElement element) throws JavaModelException { + if (element == null || !element.exists()) + error(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, element); + + if (element.isReadOnly() && (isRename() || isMove())) + error(IJavaModelStatusConstants.READ_ONLY, element); + + IResource resource = element.getResource(); + if (resource instanceof IFolder) { + if (resource.isLinked()) { + error(JavaModelStatus.INVALID_RESOURCE, element); + } + } + + int elementType = element.getElementType(); + + if (elementType == IJavaElement.COMPILATION_UNIT) { + if (isMove() && ((ICompilationUnit) element).isWorkingCopy()) + error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element); + } else if (elementType != IJavaElement.PACKAGE_FRAGMENT) { + error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element); + } + + JavaElement dest = (JavaElement) getDestinationParent(element); + verifyDestination(element, dest); + if (fRenamings != null) { + verifyRenaming(element); + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CreateElementInCUOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CreateElementInCUOperation.java new file mode 100644 index 0000000..20d2ebb --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CreateElementInCUOperation.java @@ -0,0 +1,316 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.IBuffer; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelStatus; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.jdom.DOMFactory; +import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.internal.core.jdom.DOMNode; + +/** + *

      This abstract class implements behavior common to CreateElementInCUOperations. + * To create a compilation unit, or an element contained in a compilation unit, the + * source code for the entire compilation unit is updated and saved. + * + *

      The element being created can be positioned relative to an existing + * element in the compilation unit via the methods #createAfter + * and #createBefore. By default, the new element is positioned + * as the last child of its parent element. + * + */ +public abstract class CreateElementInCUOperation extends JavaModelOperation { + /** + * The compilation unit DOM used for this operation + */ + protected IDOMCompilationUnit fCUDOM; + /** + * A constant meaning to position the new element + * as the last child of its parent element. + */ + protected static final int INSERT_LAST = 1; + /** + * A constant meaning to position the new element + * after the element defined by fAnchorElement. + */ + protected static final int INSERT_AFTER = 2; + + /** + * A constant meaning to position the new element + * before the element defined by fAnchorElement. + */ + protected static final int INSERT_BEFORE = 3; + /** + * One of the position constants, describing where + * to position the newly created element. + */ + protected int fInsertionPolicy = INSERT_LAST; + /** + * The element that the newly created element is + * positioned relative to, as described by + * fInsertPosition, or null + * if the newly created element will be positioned + * last. + */ + protected IJavaElement fAnchorElement = null; + /** + * A flag indicating whether creation of a new element occurred. + * A request for creating a duplicate element would request in this + * flag being set to false. Ensures that no deltas are generated + * when creation does not occur. + */ + protected boolean fCreationOccurred = true; + /** + * The element that is being created. + */ + protected DOMNode fCreatedElement; + /** + * The position of the element that is being created. + */ + protected int fInsertionPosition = -1; + /** + * The number of characters the new element replaces, + * or 0 if the new element is inserted, + * or -1 if the new element is append to the end of the CU. + */ + protected int fReplacementLength = -1; + /** + * Constructs an operation that creates a Java Language Element with + * the specified parent, contained within a compilation unit. + */ + public CreateElementInCUOperation(IJavaElement parentElement) { + super(null, new IJavaElement[]{parentElement}); + initializeDefaultPosition(); + } + /** + * Only allow cancelling if this operation is not nested. + */ + protected void checkCanceled() { + if (!fNested) { + super.checkCanceled(); + } + } + /** + * Instructs this operation to position the new element after + * the given sibling, or to add the new element as the last child + * of its parent if null. + */ + public void createAfter(IJavaElement sibling) { + setRelativePosition(sibling, INSERT_AFTER); + } + /** + * Instructs this operation to position the new element before + * the given sibling, or to add the new element as the last child + * of its parent if null. + */ + public void createBefore(IJavaElement sibling) { + setRelativePosition(sibling, INSERT_BEFORE); + } + /** + * Execute the operation - generate new source for the compilation unit + * and save the results. + * + * @exception JavaModelException if the operation is unable to complete + */ + protected void executeOperation() throws JavaModelException { + try { + beginTask(getMainTaskName(), getMainAmountOfWork()); + JavaElementDelta delta = newJavaElementDelta(); + ICompilationUnit unit = getCompilationUnit(); + generateNewCompilationUnitDOM(unit); + if (fCreationOccurred) { + //a change has really occurred + IBuffer buffer = unit.getBuffer(); + if (buffer == null) return; + char[] bufferContents = buffer.getCharacters(); + if (bufferContents == null) return; + char[] elementContents = net.sourceforge.phpdt.internal.core.Util.normalizeCRs(fCreatedElement.getCharacters(), bufferContents); + switch (fReplacementLength) { + case -1 : + // element is append at the end + buffer.append(elementContents); + break; + case 0 : + // element is inserted + buffer.replace(fInsertionPosition, 0, elementContents); + break; + default : + // element is replacing the previous one + buffer.replace(fInsertionPosition, fReplacementLength, elementContents); + } + unit.save(null, false); + boolean isWorkingCopy = unit.isWorkingCopy(); + if (!isWorkingCopy) + this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); + worked(1); + fResultElements = generateResultHandles(); + if (!isWorkingCopy // if unit is working copy, then save will have already fired the delta + && !Util.isExcluded(unit) + && unit.getParent().exists()) { + for (int i = 0; i < fResultElements.length; i++) { + delta.added(fResultElements[i]); + } + addDelta(delta); + } // else unit is created outside classpath + // non-java resource delta will be notified by delta processor + } + } finally { + done(); + } + } + /** + * Returns a JDOM document fragment for the element being created. + */ + protected abstract IDOMNode generateElementDOM() throws JavaModelException; + /** + * Returns the DOM with the new source to use for the given compilation unit. + */ + protected void generateNewCompilationUnitDOM(ICompilationUnit cu) throws JavaModelException { + IBuffer buffer = cu.getBuffer(); + if (buffer == null) return; + char[] prevSource = buffer.getCharacters(); + if (prevSource == null) return; + + // create a JDOM for the compilation unit + fCUDOM = (new DOMFactory()).createCompilationUnit(prevSource, cu.getElementName()); + IDOMNode child = generateElementDOM(); + if (child != null) { + insertDOMNode(fCUDOM, child); + } + worked(1); + } + /** + * Creates and returns the handle for the element this operation created. + */ + protected abstract IJavaElement generateResultHandle(); + /** + * Creates and returns the handles for the elements this operation created. + */ + protected IJavaElement[] generateResultHandles() throws JavaModelException { + return new IJavaElement[]{generateResultHandle()}; + } + /** + * Returns the compilation unit in which the new element is being created. + */ + protected ICompilationUnit getCompilationUnit() { + return getCompilationUnitFor(getParentElement()); + } + /** + * Returns the amount of work for the main task of this operation for + * progress reporting. + */ + protected int getMainAmountOfWork(){ + return 2; + } + /** + * Returns the name of the main task of this operation for + * progress reporting. + */ + public abstract String getMainTaskName(); + /** + * Returns the elements created by this operation. + */ + public IJavaElement[] getResultElements() { + return fResultElements; + } + /** + * Sets the default position in which to create the new type + * member. By default, the new element is positioned as the + * last child of the parent element in which it is created. + * Operations that require a different default position must + * override this method. + */ + protected void initializeDefaultPosition() { + + } + /** + * Inserts the given child into the given JDOM, + * based on the position settings of this operation. + * + * @see createAfter(IJavaElement) + * @see createBefore(IJavaElement); + */ + protected void insertDOMNode(IDOMNode parent, IDOMNode child) { + if (fInsertionPolicy != INSERT_LAST) { + IDOMNode sibling = ((JavaElement)fAnchorElement).findNode(fCUDOM); + if (sibling != null && fInsertionPolicy == INSERT_AFTER) { + sibling = sibling.getNextNode(); + } + if (sibling != null) { + sibling.insertSibling(child); + fCreatedElement = (DOMNode)child; + fInsertionPosition = ((DOMNode)sibling).getStartPosition(); + fReplacementLength = 0; + return; + } + } + //add as the last element of the parent + parent.addChild(child); + fCreatedElement = (DOMNode)child; + fInsertionPosition = ((DOMNode)parent).getInsertionPosition(); + // fInsertionPosition = lastChild == null ? ((DOMNode)parent).getInsertionPosition() : lastChild.getInsertionPosition(); + fReplacementLength = parent.getParent() == null ? -1 : 0; + } + /** + * Sets the name of the DOMNode that will be used to + * create this new element. + * Used by the CopyElementsOperation for renaming. + * Only used for CreateTypeMemberOperation + */ + protected void setAlteredName(String newName) { + } + /** + * Instructs this operation to position the new element relative + * to the given sibling, or to add the new element as the last child + * of its parent if null. The position + * must be one of the position constants. + */ + protected void setRelativePosition(IJavaElement sibling, int policy) throws IllegalArgumentException { + if (sibling == null) { + fAnchorElement = null; + fInsertionPolicy = INSERT_LAST; + } else { + fAnchorElement = sibling; + fInsertionPolicy = policy; + } + } + /** + * Possible failures:

        + *
      • NO_ELEMENTS_TO_PROCESS - the compilation unit supplied to the operation is + * null. + *
      • INVALID_NAME - no name, a name was null or not a valid + * import declaration name. + *
      • INVALID_SIBLING - the sibling provided for positioning is not valid. + *
      + * @see IJavaModelStatus + * @see JavaConventions + */ + public IJavaModelStatus verify() { + if (getParentElement() == null) { + return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS); + } + if (fAnchorElement != null) { + IJavaElement domPresentParent = fAnchorElement.getParent(); + if (domPresentParent.getElementType() == IJavaElement.IMPORT_CONTAINER) { + domPresentParent = domPresentParent.getParent(); + } + if (!domPresentParent.equals(getParentElement())) { + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_SIBLING, fAnchorElement); + } + } + return JavaModelStatus.VERIFIED_OK; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CreatePackageDeclarationOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CreatePackageDeclarationOperation.java new file mode 100644 index 0000000..7fe944b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CreatePackageDeclarationOperation.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelStatus; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; +import net.sourceforge.phpdt.core.IPackageDeclaration; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.jdom.DOMFactory; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.core.jdom.IDOMPackage; +import net.sourceforge.phpdt.internal.core.jdom.DOMNode; + +import org.eclipse.core.runtime.IStatus; + +/** + *

      This operation adds/replaces a package declaration in an existing compilation unit. + * If the compilation unit already includes the specified package declaration, + * it is not generated (it does not generate duplicates). + * + *

      Required Attributes:

        + *
      • Compilation unit element + *
      • Package name + *
      + */ +public class CreatePackageDeclarationOperation extends CreateElementInCUOperation { + /** + * The name of the package declaration being created + */ + protected String fName = null; +/** + * When executed, this operation will add a package declaration to the given compilation unit. + */ +public CreatePackageDeclarationOperation(String name, ICompilationUnit parentElement) { + super(parentElement); + fName= name; +} +/** + * @see CreateTypeMemberOperation#generateElementDOM + */ +protected IDOMNode generateElementDOM() throws JavaModelException { + IJavaElement[] children = getCompilationUnit().getChildren(); + //look for an existing package declaration + for (int i = 0; i < children.length; i++) { + if (children[i].getElementType() == IJavaElement.PACKAGE_DECLARATION) { + IPackageDeclaration pck = (IPackageDeclaration) children[i]; + IDOMPackage pack = (IDOMPackage) ((JavaElement)pck).findNode(fCUDOM); + if (!pack.getName().equals(fName)) { + // get the insertion position before setting the name, as this makes it a detailed node + // thus the start position is always 0 + DOMNode node = (DOMNode)pack; + fInsertionPosition = node.getStartPosition(); + fReplacementLength = node.getEndPosition() - fInsertionPosition + 1; + pack.setName(fName); + fCreatedElement = (net.sourceforge.phpdt.internal.core.jdom.DOMNode)pack; + } else { + //equivalent package declaration already exists + fCreationOccurred= false; + } + + return null; + } + } + IDOMPackage pack = (new DOMFactory()).createPackage(); + pack.setName(fName); + return pack; +} +/** + * Creates and returns the handle for the element this operation created. + */ +protected IJavaElement generateResultHandle() { + return getCompilationUnit().getPackageDeclaration(fName); +} +/** + * @see CreateElementInCUOperation#getMainTaskName() + */ +public String getMainTaskName(){ + return Util.bind("operation.createPackageProgress"); //$NON-NLS-1$ +} +/** + * Sets the correct position for new package declaration:
        + *
      • before the first import + *
      • if no imports, before the first type + *
      • if no type - first thing in the CU + *
      • + */ +protected void initializeDefaultPosition() { + try { + ICompilationUnit cu = getCompilationUnit(); +// IImportDeclaration[] imports = cu.getImports(); +// if (imports.length > 0) { +// createBefore(imports[0]); +// return; +// } + IType[] types = cu.getTypes(); + if (types.length > 0) { + createBefore(types[0]); + return; + } + } catch (JavaModelException npe) { + } +} +/** + * Possible failures:
          + *
        • NO_ELEMENTS_TO_PROCESS - no compilation unit was supplied to the operation + *
        • INVALID_NAME - a name supplied to the operation was not a valid + * package declaration name. + *
        + * @see IJavaModelStatus + * @see JavaConventions + */ +public IJavaModelStatus verify() { + IJavaModelStatus status = super.verify(); + if (!status.isOK()) { + return status; + } +// if (JavaConventions.validatePackageName(fName).getSeverity() == IStatus.ERROR) { +// return new JavaModelStatus(IJavaModelStatusConstants.INVALID_NAME, fName); +// } + return JavaModelStatus.VERIFIED_OK; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CreateWorkingCopyOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CreateWorkingCopyOperation.java new file mode 100644 index 0000000..78d052f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CreateWorkingCopyOperation.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.util.Map; + +import net.sourceforge.phpdt.core.IBufferFactory; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IProblemRequestor; +import net.sourceforge.phpdt.core.JavaModelException; + + + +/** + * Creates a new working copy and signal its addition through a delta. + */ +public class CreateWorkingCopyOperation extends JavaModelOperation { + + Map perFactoryWorkingCopies; + IBufferFactory factory; + IProblemRequestor problemRequestor; + + /* + * Creates a working copy from the given original cu and the given buffer factory. + * perFactoryWorkingCopies map is not null if the working copy is a shared working copy. + */ + public CreateWorkingCopyOperation(ICompilationUnit originalElement, Map perFactoryWorkingCopies, IBufferFactory factory, IProblemRequestor problemRequestor) { + super(new IJavaElement[] {originalElement}); + this.perFactoryWorkingCopies = perFactoryWorkingCopies; + this.factory = factory; + this.problemRequestor = problemRequestor; + } + protected void executeOperation() throws JavaModelException { + ICompilationUnit cu = getCompilationUnit(); + + WorkingCopy workingCopy = new WorkingCopy((IPackageFragment)cu.getParent(), cu.getElementName(), this.factory, this.problemRequestor); + // open the working copy now to ensure contents are that of the current state of this element + workingCopy.open(this.fMonitor); + + if (this.perFactoryWorkingCopies != null) { + this.perFactoryWorkingCopies.put(cu, workingCopy); + if (CompilationUnit.SHARED_WC_VERBOSE) { + System.out.println("Creating shared working copy " + workingCopy.toStringWithAncestors()); //$NON-NLS-1$ + } + } + + // report added java delta + JavaElementDelta delta = new JavaElementDelta(this.getJavaModel()); + delta.added(workingCopy); + addDelta(delta); + + fResultElements = new IJavaElement[] {workingCopy}; + } + /** + * Returns the compilation unit this operation is working on. + */ + protected ICompilationUnit getCompilationUnit() { + return (ICompilationUnit)getElementToProcess(); + } + /** + * @see JavaModelOperation#isReadOnly + */ + public boolean isReadOnly() { + return true; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeleteElementsOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeleteElementsOperation.java new file mode 100644 index 0000000..b79a550 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeleteElementsOperation.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import net.sourceforge.phpdt.core.IBuffer; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; +import net.sourceforge.phpdt.core.IRegion; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.core.jdom.DOMFactory; +import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit; +import net.sourceforge.phpdt.internal.core.jdom.DOMNode; +import net.sourceforge.phpdt.internal.corext.Assert; + +/** + * This operation deletes a collection of elements (and + * all of their children). + * If an element does not exist, it is ignored. + * + *

        NOTE: This operation only deletes elements contained within leaf resources - + * that is, elements within compilation units. To delete a compilation unit or + * a package, etc (which have an actual resource), a DeleteResourcesOperation + * should be used. + */ +public class DeleteElementsOperation extends MultiOperation { + /** + * The elements this operation processes grouped by compilation unit + * @see processElements(). Keys are compilation units, + * values are IRegions of elements to be processed in each + * compilation unit. + */ + protected Map fChildrenToRemove; + /** + * The DOMFactory used to manipulate the source code of + * ICompilationUnits. + */ + protected DOMFactory fFactory; + /** + * When executed, this operation will delete the given elements. The elements + * to delete cannot be null or empty, and must be contained within a + * compilation unit. + */ + public DeleteElementsOperation(IJavaElement[] elementsToDelete, boolean force) { + super(elementsToDelete, force); + fFactory = new DOMFactory(); + } + + /** + * @see MultiOperation + */ + protected String getMainTaskName() { + return Util.bind("operation.deleteElementProgress"); //$NON-NLS-1$ + } + /** + * Groups the elements to be processed by their compilation unit. + * If parent/child combinations are present, children are + * discarded (only the parents are processed). Removes any + * duplicates specified in elements to be processed. + */ + protected void groupElements() throws JavaModelException { + fChildrenToRemove = new HashMap(1); + int uniqueCUs = 0; + for (int i = 0, length = fElementsToProcess.length; i < length; i++) { + IJavaElement e = fElementsToProcess[i]; + ICompilationUnit cu = getCompilationUnitFor(e); + if (cu == null) { + throw new JavaModelException(new JavaModelStatus(JavaModelStatus.READ_ONLY, e)); + } else { + IRegion region = (IRegion) fChildrenToRemove.get(cu); + if (region == null) { + region = new Region(); + fChildrenToRemove.put(cu, region); + uniqueCUs += 1; + } + region.add(e); + } + } + fElementsToProcess = new IJavaElement[uniqueCUs]; + Iterator iter = fChildrenToRemove.keySet().iterator(); + int i = 0; + while (iter.hasNext()) { + fElementsToProcess[i++] = (IJavaElement) iter.next(); + } + } + /** + * Deletes this element from its compilation unit. + * @see MultiOperation + */ + protected void processElement(IJavaElement element) throws JavaModelException { + ICompilationUnit cu = (ICompilationUnit) element; + + // keep track of the import statements - if all are removed, delete + // the import container (and report it in the delta) +// int numberOfImports = cu.getImports().length; + + IBuffer buffer = cu.getBuffer(); + if (buffer == null) return; + JavaElementDelta delta = new JavaElementDelta(cu); + IJavaElement[] cuElements = ((IRegion) fChildrenToRemove.get(cu)).getElements(); + for (int i = 0, length = cuElements.length; i < length; i++) { + IJavaElement e = cuElements[i]; + if (e.exists()) { + char[] contents = buffer.getCharacters(); + if (contents == null) continue; + IDOMCompilationUnit cuDOM = fFactory.createCompilationUnit(contents, cu.getElementName()); + DOMNode node = (DOMNode)((JavaElement) e).findNode(cuDOM); + if (node == null) Assert.isTrue(false, "Failed to locate " + e.getElementName() + " in " + cuDOM.getName()); //$NON-NLS-1$//$NON-NLS-2$ + + int startPosition = node.getStartPosition(); + buffer.replace(startPosition, node.getEndPosition() - startPosition + 1, CharOperation.NO_CHAR); + delta.removed(e); +// if (e.getElementType() == IJavaElement.IMPORT_DECLARATION) { +// numberOfImports--; +// if (numberOfImports == 0) { +// delta.removed(cu.getImportContainer()); +// } +// } + } + } + if (delta.getAffectedChildren().length > 0) { + cu.save(getSubProgressMonitor(1), fForce); + if (!cu.isWorkingCopy()) { // if unit is working copy, then save will have already fired the delta + addDelta(delta); + this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); + } + } + } + /** + * @see MultiOperation + * This method first group the elements by ICompilationUnit, + * and then processes the ICompilationUnit. + */ + protected void processElements() throws JavaModelException { + groupElements(); + super.processElements(); + } + /** + * @see MultiOperation + */ + protected void verify(IJavaElement element) throws JavaModelException { + IJavaElement[] children = ((IRegion) fChildrenToRemove.get(element)).getElements(); + for (int i = 0; i < children.length; i++) { + IJavaElement child = children[i]; + if (child.getCorrespondingResource() != null) + error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, child); + if (child.isReadOnly()) + error(IJavaModelStatusConstants.READ_ONLY, child); + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeleteResourceElementsOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeleteResourceElementsOperation.java new file mode 100644 index 0000000..e8c5128 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeleteResourceElementsOperation.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IOpenable; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.JavaModelException; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; + +/** + * This operation deletes a collection of resources and all of their children. + * It does not delete resources which do not belong to the Java Model + * (eg GIF files). + */ +public class DeleteResourceElementsOperation extends MultiOperation { +/** + * When executed, this operation will delete the given elements. The elements + * to delete cannot be null or empty, and must have a corresponding + * resource. + */ +protected DeleteResourceElementsOperation(IJavaElement[] elementsToProcess, boolean force) { + super(elementsToProcess, force); +} +/** + * Deletes the direct children of frag corresponding to its kind + * (K_SOURCE or K_BINARY), and deletes the corresponding folder if it is then + * empty. + */ +private void deletePackageFragment(IPackageFragment frag) + throws JavaModelException { + IResource res = frag.getResource(); + if (res != null && res.getType() == IResource.FOLDER) { + // collect the children to remove + IJavaElement[] childrenOfInterest = frag.getChildren(); + if (childrenOfInterest.length > 0) { + IResource[] resources = new IResource[childrenOfInterest.length]; + // remove the children + for (int i = 0; i < childrenOfInterest.length; i++) { + resources[i] = childrenOfInterest[i].getCorrespondingResource(); + } + deleteResources(resources, fForce); + } + + // Discard non-java resources +// Object[] nonJavaResources = frag.getNonJavaResources(); +// int actualResourceCount = 0; +// for (int i = 0, max = nonJavaResources.length; i < max; i++){ +// if (nonJavaResources[i] instanceof IResource) actualResourceCount++; +// } +// IResource[] actualNonJavaResources = new IResource[actualResourceCount]; +// for (int i = 0, max = nonJavaResources.length, index = 0; i < max; i++){ +// if (nonJavaResources[i] instanceof IResource) actualNonJavaResources[index++] = (IResource)nonJavaResources[i]; +// } +// deleteResources(actualNonJavaResources, fForce); + + // delete remaining files in this package (.class file in the case where Proj=src=bin) + IResource[] remainingFiles; + try { + remainingFiles = ((IFolder) res).members(); + } catch (CoreException ce) { + throw new JavaModelException(ce); + } + boolean isEmpty = true; + for (int i = 0, length = remainingFiles.length; i < length; i++) { + IResource file = remainingFiles[i]; + if (file instanceof IFile) { + this.deleteResource(file, IResource.FORCE | IResource.KEEP_HISTORY); + } else { + isEmpty = false; + } + } + if (isEmpty) { + // delete recursively empty folders + IResource fragResource = frag.getResource(); + if (fragResource != null) { + deleteEmptyPackageFragment(frag, false, fragResource.getParent()); + } + } + } +} +/** + * @see MultiOperation + */ +protected String getMainTaskName() { + return Util.bind("operation.deleteResourceProgress"); //$NON-NLS-1$ +} +/** + * @see MultiOperation. This method delegate to deleteResource or + * deletePackageFragment depending on the type of element. + */ +protected void processElement(IJavaElement element) throws JavaModelException { + switch (element.getElementType()) { + case IJavaElement.CLASS_FILE : + case IJavaElement.COMPILATION_UNIT : + deleteResource(element.getResource(), fForce ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY); + break; + case IJavaElement.PACKAGE_FRAGMENT : + deletePackageFragment((IPackageFragment) element); + break; + default : + throw new JavaModelException(new JavaModelStatus(JavaModelStatus.INVALID_ELEMENT_TYPES, element)); + } + // ensure the element is closed + if (element instanceof IOpenable) { + ((IOpenable)element).close(); + } +} +/** + * @see MultiOperation + */ +protected void verify(IJavaElement element) throws JavaModelException { + if (element == null || !element.exists()) + error(JavaModelStatus.ELEMENT_DOES_NOT_EXIST, element); + + int type = element.getElementType(); + if (type <= IJavaElement.PACKAGE_FRAGMENT_ROOT || type > IJavaElement.COMPILATION_UNIT) + error(JavaModelStatus.INVALID_ELEMENT_TYPES, element); +// else if (type == IJavaElement.PACKAGE_FRAGMENT && element instanceof JarPackageFragment) +// error(JavaModelStatus.INVALID_ELEMENT_TYPES, element); + IResource resource = element.getResource(); + if (resource instanceof IFolder) { + if (resource.isLinked()) { + error(JavaModelStatus.INVALID_RESOURCE, element); + } + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeltaProcessor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeltaProcessor.java index ac3dd0f..45ffede 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeltaProcessor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeltaProcessor.java @@ -17,11 +17,14 @@ import java.util.HashSet; import java.util.Map; import net.sourceforge.phpdt.core.ElementChangedEvent; +import net.sourceforge.phpdt.core.IClasspathEntry; import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModel; import net.sourceforge.phpdt.core.IJavaProject; -import net.sourceforge.phpdt.core.JavaCore; import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil; +import net.sourceforge.phpeclipse.PHPCore; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -31,8 +34,10 @@ import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.QualifiedName; /** @@ -224,7 +229,7 @@ public class DeltaProcessor implements IResourceChangeListener { * to update. */ void addToProjectsToUpdateWithDependents(IProject project) { - this.projectsToUpdate.add(JavaCore.create(project)); + this.projectsToUpdate.add(PHPCore.create(project)); // this.addDependentProjects(project.getFullPath(), this.projectsToUpdate); } @@ -1061,75 +1066,75 @@ public class DeltaProcessor implements IResourceChangeListener { return file.lastModified() + file.length(); } -// public void initializeRoots() { -// // remember roots infos as old roots infos -// this.oldRoots = this.roots == null ? new HashMap() : this.roots; -// this.oldOtherRoots = this.otherRoots == null ? new HashMap() : this.otherRoots; -// -// // recompute root infos only if necessary -// if (!rootsAreStale) return; -// -// this.roots = new HashMap(); -// this.otherRoots = new HashMap(); -// this.sourceAttachments = new HashMap(); -// -// IJavaModel model = this.manager.getJavaModel(); -// IJavaProject[] projects; -// try { -// projects = model.getJavaProjects(); -// } catch (JavaModelException e) { -// // nothing can be done -// return; -// } -// for (int i = 0, length = projects.length; i < length; i++) { -// IJavaProject project = projects[i]; -// IClasspathEntry[] classpath; -// try { -// classpath = project.getResolvedClasspath(true); -// } catch (JavaModelException e) { -// // continue with next project -// continue; -// } -// for (int j= 0, classpathLength = classpath.length; j < classpathLength; j++) { -// IClasspathEntry entry = classpath[j]; -// if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) continue; -// - // root path -// IPath path = entry.getPath(); -// if (this.roots.get(path) == null) { -// this.roots.put(path, new RootInfo(project, path, ((ClasspathEntry)entry).fullExclusionPatternChars())); -// } else { -// ArrayList rootList = (ArrayList)this.otherRoots.get(path); -// if (rootList == null) { -// rootList = new ArrayList(); -// this.otherRoots.put(path, rootList); -// } -// rootList.add(new RootInfo(project, path, ((ClasspathEntry)entry).fullExclusionPatternChars())); -// } -// -// // source attachment path -// if (entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY) continue; -// QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "sourceattachment: " + path.toOSString()); //$NON-NLS-1$; -// String propertyString = null; -// try { -// propertyString = ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName); -// } catch (CoreException e) { -// continue; -// } -// IPath sourceAttachmentPath; + public void initializeRoots() { + // remember roots infos as old roots infos + this.oldRoots = this.roots == null ? new HashMap() : this.roots; + this.oldOtherRoots = this.otherRoots == null ? new HashMap() : this.otherRoots; + + // recompute root infos only if necessary + if (!rootsAreStale) return; + + this.roots = new HashMap(); + this.otherRoots = new HashMap(); + this.sourceAttachments = new HashMap(); + + IJavaModel model = this.manager.getJavaModel(); + IJavaProject[] projects; + try { + projects = model.getJavaProjects(); + } catch (JavaModelException e) { + // nothing can be done + return; + } + for (int i = 0, length = projects.length; i < length; i++) { + IJavaProject project = projects[i]; + IClasspathEntry[] classpath; + try { + classpath = project.getResolvedClasspath(true); + } catch (JavaModelException e) { + // continue with next project + continue; + } + for (int j= 0, classpathLength = classpath.length; j < classpathLength; j++) { + IClasspathEntry entry = classpath[j]; + if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) continue; + +// root path + IPath path = entry.getPath(); + if (this.roots.get(path) == null) { + this.roots.put(path, new RootInfo(project, path, ((ClasspathEntry)entry).fullExclusionPatternChars())); + } else { + ArrayList rootList = (ArrayList)this.otherRoots.get(path); + if (rootList == null) { + rootList = new ArrayList(); + this.otherRoots.put(path, rootList); + } + rootList.add(new RootInfo(project, path, ((ClasspathEntry)entry).fullExclusionPatternChars())); + } + + // source attachment path + if (entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY) continue; + QualifiedName qName = new QualifiedName(PHPCore.PLUGIN_ID, "sourceattachment: " + path.toOSString()); //$NON-NLS-1$; + String propertyString = null; + try { + propertyString = ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName); + } catch (CoreException e) { + continue; + } + IPath sourceAttachmentPath; // if (propertyString != null) { // int index= propertyString.lastIndexOf(JarPackageFragmentRoot.ATTACHMENT_PROPERTY_DELIMITER); // sourceAttachmentPath = (index < 0) ? new Path(propertyString) : new Path(propertyString.substring(0, index)); // } else { -// sourceAttachmentPath = entry.getSourceAttachmentPath(); -// } -// if (sourceAttachmentPath != null) { -// this.sourceAttachments.put(sourceAttachmentPath, path); + sourceAttachmentPath = entry.getSourceAttachmentPath(); // } -// } -// } -// this.rootsAreStale = false; -// } + if (sourceAttachmentPath != null) { + this.sourceAttachments.put(sourceAttachmentPath, path); + } + } + } + this.rootsAreStale = false; + } /* * Returns whether a given delta contains some information relevant to the JavaModel, @@ -1664,7 +1669,7 @@ public class DeltaProcessor implements IResourceChangeListener { case IResourceChangeEvent.PRE_DELETE : try { if(resource.getType() == IResource.PROJECT - && ((IProject) resource).hasNature(JavaCore.NATURE_ID)) { + && ((IProject) resource).hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) { // TODO khartlage temp-del // this.deleting((IProject)resource); } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DestroyWorkingCopyOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DestroyWorkingCopyOperation.java new file mode 100644 index 0000000..bf5e827 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DestroyWorkingCopyOperation.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.util.Map; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.JavaModelException; + + +/** + * Destroys a working copy (remove it from its cache if it is shared) + * and signal its removal through a delta. + */ +public class DestroyWorkingCopyOperation extends JavaModelOperation { + + public DestroyWorkingCopyOperation(IJavaElement workingCopy) { + super(new IJavaElement[] {workingCopy}); + } + /** + * @exception JavaModelException if setting the source + * of the original compilation unit fails + */ + protected void executeOperation() throws JavaModelException { + WorkingCopy workingCopy = getWorkingCopy(); + workingCopy.close(); + + // if original element is not on classpath flush it from the cache + IJavaElement originalElement = workingCopy.getOriginalElement(); + if (!workingCopy.getParent().exists()) { + ((CompilationUnit)originalElement).close(); + } + + // remove working copy from the cache if it is shared + JavaModelManager manager = JavaModelManager.getJavaModelManager(); + + // In order to be shared, working copies have to denote the same compilation unit + // AND use the same buffer factory. + // Assuming there is a little set of buffer factories, then use a 2 level Map cache. + Map sharedWorkingCopies = manager.sharedWorkingCopies; + + Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(workingCopy.bufferFactory); + if (perFactoryWorkingCopies != null){ + if (perFactoryWorkingCopies.remove(originalElement) != null + && CompilationUnit.SHARED_WC_VERBOSE) { + System.out.println("Destroying shared working copy " + workingCopy.toStringWithAncestors());//$NON-NLS-1$ + } + } + + // report removed java delta + JavaElementDelta delta = new JavaElementDelta(this.getJavaModel()); + delta.removed(workingCopy); + addDelta(delta); + removeReconcileDelta(workingCopy); + } + /** + * Returns the working copy this operation is working on. + */ + protected WorkingCopy getWorkingCopy() { + return (WorkingCopy)getElementToProcess(); + } + /** + * @see JavaModelOperation#isReadOnly + */ + public boolean isReadOnly() { + return true; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/ElementCache.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/ElementCache.java new file mode 100644 index 0000000..2f990d7 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/ElementCache.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.IOpenable; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.core.util.LRUCache; + +/** + * An LRU cache of JavaElements. + */ +public class ElementCache extends OverflowingLRUCache { +/** + * Constructs a new element cache of the given size. + */ +public ElementCache(int size) { + super(size); +} +/** + * Constructs a new element cache of the given size. + */ +public ElementCache(int size, int overflow) { + super(size, overflow); +} +/** + * Returns true if the element is successfully closed and + * removed from the cache, otherwise false. + * + *

        NOTE: this triggers an external removal of this element + * by closing the element. + */ +protected boolean close(LRUCacheEntry entry) { + IOpenable element = (IOpenable) entry._fKey; + try { + if (element.hasUnsavedChanges()) { + return false; + } else { + // We must close an entire JarPackageFragmentRoot at once. +// if (element instanceof JarPackageFragment) { +// JarPackageFragment packageFragment= (JarPackageFragment) element; +// JarPackageFragmentRoot root = (JarPackageFragmentRoot) packageFragment.getParent(); +// root.close(); +// } else { + element.close(); +// } + return true; + } + } catch (JavaModelException npe) { + return false; + } +} + /** + * Returns a new instance of the reciever. + */ + protected LRUCache newInstance(int size, int overflow) { + return new ElementCache(size, overflow); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/IJavaElementRequestor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/IJavaElementRequestor.java new file mode 100644 index 0000000..79f5725 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/IJavaElementRequestor.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.IField; +import net.sourceforge.phpdt.core.IMethod; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IType; + +/** + * This interface is used by IRequestorNameLookup. As results + * are found by IRequestorNameLookup, they are reported to this + * interface. An IJavaElementRequestor is able to cancel + * at any time (that is, stop receiving results), by responding + * true to #isCancelled. + */ +public interface IJavaElementRequestor { +public void acceptField(IField field); +//public void acceptInitializer(IInitializer initializer); +public void acceptMemberType(IType type); +public void acceptMethod(IMethod method); +public void acceptPackageFragment(IPackageFragment packageFragment); +public void acceptType(IType type); +/** + * Returns true if this IJavaElementRequestor does + * not want to receive any more results. + */ +boolean isCanceled(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaElement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaElement.java index c45befb..a55c97a 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaElement.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaElement.java @@ -18,8 +18,18 @@ import net.sourceforge.phpdt.core.IJavaModel; import net.sourceforge.phpdt.core.IJavaModelStatusConstants; import net.sourceforge.phpdt.core.IJavaProject; import net.sourceforge.phpdt.core.IOpenable; +import net.sourceforge.phpdt.core.IParent; +import net.sourceforge.phpdt.core.ISourceRange; +import net.sourceforge.phpdt.core.ISourceReference; import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.internal.corext.Assert; +import org.eclipse.core.resources.IResourceStatus; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.PlatformObject; @@ -94,34 +104,34 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement /** * @see IOpenable */ -// public void close() throws JavaModelException { -// Object info = JavaModelManager.getJavaModelManager().peekAtInfo(this); -// if (info != null) { -// boolean wasVerbose = false; -// try { -// if (JavaModelManager.VERBOSE) { -// System.out.println("CLOSING Element ("+ Thread.currentThread()+"): " + this.toStringWithAncestors()); //$NON-NLS-1$//$NON-NLS-2$ -// wasVerbose = true; -// JavaModelManager.VERBOSE = false; -// } -// if (this instanceof IParent) { -// IJavaElement[] children = ((JavaElementInfo) info).getChildren(); -// for (int i = 0, size = children.length; i < size; ++i) { -// JavaElement child = (JavaElement) children[i]; -// child.close(); -// } -// } -// closing(info); -// JavaModelManager.getJavaModelManager().removeInfo(this); -// if (wasVerbose) { -// System.out.println("-> Package cache size = " + JavaModelManager.getJavaModelManager().cache.pkgSize()); //$NON-NLS-1$ -// System.out.println("-> Openable cache filling ratio = " + JavaModelManager.getJavaModelManager().cache.openableFillingRatio() + "%"); //$NON-NLS-1$//$NON-NLS-2$ -// } -// } finally { -// JavaModelManager.VERBOSE = wasVerbose; -// } -// } -// } + public void close() throws JavaModelException { + Object info = JavaModelManager.getJavaModelManager().peekAtInfo(this); + if (info != null) { + boolean wasVerbose = false; + try { + if (JavaModelManager.VERBOSE) { + System.out.println("CLOSING Element ("+ Thread.currentThread()+"): " + this.toStringWithAncestors()); //$NON-NLS-1$//$NON-NLS-2$ + wasVerbose = true; + JavaModelManager.VERBOSE = false; + } + if (this instanceof IParent) { + IJavaElement[] children = ((JavaElementInfo) info).getChildren(); + for (int i = 0, size = children.length; i < size; ++i) { + JavaElement child = (JavaElement) children[i]; + child.close(); + } + } + closing(info); + JavaModelManager.getJavaModelManager().removeInfo(this); + if (wasVerbose) { + System.out.println("-> Package cache size = " + JavaModelManager.getJavaModelManager().cache.pkgSize()); //$NON-NLS-1$ + System.out.println("-> Openable cache filling ratio = " + JavaModelManager.getJavaModelManager().cache.openableFillingRatio() + "%"); //$NON-NLS-1$//$NON-NLS-2$ + } + } finally { + JavaModelManager.VERBOSE = wasVerbose; + } + } + } /** * This element is being closed. Do any necessary cleanup. */ @@ -159,9 +169,9 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement * Returns true if this JavaElement is equivalent to the given * IDOMNode. */ -// protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException { -// return false; -// } + protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException { + return false; + } /** * @see IJavaElement */ @@ -179,66 +189,66 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement * Returns the IDOMNode that corresponds to this JavaElement * or null if there is no corresponding node. */ -// public IDOMNode findNode(IDOMCompilationUnit dom) { -// int type = getElementType(); -// if (type == IJavaElement.COMPILATION_UNIT || -// type == IJavaElement.FIELD || -// type == IJavaElement.IMPORT_DECLARATION || -// type == IJavaElement.INITIALIZER || -// type == IJavaElement.METHOD || -// type == IJavaElement.PACKAGE_DECLARATION || -// type == IJavaElement.TYPE) { -// ArrayList path = new ArrayList(); -// IJavaElement element = this; -// while (element != null && element.getElementType() != IJavaElement.COMPILATION_UNIT) { -// if (element.getElementType() != IJavaElement.IMPORT_CONTAINER) { -// // the DOM does not have import containers, so skip them -// path.add(0, element); -// } -// element = element.getParent(); -// } -// if (path.size() == 0) { -// try { -// if (equalsDOMNode(dom)) { -// return dom; -// } else { -// return null; -// } -// } catch(JavaModelException e) { -// return null; -// } -// } -// return ((JavaElement) path.get(0)).followPath(path, 0, dom.getFirstChild()); -// } else { -// return null; -// } -// } -// /** -// */ -// protected IDOMNode followPath(ArrayList path, int position, IDOMNode node) { -// -// try { -// if (equalsDOMNode(node)) { -// if (position == (path.size() - 1)) { -// return node; -// } else { -// if (node.getFirstChild() != null) { -// position++; -// return ((JavaElement)path.get(position)).followPath(path, position, node.getFirstChild()); -// } else { -// return null; -// } -// } -// } else if (node.getNextNode() != null) { -// return followPath(path, position, node.getNextNode()); -// } else { -// return null; -// } -// } catch (JavaModelException e) { -// return null; -// } -// -// } + public IDOMNode findNode(IDOMCompilationUnit dom) { + int type = getElementType(); + if (type == IJavaElement.COMPILATION_UNIT || + type == IJavaElement.FIELD || + type == IJavaElement.IMPORT_DECLARATION || + type == IJavaElement.INITIALIZER || + type == IJavaElement.METHOD || + type == IJavaElement.PACKAGE_DECLARATION || + type == IJavaElement.TYPE) { + ArrayList path = new ArrayList(); + IJavaElement element = this; + while (element != null && element.getElementType() != IJavaElement.COMPILATION_UNIT) { + if (element.getElementType() != IJavaElement.IMPORT_CONTAINER) { + // the DOM does not have import containers, so skip them + path.add(0, element); + } + element = element.getParent(); + } + if (path.size() == 0) { + try { + if (equalsDOMNode(dom)) { + return dom; + } else { + return null; + } + } catch(JavaModelException e) { + return null; + } + } + return ((JavaElement) path.get(0)).followPath(path, 0, dom.getFirstChild()); + } else { + return null; + } + } + /** + */ + protected IDOMNode followPath(ArrayList path, int position, IDOMNode node) { + + try { + if (equalsDOMNode(node)) { + if (position == (path.size() - 1)) { + return node; + } else { + if (node.getFirstChild() != null) { + position++; + return ((JavaElement)path.get(position)).followPath(path, position, node.getFirstChild()); + } else { + return null; + } + } + } else if (node.getNextNode() != null) { + return followPath(path, position, node.getNextNode()); + } else { + return null; + } + } catch (JavaModelException e) { + return null; + } + + } /** * @see IJavaElement */ @@ -295,32 +305,31 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement * @exception JavaModelException if the element is not present or not accessible */ public Object getElementInfo() throws JavaModelException { -return null; // workaround to ensure parent project resolved classpath is available to avoid triggering initializers // while the JavaModelManager lock is acquired (can cause deadlocks in clients) -// IJavaProject project = getJavaProject(); -// if (project != null && !project.isOpen()) { -// // TODO: need to revisit, since deadlock could still occur if perProjectInfo is removed concurrent before entering the lock -// try { -// project.getResolvedClasspath(true); // trigger all possible container/variable initialization outside the model lock -// } catch (JavaModelException e) { -// // project is not accessible or is not a java project -// } -// } -// -// // element info creation is done inside a lock on the JavaModelManager -// JavaModelManager manager; -// synchronized(manager = JavaModelManager.getJavaModelManager()){ -// Object info = manager.getInfo(this); -// if (info == null) { -// openHierarchy(); -// info= manager.getInfo(this); -// if (info == null) { -// throw newNotPresentException(); -// } -// } -// return info; -// } + IJavaProject project = getJavaProject(); + if (project != null && !project.isOpen()) { + // TODO: need to revisit, since deadlock could still occur if perProjectInfo is removed concurrent before entering the lock + try { + project.getResolvedClasspath(true); // trigger all possible container/variable initialization outside the model lock + } catch (JavaModelException e) { + // project is not accessible or is not a java project + } + } + + // element info creation is done inside a lock on the JavaModelManager + JavaModelManager manager; + synchronized(manager = JavaModelManager.getJavaModelManager()){ + Object info = manager.getInfo(this); + if (info == null) { + openHierarchy(); + info= manager.getInfo(this); + if (info == null) { + throw newNotPresentException(); + } + } + return info; + } } /** * @see IAdaptable @@ -411,30 +420,30 @@ return null; * known to be within this element's source range already, and if no finer * grained element is found at the position, this element is returned. */ -// protected IJavaElement getSourceElementAt(int position) throws JavaModelException { -// if (this instanceof ISourceReference) { -// IJavaElement[] children = getChildren(); -// int i; -// for (i = 0; i < children.length; i++) { -// IJavaElement aChild = children[i]; -// if (aChild instanceof SourceRefElement) { -// SourceRefElement child = (SourceRefElement) children[i]; -// ISourceRange range = child.getSourceRange(); -// if (position < range.getOffset() + range.getLength() && position >= range.getOffset()) { -// if (child instanceof IParent) { -// return child.getSourceElementAt(position); -// } else { -// return child; -// } -// } -// } -// } -// } else { -// // should not happen -// Assert.isTrue(false); -// } -// return this; -// } + protected IJavaElement getSourceElementAt(int position) throws JavaModelException { + if (this instanceof ISourceReference) { + IJavaElement[] children = getChildren(); + int i; + for (i = 0; i < children.length; i++) { + IJavaElement aChild = children[i]; + if (aChild instanceof SourceRefElement) { + SourceRefElement child = (SourceRefElement) children[i]; + ISourceRange range = child.getSourceRange(); + if (position < range.getOffset() + range.getLength() && position >= range.getOffset()) { + if (child instanceof IParent) { + return child.getSourceElementAt(position); + } else { + return child; + } + } + } + } + } else { + // should not happen + Assert.isTrue(false); + } + return this; + } /** * Returns the SourceMapper facility for this element, or * null if this element does not have a @@ -475,35 +484,35 @@ return null; /** * @see IJavaElement */ -// public boolean isStructureKnown() throws JavaModelException { -// return ((JavaElementInfo)getElementInfo()).isStructureKnown(); -// } + public boolean isStructureKnown() throws JavaModelException { + return ((JavaElementInfo)getElementInfo()).isStructureKnown(); + } /** * Creates and returns and not present exception for this element. */ protected JavaModelException newNotPresentException() { return new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, this)); } -// /** -// * Opens this element and all parents that are not already open. -// * -// * @exception JavaModelException this element is not present or accessible -// */ -// protected void openHierarchy() throws JavaModelException { -// if (this instanceof IOpenable) { -// ((Openable) this).openWhenClosed(null); -// } else { -// Openable openableParent = (Openable)getOpenableParent(); -// if (openableParent != null) { -// JavaElementInfo openableParentInfo = (JavaElementInfo) JavaModelManager.getJavaModelManager().getInfo((IJavaElement) openableParent); -// if (openableParentInfo == null) { -// openableParent.openWhenClosed(null); -// } else { -// throw newNotPresentException(); -// } -// } -// } -// } + /** + * Opens this element and all parents that are not already open. + * + * @exception JavaModelException this element is not present or accessible + */ + protected void openHierarchy() throws JavaModelException { + if (this instanceof IOpenable) { + ((Openable) this).openWhenClosed(null); + } else { + Openable openableParent = (Openable)getOpenableParent(); + if (openableParent != null) { + JavaElementInfo openableParentInfo = (JavaElementInfo) JavaModelManager.getJavaModelManager().getInfo((IJavaElement) openableParent); + if (openableParentInfo == null) { + openableParent.openWhenClosed(null); + } else { + throw newNotPresentException(); + } + } + } + } /** * This element has just been opened. Do any necessary setup. */ @@ -518,48 +527,48 @@ return null; * Removes all cached info from the Java Model, including all children, * but does not close this element. */ -// protected void removeInfo() { -// Object info = JavaModelManager.getJavaModelManager().peekAtInfo(this); -// if (info != null) { -// if (this instanceof IParent) { -// IJavaElement[] children = ((JavaElementInfo)info).getChildren(); -// for (int i = 0, size = children.length; i < size; ++i) { -// JavaElement child = (JavaElement) children[i]; -// child.removeInfo(); -// } -// } -// JavaModelManager.getJavaModelManager().removeInfo(this); -// } -// } -// /** -// * Returns a copy of this element rooted at the given project. -// */ + protected void removeInfo() { + Object info = JavaModelManager.getJavaModelManager().peekAtInfo(this); + if (info != null) { + if (this instanceof IParent) { + IJavaElement[] children = ((JavaElementInfo)info).getChildren(); + for (int i = 0, size = children.length; i < size; ++i) { + JavaElement child = (JavaElement) children[i]; + child.removeInfo(); + } + } + JavaModelManager.getJavaModelManager().removeInfo(this); + } + } + /** + * Returns a copy of this element rooted at the given project. + */ public abstract IJavaElement rootedAt(IJavaProject project); -// /** -// * Runs a Java Model Operation -// */ -// public static void runOperation(JavaModelOperation operation, IProgressMonitor monitor) throws JavaModelException { -// try { -// if (operation.isReadOnly() || ResourcesPlugin.getWorkspace().isTreeLocked()) { -// operation.run(monitor); -// } else { -// // use IWorkspace.run(...) to ensure that a build will be done in autobuild mode -// ResourcesPlugin.getWorkspace().run(operation, monitor); -// } -// } catch (CoreException ce) { -// if (ce instanceof JavaModelException) { -// throw (JavaModelException)ce; -// } else { -// if (ce.getStatus().getCode() == IResourceStatus.OPERATION_FAILED) { -// Throwable e= ce.getStatus().getException(); -// if (e instanceof JavaModelException) { -// throw (JavaModelException) e; -// } -// } -// throw new JavaModelException(ce); -// } -// } -// } + /** + * Runs a Java Model Operation + */ + public static void runOperation(JavaModelOperation operation, IProgressMonitor monitor) throws JavaModelException { + try { + if (operation.isReadOnly() || ResourcesPlugin.getWorkspace().isTreeLocked()) { + operation.run(monitor); + } else { + // use IWorkspace.run(...) to ensure that a build will be done in autobuild mode + ResourcesPlugin.getWorkspace().run(operation, monitor); + } + } catch (CoreException ce) { + if (ce instanceof JavaModelException) { + throw (JavaModelException)ce; + } else { + if (ce.getStatus().getCode() == IResourceStatus.OPERATION_FAILED) { + Throwable e= ce.getStatus().getException(); + if (e instanceof JavaModelException) { + throw (JavaModelException) e; + } + } + throw new JavaModelException(ce); + } + } + } /** * Sets the occurrence count of the handle. */ diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaElementDeltaBuilder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaElementDeltaBuilder.java new file mode 100644 index 0000000..0376079 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaElementDeltaBuilder.java @@ -0,0 +1,409 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaElementDelta; +import net.sourceforge.phpdt.core.IParent; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.compiler.CharOperation; + + +/** + * A java element delta biulder creates a java element delta on + * a java element between the version of the java element + * at the time the comparator was created and the current version + * of the java element. + * + * It performs this operation by locally caching the contents of + * the java element when it is created. When the method + * createDeltas() is called, it creates a delta over the cached + * contents and the new contents. + */ +public class JavaElementDeltaBuilder { + /** + * The java element handle + */ + IJavaElement javaElement; + + /** + * The maximum depth in the java element children we should look into + */ + int maxDepth = Integer.MAX_VALUE; + + /** + * The old handle to info relationships + */ + Map infos; + + /** + * The old position info + */ + Map oldPositions; + + /** + * The new position info + */ + Map newPositions; + + /** + * Change delta + */ + JavaElementDelta delta; + + /** + * List of added elements + */ + ArrayList added; + + /** + * List of removed elements + */ + ArrayList removed; + + /** + * Doubly linked list item + */ + class ListItem { + public IJavaElement previous; + public IJavaElement next; + + public ListItem(IJavaElement previous, IJavaElement next) { + this.previous = previous; + this.next = next; + } + } +/** + * Creates a java element comparator on a java element + * looking as deep as necessary. + */ +public JavaElementDeltaBuilder(IJavaElement javaElement) { + this.javaElement = javaElement; + this.initialize(); + this.recordElementInfo( + javaElement, + (JavaModel)this.javaElement.getJavaModel(), + 0); +} +/** + * Creates a java element comparator on a java element + * looking only 'maxDepth' levels deep. + */ +public JavaElementDeltaBuilder(IJavaElement javaElement, int maxDepth) { + this.javaElement = javaElement; + this.maxDepth = maxDepth; + this.initialize(); + this.recordElementInfo( + javaElement, + (JavaModel)this.javaElement.getJavaModel(), + 0); +} +/** + * Repairs the positioning information + * after an element has been added + */ +private void added(IJavaElement element) { + this.added.add(element); + ListItem current = this.getNewPosition(element); + ListItem previous = null, next = null; + if (current.previous != null) + previous = this.getNewPosition(current.previous); + if (current.next != null) + next = this.getNewPosition(current.next); + if (previous != null) + previous.next = current.next; + if (next != null) + next.previous = current.previous; +} +/** + * Builds the java element deltas between the old content of the compilation + * unit and its new content. + */ +public void buildDeltas() { + this.recordNewPositions(this.javaElement, 0); + this.findAdditions(this.javaElement, 0); + this.findDeletions(); + this.findChangesInPositioning(this.javaElement, 0); + this.trimDelta(this.delta); + if (this.delta.getAffectedChildren().length == 0) { + // this is a fine grained but not children affected -> mark as content changed + this.delta.contentChanged(); + } +} +/** + * Finds elements which have been added or changed. + */ +private void findAdditions(IJavaElement newElement, int depth) { + JavaElementInfo oldInfo = this.getElementInfo(newElement); + if (oldInfo == null && depth < this.maxDepth) { + this.delta.added(newElement); + added(newElement); + } else { + this.removeElementInfo(newElement); + } + + if (depth >= this.maxDepth) { + // mark element as changed + this.delta.changed(newElement, IJavaElementDelta.F_CONTENT); + return; + } + + JavaElementInfo newInfo = null; + try { + newInfo = (JavaElementInfo)((JavaElement)newElement).getElementInfo(); + } catch (JavaModelException npe) { + return; + } + + this.findContentChange(oldInfo, newInfo, newElement); + + if (oldInfo != null && newElement instanceof IParent) { + + IJavaElement[] children = newInfo.getChildren(); + if (children != null) { + int length = children.length; + for(int i = 0; i < length; i++) { + this.findAdditions(children[i], depth + 1); + } + } + } +} +/** + * Looks for changed positioning of elements. + */ +private void findChangesInPositioning(IJavaElement element, int depth) { + if (depth >= this.maxDepth || this.added.contains(element) || this.removed.contains(element)) + return; + + if (!isPositionedCorrectly(element)) { + this.delta.changed(element, IJavaElementDelta.F_REORDER); + } + + if (element instanceof IParent) { + JavaElementInfo info = null; + try { + info = (JavaElementInfo)((JavaElement)element).getElementInfo(); + } catch (JavaModelException npe) { + return; + } + + IJavaElement[] children = info.getChildren(); + if (children != null) { + int length = children.length; + for(int i = 0; i < length; i++) { + this.findChangesInPositioning(children[i], depth + 1); + } + } + } +} +/** + * The elements are equivalent, but might have content changes. + */ +private void findContentChange(JavaElementInfo oldInfo, JavaElementInfo newInfo, IJavaElement newElement) { + if (oldInfo instanceof MemberElementInfo && newInfo instanceof MemberElementInfo) { + if (((MemberElementInfo)oldInfo).getModifiers() != ((MemberElementInfo)newInfo).getModifiers()) { + this.delta.changed(newElement, IJavaElementDelta.F_MODIFIERS); + } else if (oldInfo instanceof SourceMethodElementInfo && newInfo instanceof SourceMethodElementInfo) { + if (!CharOperation.equals( + ((SourceMethodElementInfo)oldInfo).getReturnTypeName(), + ((SourceMethodElementInfo)newInfo).getReturnTypeName())) { + this.delta.changed(newElement, IJavaElementDelta.F_CONTENT); + } + } else if (oldInfo instanceof SourceFieldElementInfo && newInfo instanceof SourceFieldElementInfo) { + if (!CharOperation.equals( + ((SourceFieldElementInfo)oldInfo).getTypeName(), + ((SourceFieldElementInfo)newInfo).getTypeName())) { + this.delta.changed(newElement, IJavaElementDelta.F_CONTENT); + } + } + } + if (oldInfo instanceof SourceTypeElementInfo && newInfo instanceof SourceTypeElementInfo) { + SourceTypeElementInfo oldSourceTypeInfo = (SourceTypeElementInfo)oldInfo; + SourceTypeElementInfo newSourceTypeInfo = (SourceTypeElementInfo)newInfo; + if (!CharOperation.equals(oldSourceTypeInfo.getSuperclassName(), newSourceTypeInfo.getSuperclassName()) + || !CharOperation.equals(oldSourceTypeInfo.getInterfaceNames(), newSourceTypeInfo.getInterfaceNames())) { + this.delta.changed(newElement, IJavaElementDelta.F_SUPER_TYPES); + } + } +} +/** + * Adds removed deltas for any handles left in the table + */ +private void findDeletions() { + Iterator iter = this.infos.keySet().iterator(); + while(iter.hasNext()) { + IJavaElement element = (IJavaElement)iter.next(); + this.delta.removed(element); + this.removed(element); + } +} +private JavaElementInfo getElementInfo(IJavaElement element) { + return (JavaElementInfo)this.infos.get(element); +} +private ListItem getNewPosition(IJavaElement element) { + return (ListItem)this.newPositions.get(element); +} +private ListItem getOldPosition(IJavaElement element) { + return (ListItem)this.oldPositions.get(element); +} +private void initialize() { + this.infos = new HashMap(20); + this.oldPositions = new HashMap(20); + this.newPositions = new HashMap(20); + this.putOldPosition(this.javaElement, new ListItem(null, null)); + this.putNewPosition(this.javaElement, new ListItem(null, null)); + this.delta = new JavaElementDelta(javaElement); + + // if building a delta on a compilation unit or below, + // it's a fine grained delta + if (javaElement.getElementType() >= IJavaElement.COMPILATION_UNIT) { + this.delta.fineGrained(); + } + + this.added = new ArrayList(5); + this.removed = new ArrayList(5); +} +/** + * Inserts position information for the elements into the new or old positions table + */ +private void insertPositions(IJavaElement[] elements, boolean isNew) { + int length = elements.length; + IJavaElement previous = null, current = null, next = (length > 0) ? elements[0] : null; + for(int i = 0; i < length; i++) { + previous = current; + current = next; + next = (i + 1 < length) ? elements[i + 1] : null; + if (isNew) { + this.putNewPosition(current, new ListItem(previous, next)); + } else { + this.putOldPosition(current, new ListItem(previous, next)); + } + } +} +/** + * Returns whether the elements position has not changed. + */ +private boolean isPositionedCorrectly(IJavaElement element) { + ListItem oldListItem = this.getOldPosition(element); + if (oldListItem == null) return false; + + ListItem newListItem = this.getNewPosition(element); + if (newListItem == null) return false; + + IJavaElement oldPrevious = oldListItem.previous; + IJavaElement newPrevious = newListItem.previous; + if (oldPrevious == null) { + return newPrevious == null; + } else { + return oldPrevious.equals(newPrevious); + } +} +private void putElementInfo(IJavaElement element, JavaElementInfo info) { + this.infos.put(element, info); +} +private void putNewPosition(IJavaElement element, ListItem position) { + this.newPositions.put(element, position); +} +private void putOldPosition(IJavaElement element, ListItem position) { + this.oldPositions.put(element, position); +} +/** + * Records this elements info, and attempts + * to record the info for the children. + */ +private void recordElementInfo(IJavaElement element, JavaModel model, int depth) { + if (depth >= this.maxDepth) { + return; + } + JavaElementInfo info = null;//(JavaElementInfo)JavaModelManager.getJavaModelManager().getInfo(element); + if (info == null) // no longer in the java model. + return; + this.putElementInfo(element, info); + + if (element instanceof IParent) { + IJavaElement[] children = info.getChildren(); + if (children != null) { + insertPositions(children, false); + for(int i = 0, length = children.length; i < length; i++) + recordElementInfo(children[i], model, depth + 1); + } + } +} +/** + * Fills the newPositions hashtable with the new position information + */ +private void recordNewPositions(IJavaElement newElement, int depth) { + if (depth < this.maxDepth && newElement instanceof IParent) { + JavaElementInfo info = null; + try { + info = (JavaElementInfo)((JavaElement)newElement).getElementInfo(); + } catch (JavaModelException npe) { + return; + } + + IJavaElement[] children = info.getChildren(); + if (children != null) { + insertPositions(children, true); + for(int i = 0, length = children.length; i < length; i++) { + recordNewPositions(children[i], depth + 1); + } + } + } +} +/** + * Repairs the positioning information + * after an element has been removed + */ +private void removed(IJavaElement element) { + this.removed.add(element); + ListItem current = this.getOldPosition(element); + ListItem previous = null, next = null; + if (current.previous != null) + previous = this.getOldPosition(current.previous); + if (current.next != null) + next = this.getOldPosition(current.next); + if (previous != null) + previous.next = current.next; + if (next != null) + next.previous = current.previous; + +} +private void removeElementInfo(IJavaElement element) { + this.infos.remove(element); +} +public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append("Built delta:\n"); //$NON-NLS-1$ + buffer.append(this.delta.toString()); + return buffer.toString(); +} +/** + * Trims deletion deltas to only report the highest level of deletion + */ +private void trimDelta(JavaElementDelta delta) { + if (delta.getKind() == IJavaElementDelta.REMOVED) { + IJavaElementDelta[] children = delta.getAffectedChildren(); + for(int i = 0, length = children.length; i < length; i++) { + delta.removeAffectedChild((JavaElementDelta)children[i]); + } + } else { + IJavaElementDelta[] children = delta.getAffectedChildren(); + for(int i = 0, length = children.length; i < length; i++) { + trimDelta((JavaElementDelta)children[i]); + } + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaElementRequestor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaElementRequestor.java new file mode 100644 index 0000000..88201b0 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaElementRequestor.java @@ -0,0 +1,225 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.util.ArrayList; + +import net.sourceforge.phpdt.core.IField; +import net.sourceforge.phpdt.core.IMethod; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IType; + +/** + * @see IJavaElementRequestor + */ + +public class JavaElementRequestor implements IJavaElementRequestor { + /** + * True if this requestor no longer wants to receive + * results from its IRequestorNameLookup. + */ + protected boolean fCanceled= false; + + /** + * A collection of the resulting fields, or null + * if no field results have been received. + */ + protected ArrayList fFields= null; + + /** + * A collection of the resulting initializers, or null + * if no initializer results have been received. + */ + protected ArrayList fInitializers= null; + + /** + * A collection of the resulting member types, or null + * if no member type results have been received. + */ + protected ArrayList fMemberTypes= null; + + /** + * A collection of the resulting methods, or null + * if no method results have been received. + */ + protected ArrayList fMethods= null; + + /** + * A collection of the resulting package fragments, or null + * if no package fragment results have been received. + */ + protected ArrayList fPackageFragments= null; + + /** + * A collection of the resulting types, or null + * if no type results have been received. + */ + protected ArrayList fTypes= null; + + /** + * Empty arrays used for efficiency + */ + protected static IField[] fgEmptyFieldArray= new IField[0]; +// protected static IInitializer[] fgEmptyInitializerArray= new IInitializer[0]; + protected static IType[] fgEmptyTypeArray= new IType[0]; + protected static IPackageFragment[] fgEmptyPackageFragmentArray= new IPackageFragment[0]; + protected static IMethod[] fgEmptyMethodArray= new IMethod[0]; +/** + * @see IJavaElementRequestor + */ +public void acceptField(IField field) { + if (fFields == null) { + fFields= new ArrayList(); + } + fFields.add(field); +} +/** + * @see IJavaElementRequestor + */ +//public void acceptInitializer(IInitializer initializer) { +// if (fInitializers == null) { +// fInitializers= new ArrayList(); +// } +// fInitializers.add(initializer); +//} +/** + * @see IJavaElementRequestor + */ +public void acceptMemberType(IType type) { + if (fMemberTypes == null) { + fMemberTypes= new ArrayList(); + } + fMemberTypes.add(type); +} +/** + * @see IJavaElementRequestor + */ +public void acceptMethod(IMethod method) { + if (fMethods == null) { + fMethods = new ArrayList(); + } + fMethods.add(method); +} +/** + * @see IJavaElementRequestor + */ +public void acceptPackageFragment(IPackageFragment packageFragment) { + if (fPackageFragments== null) { + fPackageFragments= new ArrayList(); + } + fPackageFragments.add(packageFragment); +} +/** + * @see IJavaElementRequestor + */ +public void acceptType(IType type) { + if (fTypes == null) { + fTypes= new ArrayList(); + } + fTypes.add(type); +} +/** + * @see IJavaElementRequestor + */ +public IField[] getFields() { + if (fFields == null) { + return fgEmptyFieldArray; + } + int size = fFields.size(); + IField[] results = new IField[size]; + fFields.toArray(results); + return results; +} +/** + * @see IJavaElementRequestor + */ +//public IInitializer[] getInitializers() { +// if (fInitializers == null) { +// return fgEmptyInitializerArray; +// } +// int size = fInitializers.size(); +// IInitializer[] results = new IInitializer[size]; +// fInitializers.toArray(results); +// return results; +//} +/** + * @see IJavaElementRequestor + */ +public IType[] getMemberTypes() { + if (fMemberTypes == null) { + return fgEmptyTypeArray; + } + int size = fMemberTypes.size(); + IType[] results = new IType[size]; + fMemberTypes.toArray(results); + return results; +} +/** + * @see IJavaElementRequestor + */ +public IMethod[] getMethods() { + if (fMethods == null) { + return fgEmptyMethodArray; + } + int size = fMethods.size(); + IMethod[] results = new IMethod[size]; + fMethods.toArray(results); + return results; +} +/** + * @see IJavaElementRequestor + */ +public IPackageFragment[] getPackageFragments() { + if (fPackageFragments== null) { + return fgEmptyPackageFragmentArray; + } + int size = fPackageFragments.size(); + IPackageFragment[] results = new IPackageFragment[size]; + fPackageFragments.toArray(results); + return results; +} +/** + * @see IJavaElementRequestor + */ +public IType[] getTypes() { + if (fTypes== null) { + return fgEmptyTypeArray; + } + int size = fTypes.size(); + IType[] results = new IType[size]; + fTypes.toArray(results); + return results; +} +/** + * @see IJavaElementRequestor + */ +public boolean isCanceled() { + return fCanceled; +} +/** + * Reset the state of this requestor. + */ +public void reset() { + fCanceled = false; + fFields = null; + fInitializers = null; + fMemberTypes = null; + fMethods = null; + fPackageFragments = null; + fTypes = null; +} +/** + * Sets the #isCanceled state of this requestor to true or false. + */ +public void setCanceled(boolean b) { + fCanceled= b; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModel.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModel.java index 41c449f..daa7f05 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModel.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModel.java @@ -10,14 +10,17 @@ *******************************************************************************/ package net.sourceforge.phpdt.internal.core; +import java.io.File; import java.util.ArrayList; import java.util.HashSet; +import java.util.Map; import net.sourceforge.phpdt.core.IJavaElement; import net.sourceforge.phpdt.core.IJavaModel; import net.sourceforge.phpdt.core.IJavaProject; import net.sourceforge.phpdt.core.JavaModelException; +import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; @@ -25,6 +28,7 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jface.util.Assert; @@ -60,55 +64,55 @@ protected JavaModel() throws Error { /* * @see IJavaModel */ -//public boolean contains(IResource resource) { -// switch (resource.getType()) { -// case IResource.ROOT: -// case IResource.PROJECT: -// return true; -// } -// // file or folder -// IJavaProject[] projects; -// try { -// projects = this.getJavaProjects(); -// } catch (JavaModelException e) { -// return false; -// } -// for (int i = 0, length = projects.length; i < length; i++) { -// JavaProject project = (JavaProject)projects[i]; -// -// if (!project.contains(resource)) { -// return false; -// } -// } -// return true; -//} +public boolean contains(IResource resource) { + switch (resource.getType()) { + case IResource.ROOT: + case IResource.PROJECT: + return true; + } + // file or folder + IJavaProject[] projects; + try { + projects = this.getJavaProjects(); + } catch (JavaModelException e) { + return false; + } + for (int i = 0, length = projects.length; i < length; i++) { + JavaProject project = (JavaProject)projects[i]; + + if (!project.contains(resource)) { + return false; + } + } + return true; +} /** * @see IJavaModel */ -//public void copy(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException { -// if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) { -// runOperation(new CopyResourceElementsOperation(elements, containers, force), elements, siblings, renamings, monitor); -// } else { -// runOperation(new CopyElementsOperation(elements, containers, force), elements, siblings, renamings, monitor); -// } -//} +public void copy(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException { + if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) { + runOperation(new CopyResourceElementsOperation(elements, containers, force), elements, siblings, renamings, monitor); + } else { + runOperation(new CopyElementsOperation(elements, containers, force), elements, siblings, renamings, monitor); + } +} /** * Returns a new element info for this element. */ -//protected OpenableElementInfo createElementInfo() { -// return new JavaModelInfo(); -//} +protected OpenableElementInfo createElementInfo() { + return new JavaModelInfo(); +} /** * @see IJavaModel */ -//public void delete(IJavaElement[] elements, boolean force, IProgressMonitor monitor) throws JavaModelException { -// if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) { -// runOperation(new DeleteResourceElementsOperation(elements, force), monitor); -// } else { -// runOperation(new DeleteElementsOperation(elements, force), monitor); -// } -//} +public void delete(IJavaElement[] elements, boolean force, IProgressMonitor monitor) throws JavaModelException { + if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) { + runOperation(new DeleteResourceElementsOperation(elements, force), monitor); + } else { + runOperation(new DeleteElementsOperation(elements, force), monitor); + } +} /** * Finds the given project in the list of the java model's children. * Returns null if not found. @@ -136,23 +140,23 @@ public static void flushExternalFileCache() { /** */ -//protected boolean generateInfos( -// OpenableElementInfo info, -// IProgressMonitor pm, -// Map newElements, -// IResource underlyingResource) throws JavaModelException { -// -// JavaModelManager.getJavaModelManager().putInfo(this, info); -// // determine my children -// IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); -// for (int i = 0, max = projects.length; i < max; i++) { -// IProject project = projects[i]; -// if (JavaProject.hasJavaNature(project)) { -// info.addChild(getJavaProject(project)); -// } -// } -// return true; -//} +protected boolean generateInfos( + OpenableElementInfo info, + IProgressMonitor pm, + Map newElements, + IResource underlyingResource) throws JavaModelException { + + JavaModelManager.getJavaModelManager().putInfo(this, info); + // determine my children + IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); + for (int i = 0, max = projects.length; i < max; i++) { + IProject project = projects[i]; + if (JavaProject.hasJavaNature(project)) { + info.addChild(getJavaProject(project)); + } + } + return true; +} /** * Returns the IJavaElement represented by the String * memento. @@ -425,13 +429,13 @@ public IWorkspace getWorkspace() { /** * @see IJavaModel */ -//public void move(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException { -// if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) { -// runOperation(new MoveResourceElementsOperation(elements, containers, force), elements, siblings, renamings, monitor); -// } else { -// runOperation(new MoveElementsOperation(elements, containers, force), elements, siblings, renamings, monitor); -// } -//} +public void move(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException { + if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) { + runOperation(new MoveResourceElementsOperation(elements, containers, force), elements, siblings, renamings, monitor); + } else { + runOperation(new MoveElementsOperation(elements, containers, force), elements, siblings, renamings, monitor); + } +} /** * @see IJavaModel#refreshExternalArchives(IJavaElement[], IProgressMonitor) @@ -446,16 +450,16 @@ public IWorkspace getWorkspace() { /** * @see IJavaModel */ -//public void rename(IJavaElement[] elements, IJavaElement[] destinations, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException { -// MultiOperation op; -// if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) { -// op = new RenameResourceElementsOperation(elements, destinations, renamings, force); -// } else { -// op = new RenameElementsOperation(elements, destinations, renamings, force); -// } -// -// runOperation(op, monitor); -//} +public void rename(IJavaElement[] elements, IJavaElement[] destinations, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException { + MultiOperation op; + if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) { + op = new RenameResourceElementsOperation(elements, destinations, renamings, force); + } else { + op = new RenameElementsOperation(elements, destinations, renamings, force); + } + + runOperation(op, monitor); +} /* * @see JavaElement#rootedAt(IJavaProject) */ @@ -466,15 +470,15 @@ public IJavaElement rootedAt(IJavaProject project) { /** * Configures and runs the MultiOperation. */ -//protected void runOperation(MultiOperation op, IJavaElement[] elements, IJavaElement[] siblings, String[] renamings, IProgressMonitor monitor) throws JavaModelException { -// op.setRenamings(renamings); -// if (siblings != null) { -// for (int i = 0; i < elements.length; i++) { -// op.setInsertBefore(elements[i], siblings[i]); -// } -// } -// runOperation(op, monitor); -//} +protected void runOperation(MultiOperation op, IJavaElement[] elements, IJavaElement[] siblings, String[] renamings, IProgressMonitor monitor) throws JavaModelException { + op.setRenamings(renamings); + if (siblings != null) { + for (int i = 0; i < elements.length; i++) { + op.setInsertBefore(elements[i], siblings[i]); + } + } + runOperation(op, monitor); +} /** * @private Debugging purposes */ @@ -491,41 +495,41 @@ protected void toStringInfo(int tab, StringBuffer buffer, Object info) { * or null if unbound * Internal items must be referred to using container relative paths. */ -//public static Object getTarget(IContainer container, IPath path, boolean checkResourceExistence) { -// -// if (path == null) return null; -// -// // lookup - inside the container -// if (path.getDevice() == null) { // container relative paths should not contain a device -// // (see http://dev.eclipse.org/bugs/show_bug.cgi?id=18684) -// // (case of a workspace rooted at d:\ ) -// IResource resource = container.findMember(path); -// if (resource != null){ -// if (!checkResourceExistence ||resource.exists()) return resource; -// return null; -// } -// } -// -// // if path is relative, it cannot be an external path -// // (see http://dev.eclipse.org/bugs/show_bug.cgi?id=22517) -// if (!path.isAbsolute()) return null; -// -// // lookup - outside the container -// File externalFile = new File(path.toOSString()); -// if (!checkResourceExistence) { -// return externalFile; -// } else if (existingExternalFiles.contains(externalFile)) { -// return externalFile; -// } else { -// if (JavaModelManager.ZIP_ACCESS_VERBOSE) { -// System.out.println("(" + Thread.currentThread() + ") [JavaModel.getTarget(...)] Checking existence of " + path.toString()); //$NON-NLS-1$ //$NON-NLS-2$ -// } -// if (externalFile.exists()) { -// // cache external file -// existingExternalFiles.add(externalFile); -// return externalFile; -// } -// } -// return null; -//} +public static Object getTarget(IContainer container, IPath path, boolean checkResourceExistence) { + + if (path == null) return null; + + // lookup - inside the container + if (path.getDevice() == null) { // container relative paths should not contain a device + // (see http://dev.eclipse.org/bugs/show_bug.cgi?id=18684) + // (case of a workspace rooted at d:\ ) + IResource resource = container.findMember(path); + if (resource != null){ + if (!checkResourceExistence ||resource.exists()) return resource; + return null; + } + } + + // if path is relative, it cannot be an external path + // (see http://dev.eclipse.org/bugs/show_bug.cgi?id=22517) + if (!path.isAbsolute()) return null; + + // lookup - outside the container + File externalFile = new File(path.toOSString()); + if (!checkResourceExistence) { + return externalFile; + } else if (existingExternalFiles.contains(externalFile)) { + return externalFile; + } else { + if (JavaModelManager.ZIP_ACCESS_VERBOSE) { + System.out.println("(" + Thread.currentThread() + ") [JavaModel.getTarget(...)] Checking existence of " + path.toString()); //$NON-NLS-1$ //$NON-NLS-2$ + } + if (externalFile.exists()) { + // cache external file + existingExternalFiles.add(externalFile); + return externalFile; + } + } + return null; +} } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelCache.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelCache.java new file mode 100644 index 0000000..4121aa3 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelCache.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.phpdt.core.IJavaElement; + +/** + * The cache of java elements to their respective info. + */ +public class JavaModelCache { + public static final int PKG_CACHE_SIZE = 500; + public static final int OPENABLE_CACHE_SIZE = 2000; + + /** + * Active Java Model Info + */ + protected JavaModelInfo modelInfo; + + /** + * Cache of open projects and package fragment roots. + */ + protected Map projectAndRootCache; + + /** + * Cache of open package fragments + */ + protected Map pkgCache; + + /** + * Cache of open compilation unit and class files + */ + protected OverflowingLRUCache openableCache; + + /** + * Cache of open children of openable Java Model Java elements + */ + protected Map childrenCache; + +public JavaModelCache() { + this.projectAndRootCache = new HashMap(50); + this.pkgCache = new HashMap(PKG_CACHE_SIZE); + this.openableCache = new ElementCache(OPENABLE_CACHE_SIZE); + this.childrenCache = new HashMap(OPENABLE_CACHE_SIZE*20); // average 20 chilren per openable +} + +public double openableFillingRatio() { + return this.openableCache.fillingRatio(); +} +public int pkgSize() { + return this.pkgCache.size(); +} + +/** + * Returns the info for the element. + */ +public Object getInfo(IJavaElement element) { + switch (element.getElementType()) { + case IJavaElement.JAVA_MODEL: + return this.modelInfo; + case IJavaElement.JAVA_PROJECT: + case IJavaElement.PACKAGE_FRAGMENT_ROOT: + return this.projectAndRootCache.get(element); + case IJavaElement.PACKAGE_FRAGMENT: + return this.pkgCache.get(element); + case IJavaElement.COMPILATION_UNIT: + case IJavaElement.CLASS_FILE: + return this.openableCache.get(element); + default: + return this.childrenCache.get(element); + } +} + +/** + * Returns the info for this element without + * disturbing the cache ordering. + */ +protected Object peekAtInfo(IJavaElement element) { + switch (element.getElementType()) { + case IJavaElement.JAVA_MODEL: + return this.modelInfo; + case IJavaElement.JAVA_PROJECT: + case IJavaElement.PACKAGE_FRAGMENT_ROOT: + return this.projectAndRootCache.get(element); + case IJavaElement.PACKAGE_FRAGMENT: + return this.pkgCache.get(element); + case IJavaElement.COMPILATION_UNIT: + case IJavaElement.CLASS_FILE: + return this.openableCache.peek(element); + default: + return this.childrenCache.get(element); + } +} + +/** + * Remember the info for the element. + */ +protected void putInfo(IJavaElement element, Object info) { + switch (element.getElementType()) { + case IJavaElement.JAVA_MODEL: + this.modelInfo = (JavaModelInfo) info; + break; + case IJavaElement.JAVA_PROJECT: + case IJavaElement.PACKAGE_FRAGMENT_ROOT: + this.projectAndRootCache.put(element, info); + break; + case IJavaElement.PACKAGE_FRAGMENT: + this.pkgCache.put(element, info); + break; + case IJavaElement.COMPILATION_UNIT: + case IJavaElement.CLASS_FILE: + this.openableCache.put(element, info); + break; + default: + this.childrenCache.put(element, info); + } +} +/** + * Removes the info of the element from the cache. + */ +protected void removeInfo(IJavaElement element) { + switch (element.getElementType()) { + case IJavaElement.JAVA_MODEL: + this.modelInfo = null; + break; + case IJavaElement.JAVA_PROJECT: + case IJavaElement.PACKAGE_FRAGMENT_ROOT: + this.projectAndRootCache.remove(element); + break; + case IJavaElement.PACKAGE_FRAGMENT: + this.pkgCache.remove(element); + break; + case IJavaElement.COMPILATION_UNIT: + case IJavaElement.CLASS_FILE: + this.openableCache.remove(element); + break; + default: + this.childrenCache.remove(element); + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelInfo.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelInfo.java new file mode 100644 index 0000000..b572012 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelInfo.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; + +/** + * Implementation of IJavaModel. A Java Model is specific to a + * workspace. + * + * @see IJavaModel + */ +public class JavaModelInfo extends OpenableElementInfo { + + /** + * A array with all the non-java projects contained by this model + */ + Object[] nonJavaResources; + +/** + * Constructs a new Java Model Info + */ +protected JavaModelInfo() { +} +/** + * Compute the non-java resources contained in this java project. + */ +private Object[] computeNonJavaResources() { + IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); + int length = projects.length; + Object[] nonJavaResources = null; + int index = 0; + for (int i = 0; i < length; i++) { + IProject project = projects[i]; + if (!JavaProject.hasJavaNature(project)) { + if (nonJavaResources == null) { + nonJavaResources = new Object[length]; + } + nonJavaResources[index++] = project; + } + } + if (index == 0) return NO_NON_JAVA_RESOURCES; + if (index < length) { + System.arraycopy(nonJavaResources, 0, nonJavaResources = new Object[index], 0, index); + } + return nonJavaResources; +} + +/** + * Returns an array of non-java resources contained in the receiver. + */ +Object[] getNonJavaResources() { + + Object[] nonJavaResources = this.nonJavaResources; + if (nonJavaResources == null) { + nonJavaResources = computeNonJavaResources(); + this.nonJavaResources = nonJavaResources; + } + return nonJavaResources; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelManager.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelManager.java index 6652089..0ab7de9 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelManager.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelManager.java @@ -11,9 +11,12 @@ package net.sourceforge.phpdt.internal.core; import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; @@ -25,16 +28,21 @@ import java.util.WeakHashMap; import java.util.zip.ZipFile; import net.sourceforge.phpdt.core.ElementChangedEvent; +import net.sourceforge.phpdt.core.IClasspathEntry; import net.sourceforge.phpdt.core.ICompilationUnit; import net.sourceforge.phpdt.core.IElementChangedListener; import net.sourceforge.phpdt.core.IJavaElement; import net.sourceforge.phpdt.core.IJavaElementDelta; +import net.sourceforge.phpdt.core.IJavaModel; import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; import net.sourceforge.phpdt.core.IWorkingCopy; -import net.sourceforge.phpdt.core.JavaCore; import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil; +import net.sourceforge.phpeclipse.PHPCore; import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.builder.PHPBuilder; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; @@ -56,6 +64,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Preferences; import org.eclipse.core.runtime.Status; @@ -81,7 +90,7 @@ public class JavaModelManager implements ISaveParticipant { public static HashMap PreviousSessionVariables = new HashMap(5); public static HashSet OptionNames = new HashSet(20); public final static String CP_VARIABLE_PREFERENCES_PREFIX = PHPeclipsePlugin.PLUGIN_ID+".classpathVariable."; //$NON-NLS-1$ -// public final static String CP_CONTAINER_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".classpathContainer."; //$NON-NLS-1$ +// public final static String CP_CONTAINER_PREFERENCES_PREFIX = PHPCore.PLUGIN_ID+".classpathContainer."; //$NON-NLS-1$ public final static String CP_ENTRY_IGNORE = "####"; //$NON-NLS-1$ /** @@ -137,38 +146,38 @@ public class JavaModelManager implements ISaveParticipant { * Returns whether the given full path (for a package) conflicts with the output location * of the given project. */ -// public static boolean conflictsWithOutputLocation(IPath folderPath, JavaProject project) { -// try { -// IPath outputLocation = project.getOutputLocation(); -// if (outputLocation == null) { -// // in doubt, there is a conflict -// return true; -// } -// if (outputLocation.isPrefixOf(folderPath)) { -// // only allow nesting in project's output if there is a corresponding source folder -// // or if the project's output is not used (in other words, if all source folders have their custom output) -// IClasspathEntry[] classpath = project.getResolvedClasspath(true); -// boolean isOutputUsed = false; -// for (int i = 0, length = classpath.length; i < length; i++) { -// IClasspathEntry entry = classpath[i]; -// if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { -// if (entry.getPath().equals(outputLocation)) { -// return false; -// } -// if (entry.getOutputLocation() == null) { -// isOutputUsed = true; -// } -// } -// } -// return isOutputUsed; -// } -// return false; -// } catch (JavaModelException e) { -// // in doubt, there is a conflict -// return true; -// } -// } -// + public static boolean conflictsWithOutputLocation(IPath folderPath, JavaProject project) { + try { + IPath outputLocation = project.getOutputLocation(); + if (outputLocation == null) { + // in doubt, there is a conflict + return true; + } + if (outputLocation.isPrefixOf(folderPath)) { + // only allow nesting in project's output if there is a corresponding source folder + // or if the project's output is not used (in other words, if all source folders have their custom output) + IClasspathEntry[] classpath = project.getResolvedClasspath(true); + boolean isOutputUsed = false; + for (int i = 0, length = classpath.length; i < length; i++) { + IClasspathEntry entry = classpath[i]; + if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { + if (entry.getPath().equals(outputLocation)) { + return false; + } + if (entry.getOutputLocation() == null) { + isOutputUsed = true; + } + } + } + return isOutputUsed; + } + return false; + } catch (JavaModelException e) { + // in doubt, there is a conflict + return true; + } + } + // public static IClasspathContainer containerGet(IJavaProject project, IPath containerPath) { // Map projectContainers = (Map)Containers.get(project); // if (projectContainers == null){ @@ -239,13 +248,13 @@ public class JavaModelManager implements ISaveParticipant { int type = resource.getType(); switch (type) { case IResource.PROJECT : - return JavaCore.create((IProject) resource); + return PHPCore.create((IProject) resource); case IResource.FILE : return create((IFile) resource, project); case IResource.FOLDER : return create((IFolder) resource, project); case IResource.ROOT : - return JavaCore.create((IWorkspaceRoot) resource); + return PHPCore.create((IWorkspaceRoot) resource); default : return null; } @@ -271,7 +280,7 @@ public class JavaModelManager implements ISaveParticipant { return null; } if (project == null) { - project = JavaCore.create(file.getProject()); + project = PHPCore.create(file.getProject()); } if (file.getFileExtension() != null) { @@ -302,18 +311,16 @@ public class JavaModelManager implements ISaveParticipant { return null; } if (project == null) { - project = JavaCore.create(folder.getProject()); + project = PHPCore.create(folder.getProject()); + } + IJavaElement element = determineIfOnClasspath(folder, project); + if (conflictsWithOutputLocation(folder.getFullPath(), (JavaProject)project) + || (folder.getName().indexOf('.') >= 0 + && !(element instanceof IPackageFragmentRoot))) { + return null; // only package fragment roots are allowed with dot names + } else { + return element; } -// TODO khartlage temp-del -// IJavaElement element = determineIfOnClasspath(folder, project); -// if (conflictsWithOutputLocation(folder.getFullPath(), (JavaProject)project) -// || (folder.getName().indexOf('.') >= 0 -// && !(element instanceof IPackageFragmentRoot))) { -// return null; // only package fragment roots are allowed with dot names -// } else { -// return element; -// } -return null; } /** @@ -326,7 +333,7 @@ return null; // return null; // } // if (project == null) { -// project = JavaCore.create(file.getProject()); +// project = PHPCore.create(file.getProject()); // } // IPackageFragment pkg = (IPackageFragment) determineIfOnClasspath(file, project); // if (pkg == null) { @@ -348,24 +355,20 @@ return null; if (file == null) return null; if (project == null) { - project = JavaCore.create(file.getProject()); + project = PHPCore.create(file.getProject()); } -// TODO khartlage temp-del -// IPackageFragment pkg = (IPackageFragment) determineIfOnClasspath(file, project); -// if (pkg == null) { - + IPackageFragment pkg = (IPackageFragment) determineIfOnClasspath(file, project); + if (pkg == null) { // not on classpath - make the root its folder, and a default package -// IPackageFragmentRoot root = project.getPackageFragmentRoot(file.getParent()); -// pkg = root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME); -// -// if (VERBOSE){ -// System.out.println("WARNING : creating unit element outside classpath ("+ Thread.currentThread()+"): " + file.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$ -// } -// } -// return pkg.getCompilationUnit(file.getName()); -return null; + IPackageFragmentRoot root = project.getPackageFragmentRoot(file.getParent()); + pkg = root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME); + + if (VERBOSE){ + System.out.println("WARNING : creating unit element outside classpath ("+ Thread.currentThread()+"): " + file.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$ + } + } + return pkg.getCompilationUnit(file.getName()); } - /** * Creates and returns a handle for the given JAR file, its project being the given project. * The Java model associated with the JAR's project may be @@ -378,7 +381,7 @@ return null; // return null; // } // if (project == null) { -// project = JavaCore.create(file.getProject()); +// project = PHPCore.create(file.getProject()); // } // // // Create a jar package fragment root only if on the classpath @@ -402,50 +405,50 @@ return null; * the package fragment the given resource is located in, or null * if the given resource is not on the classpath of the given project. */ -// public static IJavaElement determineIfOnClasspath( -// IResource resource, -// IJavaProject project) { -// -// IPath resourcePath = resource.getFullPath(); -// try { -// IClasspathEntry[] entries = -// Util.isJavaFileName(resourcePath.lastSegment()) -// ? project.getRawClasspath() // JAVA file can only live inside SRC folder (on the raw path) -// : ((JavaProject)project).getResolvedClasspath(true); -// -// for (int i = 0; i < entries.length; i++) { -// IClasspathEntry entry = entries[i]; -// if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) continue; -// IPath rootPath = entry.getPath(); -// if (rootPath.equals(resourcePath)) { -// return project.getPackageFragmentRoot(resource); -// } else if (rootPath.isPrefixOf(resourcePath) && !Util.isExcluded(resource, ((ClasspathEntry)entry).fullExclusionPatternChars())) { -// // given we have a resource child of the root, it cannot be a JAR pkg root -// IPackageFragmentRoot root = ((JavaProject) project).getFolderPackageFragmentRoot(rootPath); -// if (root == null) return null; -// IPath pkgPath = resourcePath.removeFirstSegments(rootPath.segmentCount()); -// if (resource.getType() == IResource.FILE) { -// // if the resource is a file, then remove the last segment which -// // is the file name in the package -// pkgPath = pkgPath.removeLastSegments(1); -// -// // don't check validity of package name (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=26706) -// String pkgName = pkgPath.toString().replace('/', '.'); -// return root.getPackageFragment(pkgName); -// } else { -// String pkgName = Util.packageName(pkgPath); -// if (pkgName == null || JavaConventions.validatePackageName(pkgName).getSeverity() == IStatus.ERROR) { -// return null; -// } -// return root.getPackageFragment(pkgName); -// } -// } -// } -// } catch (JavaModelException npe) { -// return null; -// } -// return null; -// } + public static IJavaElement determineIfOnClasspath( + IResource resource, + IJavaProject project) { + + IPath resourcePath = resource.getFullPath(); + try { + IClasspathEntry[] entries = + Util.isJavaFileName(resourcePath.lastSegment()) + ? project.getRawClasspath() // JAVA file can only live inside SRC folder (on the raw path) + : ((JavaProject)project).getResolvedClasspath(true); + + for (int i = 0; i < entries.length; i++) { + IClasspathEntry entry = entries[i]; + if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) continue; + IPath rootPath = entry.getPath(); + if (rootPath.equals(resourcePath)) { + return project.getPackageFragmentRoot(resource); + } else if (rootPath.isPrefixOf(resourcePath) && !Util.isExcluded(resource, ((ClasspathEntry)entry).fullExclusionPatternChars())) { + // given we have a resource child of the root, it cannot be a JAR pkg root + IPackageFragmentRoot root = ((JavaProject) project).getFolderPackageFragmentRoot(rootPath); + if (root == null) return null; + IPath pkgPath = resourcePath.removeFirstSegments(rootPath.segmentCount()); + if (resource.getType() == IResource.FILE) { + // if the resource is a file, then remove the last segment which + // is the file name in the package + pkgPath = pkgPath.removeLastSegments(1); + + // don't check validity of package name (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=26706) + String pkgName = pkgPath.toString().replace('/', '.'); + return root.getPackageFragment(pkgName); + } else { + String pkgName = Util.packageName(pkgPath); + if (pkgName == null){// || JavaConventions.validatePackageName(pkgName).getSeverity() == IStatus.ERROR) { + return null; + } + return root.getPackageFragment(pkgName); + } + } + } + } catch (JavaModelException npe) { + return null; + } + return null; + } /** * The singleton manager @@ -455,7 +458,7 @@ return null; /** * Infos cache. */ -// protected JavaModelCache cache = new JavaModelCache(); + protected JavaModelCache cache = new JavaModelCache(); /** * Set of elements which are out of sync with their buffers. @@ -525,8 +528,8 @@ return null; public IProject project; public Object savedState; public boolean triedRead; -// public IClasspathEntry[] classpath; -// public IClasspathEntry[] lastResolvedClasspath; + public IClasspathEntry[] classpath; + public IClasspathEntry[] lastResolvedClasspath; public Map resolvedPathToRawEntries; // reverse map from resolved path to raw entries public IPath outputLocation; public Preferences preferences; @@ -578,7 +581,7 @@ return null; /** * Line separator to use throughout the JavaModel for any source edit operation */ - // public static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$ + public static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$ /** * Constructs a new JavaModelManager */ @@ -652,7 +655,7 @@ return null; * Configure the plugin with respect to option settings defined in ".options" file */ public void configurePluginDebugOptions(){ - if(JavaCore.getPlugin().isDebugging()){ + if(PHPCore.getPlugin().isDebugging()){ // TODO khartlage temp-del String option = Platform.getDebugOption(BUILDER_DEBUG); // if(option != null) JavaBuilder.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ @@ -934,9 +937,9 @@ return null; /** * Returns the info for the element. */ -// public Object getInfo(IJavaElement element) { -// return this.cache.getInfo(element); -// } + public Object getInfo(IJavaElement element) { + return this.cache.getInfo(element); + } /** * Returns the handle to the active Java Model. @@ -997,7 +1000,7 @@ return null; JavaModelManager.PerProjectInfo info = getPerProjectInfo(project, false /* don't create info */); if (info == null) { if (!JavaProject.hasJavaNature(project)) { - throw ((JavaProject)JavaCore.create(project)).newNotPresentException(); + throw ((JavaProject)PHPCore.create(project)).newNotPresentException(); } info = getPerProjectInfo(project, true /* create info */); } @@ -1007,12 +1010,12 @@ return null; /** * Returns the name of the variables for which an CP variable initializer is registered through an extension point */ -// public static String[] getRegisteredVariableNames(){ -// -// Plugin jdtCorePlugin = JavaCore.getPlugin(); -// if (jdtCorePlugin == null) return null; -// -// ArrayList variableList = new ArrayList(5); + public static String[] getRegisteredVariableNames(){ + + Plugin jdtCorePlugin = PHPCore.getPlugin(); + if (jdtCorePlugin == null) return null; + + ArrayList variableList = new ArrayList(5); // IExtensionPoint extension = jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.CPVARIABLE_INITIALIZER_EXTPOINT_ID); // if (extension != null) { // IExtension[] extensions = extension.getExtensions(); @@ -1024,17 +1027,17 @@ return null; // } // } // } -// String[] variableNames = new String[variableList.size()]; -// variableList.toArray(variableNames); -// return variableNames; -// } + String[] variableNames = new String[variableList.size()]; + variableList.toArray(variableNames); + return variableNames; + } /** * Returns the name of the container IDs for which an CP container initializer is registered through an extension point */ // public static String[] getRegisteredContainerIDs(){ // -// Plugin jdtCorePlugin = JavaCore.getPlugin(); +// Plugin jdtCorePlugin = PHPCore.getPlugin(); // if (jdtCorePlugin == null) return null; // // ArrayList containerIDList = new ArrayList(5); @@ -1059,7 +1062,7 @@ return null; */ private File getSerializationFile(IProject project) { if (!project.exists()) return null; - IPluginDescriptor descr= JavaCore.getJavaCore().getDescriptor(); + IPluginDescriptor descr= PHPCore.getJavaCore().getDescriptor(); IPath workingLocation= project.getPluginWorkingLocation(descr); return workingLocation.append("state.dat").toFile(); //$NON-NLS-1$ } @@ -1091,18 +1094,18 @@ return null; } else { // internal resource (not an IFile or not existing) IPath location; if (file.getType() != IResource.FILE || (location = file.getLocation()) == null) { - throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("file.notFound", path.toString()), null)); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, PHPCore.PLUGIN_ID, -1, Util.bind("file.notFound", path.toString()), null)); //$NON-NLS-1$ } fileSystemPath= location.toOSString(); } } else if (!path.isAbsolute()) { file= root.getFile(path); if (file == null || file.getType() != IResource.FILE) { - throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("file.notFound", path.toString()), null)); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, PHPCore.PLUGIN_ID, -1, Util.bind("file.notFound", path.toString()), null)); //$NON-NLS-1$ } IPath location = file.getLocation(); if (location == null) { - throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("file.notFound", path.toString()), null)); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, PHPCore.PLUGIN_ID, -1, Util.bind("file.notFound", path.toString()), null)); //$NON-NLS-1$ } fileSystemPath= location.toOSString(); } else { @@ -1119,7 +1122,7 @@ return null; } return zipFile; } catch (IOException e) { - throw new CoreException(new Status(Status.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("status.IOException"), e)); //$NON-NLS-1$ + throw new CoreException(new Status(Status.ERROR, PHPCore.PLUGIN_ID, -1, Util.bind("status.IOException"), e)); //$NON-NLS-1$ } } } @@ -1127,7 +1130,7 @@ return null; // public void loadVariablesAndContainers() throws CoreException { // // // backward compatibility, consider persistent property -// QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "variables"); //$NON-NLS-1$ +// QualifiedName qName = new QualifiedName(PHPCore.PLUGIN_ID, "variables"); //$NON-NLS-1$ // String xmlString = ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName); // // try { @@ -1173,7 +1176,7 @@ return null; // } // // // load variables and containers from preferences into cache -// Preferences preferences = JavaCore.getPlugin().getPluginPreferences(); +// Preferences preferences = PHPCore.getPlugin().getPluginPreferences(); // // // only get variable from preferences not set to their default // String[] propertyNames = preferences.propertyNames(); @@ -1270,18 +1273,19 @@ return null; * Returns the info for this element without * disturbing the cache ordering. */ // TODO: should be synchronized, could answer unitialized info or if cache is in middle of rehash, could even answer distinct element info -// protected Object peekAtInfo(IJavaElement element) { -// return this.cache.peekAtInfo(element); -// } + protected Object peekAtInfo(IJavaElement element) { + return this.cache.peekAtInfo(element); + } /** * @see ISaveParticipant */ public void prepareToSave(ISaveContext context) throws CoreException { } -// protected void putInfo(IJavaElement element, Object info) { -// this.cache.putInfo(element, info); -// } + + protected void putInfo(IJavaElement element, Object info) { + this.cache.putInfo(element, info); + } /** * Reads the build state for the relevant project. @@ -1293,14 +1297,14 @@ return null; DataInputStream in= new DataInputStream(new BufferedInputStream(new FileInputStream(file))); try { String pluginID= in.readUTF(); - if (!pluginID.equals(JavaCore.PLUGIN_ID)) + if (!pluginID.equals(PHPCore.PLUGIN_ID)) throw new IOException(Util.bind("build.wrongFileFormat")); //$NON-NLS-1$ String kind= in.readUTF(); if (!kind.equals("STATE")) //$NON-NLS-1$ throw new IOException(Util.bind("build.wrongFileFormat")); //$NON-NLS-1$ + if (in.readBoolean()) + return PHPBuilder.readState(project, in); // TODO khartlage temp-del -// if (in.readBoolean()) -// return JavaBuilder.readState(project, in); // if (JavaBuilder.DEBUG) // System.out.println("Saved state thinks last build failed for " + project.getName()); //$NON-NLS-1$ } finally { @@ -1308,7 +1312,7 @@ return null; } } catch (Exception e) { e.printStackTrace(); - throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR, "Error reading last build state for project "+ project.getName(), e)); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, PHPCore.PLUGIN_ID, Platform.PLUGIN_ERROR, "Error reading last build state for project "+ project.getName(), e)); //$NON-NLS-1$ } } return null; @@ -1409,9 +1413,9 @@ return null; } } -// protected void removeInfo(IJavaElement element) { -// this.cache.removeInfo(element); -// } + protected void removeInfo(IJavaElement element) { + this.cache.removeInfo(element); + } public void removePerProjectInfo(JavaProject javaProject) { synchronized(perProjectInfo) { // use the perProjectInfo collection as its own lock @@ -1435,49 +1439,48 @@ return null; if (context.getKind() == ISaveContext.SNAPSHOT) return; // save built state - // TODO khartlage temp-del -// if (info.triedRead) saveBuiltState(info); + if (info.triedRead) saveBuiltState(info); } /** * Saves the built state for the project. */ -// private void saveBuiltState(PerProjectInfo info) throws CoreException { + private void saveBuiltState(PerProjectInfo info) throws CoreException { // if (JavaBuilder.DEBUG) // System.out.println(Util.bind("build.saveStateProgress", info.project.getName())); //$NON-NLS-1$ -// File file = getSerializationFile(info.project); -// if (file == null) return; -// long t = System.currentTimeMillis(); -// try { -// DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))); -// try { -// out.writeUTF(JavaCore.PLUGIN_ID); -// out.writeUTF("STATE"); //$NON-NLS-1$ -// if (info.savedState == null) { -// out.writeBoolean(false); -// } else { -// out.writeBoolean(true); -// JavaBuilder.writeState(info.savedState, out); -// } -// } finally { -// out.close(); -// } -// } catch (RuntimeException e) { -// try {file.delete();} catch(SecurityException se) {} -// throw new CoreException( -// new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR, -// Util.bind("build.cannotSaveState", info.project.getName()), e)); //$NON-NLS-1$ -// } catch (IOException e) { -// try {file.delete();} catch(SecurityException se) {} -// throw new CoreException( -// new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR, -// Util.bind("build.cannotSaveState", info.project.getName()), e)); //$NON-NLS-1$ -// } + File file = getSerializationFile(info.project); + if (file == null) return; + long t = System.currentTimeMillis(); + try { + DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))); + try { + out.writeUTF(PHPCore.PLUGIN_ID); + out.writeUTF("STATE"); //$NON-NLS-1$ + if (info.savedState == null) { + out.writeBoolean(false); + } else { + out.writeBoolean(true); + PHPBuilder.writeState(info.savedState, out); + } + } finally { + out.close(); + } + } catch (RuntimeException e) { + try {file.delete();} catch(SecurityException se) {} + throw new CoreException( + new Status(IStatus.ERROR, PHPCore.PLUGIN_ID, Platform.PLUGIN_ERROR, + Util.bind("build.cannotSaveState", info.project.getName()), e)); //$NON-NLS-1$ + } catch (IOException e) { + try {file.delete();} catch(SecurityException se) {} + throw new CoreException( + new Status(IStatus.ERROR, PHPCore.PLUGIN_ID, Platform.PLUGIN_ERROR, + Util.bind("build.cannotSaveState", info.project.getName()), e)); //$NON-NLS-1$ + } // if (JavaBuilder.DEBUG) { // t = System.currentTimeMillis() - t; // System.out.println(Util.bind("build.saveStateComplete", String.valueOf(t))); //$NON-NLS-1$ // } -// } + } /** * @see ISaveParticipant @@ -1506,7 +1509,7 @@ return null; if (vStats != null) { IStatus[] stats= new IStatus[vStats.size()]; vStats.toArray(stats); - throw new CoreException(new MultiStatus(JavaCore.PLUGIN_ID, IStatus.ERROR, stats, Util.bind("build.cannotSaveStates"), null)); //$NON-NLS-1$ + throw new CoreException(new MultiStatus(PHPCore.PLUGIN_ID, IStatus.ERROR, stats, Util.bind("build.cannotSaveStates"), null)); //$NON-NLS-1$ } } @@ -1518,7 +1521,7 @@ return null; // optional behaviour // possible value of index 0 is Compute - if (!JavaCore.COMPUTE.equals(JavaCore.getOption(JavaCore.CORE_JAVA_BUILD_ORDER))) return; // cannot be customized at project level + if (!PHPCore.COMPUTE.equals(PHPCore.getOption(PHPCore.CORE_JAVA_BUILD_ORDER))) return; // cannot be customized at project level if (javaBuildOrder == null || javaBuildOrder.length <= 1) return; @@ -1587,14 +1590,14 @@ return null; // if (this.deltaProcessor.indexManager != null){ // no more indexing // this.deltaProcessor.indexManager.shutdown(); // } -// try { -// IJavaModel model = this.getJavaModel(); -// if (model != null) { + try { + IJavaModel model = this.getJavaModel(); + if (model != null) { -// model.close(); -// } -// } catch (JavaModelException e) { -// } + model.close(); + } + } catch (JavaModelException e) { + } } /** @@ -1659,11 +1662,11 @@ return null; if (variablePath == JavaModelManager.VariableInitializationInProgress){ return; } - Preferences preferences = JavaCore.getPlugin().getPluginPreferences(); + Preferences preferences = PHPCore.getPlugin().getPluginPreferences(); String variableKey = CP_VARIABLE_PREFERENCES_PREFIX+variableName; String variableString = variablePath == null ? CP_ENTRY_IGNORE : variablePath.toString(); preferences.setDefault(variableKey, CP_ENTRY_IGNORE); // use this default to get rid of removed ones preferences.setValue(variableKey, variableString); - JavaCore.getPlugin().savePluginPreferences(); + PHPCore.getPlugin().savePluginPreferences(); } } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelOperation.java index 0347ce1..4fc9675 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelOperation.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelOperation.java @@ -381,9 +381,8 @@ public abstract class JavaModelOperation implements IWorkspaceRunnable, IProgres DeltaProcessor deltaProcessor = JavaModelManager.getJavaModelManager().deltaProcessor; if (deltaProcessor.roots == null) { // TODO khartlage temp-del -// deltaProcessor.initializeRoots(); + deltaProcessor.initializeRoots(); } - executeOperation(); } else { throw new JavaModelException(status); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaProject.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaProject.java index c8541ba..2a0a680 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaProject.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaProject.java @@ -13,32 +13,76 @@ package net.sourceforge.phpdt.internal.core; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; - +import java.io.OutputStreamWriter; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; + +import net.sourceforge.phpdt.core.IClasspathEntry; import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelMarker; +import net.sourceforge.phpdt.core.IJavaModelStatus; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.codeassist.ISearchableNameEnvironment; +import net.sourceforge.phpdt.internal.compiler.util.ObjectVector; +import net.sourceforge.phpdt.internal.corext.Assert; +import net.sourceforge.phpeclipse.LoadPathEntry; import net.sourceforge.phpeclipse.PHPCore; import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import org.apache.xerces.dom.DocumentImpl; +import org.apache.xml.serialize.Method; +import org.apache.xml.serialize.OutputFormat; +import org.apache.xml.serialize.Serializer; +import org.apache.xml.serialize.SerializerFactory; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IProjectNature; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Preferences; import org.eclipse.core.runtime.QualifiedName; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; /** * Handle for a Java Project. @@ -58,7 +102,7 @@ import org.eclipse.core.runtime.QualifiedName; * * @see IJavaProject */ -public class JavaProject +public class JavaProject extends Openable implements IJavaProject , IProjectNature { @@ -76,6 +120,8 @@ public class JavaProject * The platform project this IJavaProject is based on */ protected IProject fProject; + protected List fLoadPathEntries; + protected boolean fScratched; /** * Name of file containing project classpath @@ -90,7 +136,7 @@ public class JavaProject /** * Value of the project's raw classpath if the .classpath file contains invalid entries. */ -// public static final IClasspathEntry[] INVALID_CLASSPATH = new IClasspathEntry[0]; + public static final IClasspathEntry[] INVALID_CLASSPATH = new IClasspathEntry[0]; private static final String CUSTOM_DEFAULT_OPTION_VALUE = "#\r\n\r#custom-non-empty-default-value#\r\n\r#"; //$NON-NLS-1$ @@ -185,7 +231,125 @@ public class JavaProject super(JAVA_PROJECT, parent, project.getName()); fProject = project; } + public void addLoadPathEntry(IProject anotherPHPProject) { + fScratched = true; + + LoadPathEntry newEntry = new LoadPathEntry(anotherPHPProject); + getLoadPathEntries().add(newEntry); + } + + public void configure() throws CoreException { + // get project description and then the associated build commands + IProjectDescription desc = fProject.getDescription(); + ICommand[] commands = desc.getBuildSpec(); + + // determine if builder already associated + boolean found = false; + for (int i = 0; i < commands.length; ++i) { + if (commands[i].getBuilderName().equals(PHPeclipsePlugin.BUILDER_PARSER_ID)) { + found = true; + break; + } + } + + // add builder if not already in project + if (!found) { + ICommand command = desc.newCommand(); + command.setBuilderName(PHPeclipsePlugin.BUILDER_PARSER_ID); + ICommand[] newCommands = new ICommand[commands.length + 1]; + + // Add it before other builders. + System.arraycopy(commands, 0, newCommands, 1, commands.length); + newCommands[0] = command; + desc.setBuildSpec(newCommands); + fProject.setDescription(desc, null); + } + } + + protected void loadLoadPathEntries() { + fLoadPathEntries = new ArrayList(); + + IFile loadPathsFile = getLoadPathEntriesFile(); + + XMLReader reader = null; + try { + reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + reader.setContentHandler(getLoadPathEntriesContentHandler()); + reader.parse(new InputSource(loadPathsFile.getContents())); + } catch (Exception e) { + //the file is nonextant or unreadable + } + } + + public List getLoadPathEntries() { + if (fLoadPathEntries == null) { + loadLoadPathEntries(); + } + + return fLoadPathEntries; + } + + protected ContentHandler getLoadPathEntriesContentHandler() { + return new ContentHandler() { + public void characters(char[] arg0, int arg1, int arg2) throws SAXException { + } + + public void endDocument() throws SAXException { + } + + public void endElement(String arg0, String arg1, String arg2) throws SAXException { + } + + public void endPrefixMapping(String arg0) throws SAXException { + } + + public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException { + } + + public void processingInstruction(String arg0, String arg1) throws SAXException { + } + + public void setDocumentLocator(Locator arg0) { + } + + public void skippedEntity(String arg0) throws SAXException { + } + + public void startDocument() throws SAXException { + } + + public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { + if ("pathentry".equals(qName)) + if ("project".equals(atts.getValue("type"))) { + IPath referencedProjectPath = new Path(atts.getValue("path")); + IProject referencedProject = getProject(referencedProjectPath.lastSegment()); + fLoadPathEntries.add(new LoadPathEntry(referencedProject)); + } + } + + public void startPrefixMapping(String arg0, String arg1) throws SAXException { + } + }; + } + + protected IFile getLoadPathEntriesFile() { + return fProject.getFile(".loadpath"); + } + + protected String getLoadPathXML() { + StringBuffer buffer = new StringBuffer(); + buffer.append(""); + Iterator pathEntriesIterator = fLoadPathEntries.iterator(); + + while (pathEntriesIterator.hasNext()) { + LoadPathEntry entry = (LoadPathEntry) pathEntriesIterator.next(); + buffer.append(entry.toXML()); + } + + buffer.append(""); + return buffer.toString(); + } /** * Adds a builder to the build spec for the given project. */ @@ -203,18 +367,18 @@ public class JavaProject } } -// protected void closing(Object info) throws JavaModelException { -// -// // forget source attachment recommendations -// IPackageFragmentRoot[] roots = this.getPackageFragmentRoots(); + protected void closing(Object info) throws JavaModelException { + + // forget source attachment recommendations + IPackageFragmentRoot[] roots = this.getPackageFragmentRoots(); // for (int i = 0; i < roots.length; i++) { // if (roots[i] instanceof JarPackageFragmentRoot){ // ((JarPackageFragmentRoot) roots[i]).setSourceAttachmentProperty(null); // } // } -// -// super.closing(info); -// } + + super.closing(info); + } @@ -222,52 +386,52 @@ public class JavaProject * Internal computation of an expanded classpath. It will eliminate duplicates, and produce copies * of exported classpath entries to avoid possible side-effects ever after. */ -// private void computeExpandedClasspath( -// JavaProject initialProject, -// boolean ignoreUnresolvedVariable, -// boolean generateMarkerOnError, -// HashSet visitedProjects, -// ObjectVector accumulatedEntries) throws JavaModelException { -// -// if (visitedProjects.contains(this)){ -// return; // break cycles if any -// } -// visitedProjects.add(this); -// -// if (generateMarkerOnError && !this.equals(initialProject)){ -// generateMarkerOnError = false; -// } -// IClasspathEntry[] immediateClasspath = -// getResolvedClasspath(ignoreUnresolvedVariable, generateMarkerOnError); -// -// IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); -// for (int i = 0, length = immediateClasspath.length; i < length; i++){ -// IClasspathEntry entry = immediateClasspath[i]; -// -// boolean isInitialProject = this.equals(initialProject); -// if (isInitialProject || entry.isExported()){ -// -// accumulatedEntries.add(entry); -// -// // recurse in project to get all its indirect exports (only consider exported entries from there on) -// if (entry.getEntryKind() == ClasspathEntry.CPE_PROJECT) { -// IResource member = workspaceRoot.findMember(entry.getPath()); -// if (member != null && member.getType() == IResource.PROJECT){ // double check if bound to project (23977) -// IProject projRsc = (IProject) member; -// if (JavaProject.hasJavaNature(projRsc)) { -// JavaProject project = (JavaProject) JavaCore.create(projRsc); -// project.computeExpandedClasspath( -// initialProject, -// ignoreUnresolvedVariable, -// generateMarkerOnError, -// visitedProjects, -// accumulatedEntries); -// } -// } -// } -// } -// } -// } + private void computeExpandedClasspath( + JavaProject initialProject, + boolean ignoreUnresolvedVariable, + boolean generateMarkerOnError, + HashSet visitedProjects, + ObjectVector accumulatedEntries) throws JavaModelException { + + if (visitedProjects.contains(this)){ + return; // break cycles if any + } + visitedProjects.add(this); + + if (generateMarkerOnError && !this.equals(initialProject)){ + generateMarkerOnError = false; + } + IClasspathEntry[] immediateClasspath = + getResolvedClasspath(ignoreUnresolvedVariable, generateMarkerOnError); + + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + for (int i = 0, length = immediateClasspath.length; i < length; i++){ + IClasspathEntry entry = immediateClasspath[i]; + + boolean isInitialProject = this.equals(initialProject); + if (isInitialProject || entry.isExported()){ + + accumulatedEntries.add(entry); + + // recurse in project to get all its indirect exports (only consider exported entries from there on) + if (entry.getEntryKind() == ClasspathEntry.CPE_PROJECT) { + IResource member = workspaceRoot.findMember(entry.getPath()); + if (member != null && member.getType() == IResource.PROJECT){ // double check if bound to project (23977) + IProject projRsc = (IProject) member; + if (JavaProject.hasJavaNature(projRsc)) { + JavaProject project = (JavaProject) PHPCore.create(projRsc); + project.computeExpandedClasspath( + initialProject, + ignoreUnresolvedVariable, + generateMarkerOnError, + visitedProjects, + accumulatedEntries); + } + } + } + } + } + } /** * Returns (local/all) the package fragment roots identified by the given project's classpath. @@ -275,140 +439,140 @@ public class JavaProject * eliminating duplicates silently. * Only works with resolved entries */ -// public IPackageFragmentRoot[] computePackageFragmentRoots(IClasspathEntry[] resolvedClasspath, boolean retrieveExportedRoots) throws JavaModelException { -// -// ObjectVector accumulatedRoots = new ObjectVector(); -// computePackageFragmentRoots( -// resolvedClasspath, -// accumulatedRoots, -// new HashSet(5), // rootIDs -// true, // inside original project -// true, // check existency -// retrieveExportedRoots); -// IPackageFragmentRoot[] rootArray = new IPackageFragmentRoot[accumulatedRoots.size()]; -// accumulatedRoots.copyInto(rootArray); -// return rootArray; -// } -// -// /** -// * Computes the package fragment roots identified by the given entry. -// * Only works with resolved entry -// */ -// public IPackageFragmentRoot[] computePackageFragmentRoots(IClasspathEntry resolvedEntry) { -// try { -// return -// computePackageFragmentRoots( -// new IClasspathEntry[]{ resolvedEntry }, -// false // don't retrieve exported roots -// ); -// } catch (JavaModelException e) { -// return new IPackageFragmentRoot[] {}; -// } -// } + public IPackageFragmentRoot[] computePackageFragmentRoots(IClasspathEntry[] resolvedClasspath, boolean retrieveExportedRoots) throws JavaModelException { + + ObjectVector accumulatedRoots = new ObjectVector(); + computePackageFragmentRoots( + resolvedClasspath, + accumulatedRoots, + new HashSet(5), // rootIDs + true, // inside original project + true, // check existency + retrieveExportedRoots); + IPackageFragmentRoot[] rootArray = new IPackageFragmentRoot[accumulatedRoots.size()]; + accumulatedRoots.copyInto(rootArray); + return rootArray; + } + + /** + * Computes the package fragment roots identified by the given entry. + * Only works with resolved entry + */ + public IPackageFragmentRoot[] computePackageFragmentRoots(IClasspathEntry resolvedEntry) { + try { + return + computePackageFragmentRoots( + new IClasspathEntry[]{ resolvedEntry }, + false // don't retrieve exported roots + ); + } catch (JavaModelException e) { + return new IPackageFragmentRoot[] {}; + } + } /** * Returns the package fragment roots identified by the given entry. In case it refers to * a project, it will follow its classpath so as to find exported roots as well. * Only works with resolved entry */ -// public void computePackageFragmentRoots( -// IClasspathEntry resolvedEntry, -// ObjectVector accumulatedRoots, -// HashSet rootIDs, -// boolean insideOriginalProject, -// boolean checkExistency, -// boolean retrieveExportedRoots) throws JavaModelException { -// -// String rootID = ((ClasspathEntry)resolvedEntry).rootID(); -// if (rootIDs.contains(rootID)) return; -// -// IPath projectPath = getProject().getFullPath(); -// IPath entryPath = resolvedEntry.getPath(); -// IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); -// -// switch(resolvedEntry.getEntryKind()){ -// -// // source folder -// case IClasspathEntry.CPE_SOURCE : -// -// if (projectPath.isPrefixOf(entryPath)){ -// if (checkExistency) { -// Object target = JavaModel.getTarget(workspaceRoot, entryPath, checkExistency); -// if (target == null) return; -// -// if (target instanceof IFolder || target instanceof IProject){ -// accumulatedRoots.add( -// getPackageFragmentRoot((IResource)target)); -// rootIDs.add(rootID); -// } -// } else { -// IPackageFragmentRoot root = getFolderPackageFragmentRoot(entryPath); -// if (root != null) { -// accumulatedRoots.add(root); -// rootIDs.add(rootID); -// } -// } -// } -// break; -// -// // internal/external JAR or folder -// case IClasspathEntry.CPE_LIBRARY : -// -// if (!insideOriginalProject && !resolvedEntry.isExported()) return; -// -// if (checkExistency) { -// Object target = JavaModel.getTarget(workspaceRoot, entryPath, checkExistency); -// if (target == null) return; -// -// if (target instanceof IResource){ -// // internal target -// IResource resource = (IResource) target; -// IPackageFragmentRoot root = getPackageFragmentRoot(resource); -// if (root != null) { -// accumulatedRoots.add(root); -// rootIDs.add(rootID); -// } -// } else { -// // external target - only JARs allowed + public void computePackageFragmentRoots( + IClasspathEntry resolvedEntry, + ObjectVector accumulatedRoots, + HashSet rootIDs, + boolean insideOriginalProject, + boolean checkExistency, + boolean retrieveExportedRoots) throws JavaModelException { + + String rootID = ((ClasspathEntry)resolvedEntry).rootID(); + if (rootIDs.contains(rootID)) return; + + IPath projectPath = getProject().getFullPath(); + IPath entryPath = resolvedEntry.getPath(); + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + + switch(resolvedEntry.getEntryKind()){ + + // source folder + case IClasspathEntry.CPE_SOURCE : + + if (projectPath.isPrefixOf(entryPath)){ + if (checkExistency) { + Object target = JavaModel.getTarget(workspaceRoot, entryPath, checkExistency); + if (target == null) return; + + if (target instanceof IFolder || target instanceof IProject){ + accumulatedRoots.add( + getPackageFragmentRoot((IResource)target)); + rootIDs.add(rootID); + } + } else { + IPackageFragmentRoot root = getFolderPackageFragmentRoot(entryPath); + if (root != null) { + accumulatedRoots.add(root); + rootIDs.add(rootID); + } + } + } + break; + + // internal/external JAR or folder + case IClasspathEntry.CPE_LIBRARY : + + if (!insideOriginalProject && !resolvedEntry.isExported()) return; + + if (checkExistency) { + Object target = JavaModel.getTarget(workspaceRoot, entryPath, checkExistency); + if (target == null) return; + + if (target instanceof IResource){ + // internal target + IResource resource = (IResource) target; + IPackageFragmentRoot root = getPackageFragmentRoot(resource); + if (root != null) { + accumulatedRoots.add(root); + rootIDs.add(rootID); + } + } else { + // external target - only JARs allowed // if (((java.io.File)target).isFile() && (Util.isArchiveFileName(entryPath.lastSegment()))) { // accumulatedRoots.add( // new JarPackageFragmentRoot(entryPath, this)); // rootIDs.add(rootID); // } -// } -// } else { -// IPackageFragmentRoot root = getPackageFragmentRoot(entryPath); -// if (root != null) { -// accumulatedRoots.add(root); -// rootIDs.add(rootID); -// } -// } -// break; -// -// // recurse into required project -// case IClasspathEntry.CPE_PROJECT : -// -// if (!retrieveExportedRoots) return; -// if (!insideOriginalProject && !resolvedEntry.isExported()) return; -// -// IResource member = workspaceRoot.findMember(entryPath); -// if (member != null && member.getType() == IResource.PROJECT){// double check if bound to project (23977) -// IProject requiredProjectRsc = (IProject) member; -// if (JavaProject.hasJavaNature(requiredProjectRsc)){ // special builder binary output -// rootIDs.add(rootID); -// JavaProject requiredProject = (JavaProject)JavaCore.create(requiredProjectRsc); -// requiredProject.computePackageFragmentRoots( -// requiredProject.getResolvedClasspath(true), -// accumulatedRoots, -// rootIDs, -// false, -// checkExistency, -// retrieveExportedRoots); -// } -// break; -// } -// } -// } + } + } else { + IPackageFragmentRoot root = getPackageFragmentRoot(entryPath); + if (root != null) { + accumulatedRoots.add(root); + rootIDs.add(rootID); + } + } + break; + + // recurse into required project + case IClasspathEntry.CPE_PROJECT : + + if (!retrieveExportedRoots) return; + if (!insideOriginalProject && !resolvedEntry.isExported()) return; + + IResource member = workspaceRoot.findMember(entryPath); + if (member != null && member.getType() == IResource.PROJECT){// double check if bound to project (23977) + IProject requiredProjectRsc = (IProject) member; + if (JavaProject.hasJavaNature(requiredProjectRsc)){ // special builder binary output + rootIDs.add(rootID); + JavaProject requiredProject = (JavaProject)PHPCore.create(requiredProjectRsc); + requiredProject.computePackageFragmentRoots( + requiredProject.getResolvedClasspath(true), + accumulatedRoots, + rootIDs, + false, + checkExistency, + retrieveExportedRoots); + } + break; + } + } + } /** * Returns (local/all) the package fragment roots identified by the given project's classpath. @@ -416,27 +580,27 @@ public class JavaProject * eliminating duplicates silently. * Only works with resolved entries */ -// public void computePackageFragmentRoots( -// IClasspathEntry[] resolvedClasspath, -// ObjectVector accumulatedRoots, -// HashSet rootIDs, -// boolean insideOriginalProject, -// boolean checkExistency, -// boolean retrieveExportedRoots) throws JavaModelException { -// -// if (insideOriginalProject){ -// rootIDs.add(rootID()); -// } -// for (int i = 0, length = resolvedClasspath.length; i < length; i++){ -// computePackageFragmentRoots( -// resolvedClasspath[i], -// accumulatedRoots, -// rootIDs, -// insideOriginalProject, -// checkExistency, -// retrieveExportedRoots); -// } -// } + public void computePackageFragmentRoots( + IClasspathEntry[] resolvedClasspath, + ObjectVector accumulatedRoots, + HashSet rootIDs, + boolean insideOriginalProject, + boolean checkExistency, + boolean retrieveExportedRoots) throws JavaModelException { + + if (insideOriginalProject){ + rootIDs.add(rootID()); + } + for (int i = 0, length = resolvedClasspath.length; i < length; i++){ + computePackageFragmentRoots( + resolvedClasspath[i], + accumulatedRoots, + rootIDs, + insideOriginalProject, + checkExistency, + retrieveExportedRoots); + } + } /** * Compute the file name to use for a given shared property @@ -446,222 +610,214 @@ public class JavaProject return '.' + qName.getLocalName(); } - /** - * Configure the project with Java nature. - */ - public void configure() throws CoreException { - - // register Java builder - addToBuildSpec(PHPeclipsePlugin.BUILDER_PARSER_ID); - } /* * Returns whether the given resource is accessible through the children or the non-Java resources of this project. * Returns true if the resource is not in the project. * Assumes that the resource is a folder or a file. */ -// public boolean contains(IResource resource) { -// -// IClasspathEntry[] classpath; -// IPath output; -// try { -// classpath = getResolvedClasspath(true); -// output = getOutputLocation(); -// } catch (JavaModelException e) { -// return false; -// } -// -// IPath fullPath = resource.getFullPath(); -// IPath innerMostOutput = output.isPrefixOf(fullPath) ? output : null; -// IClasspathEntry innerMostEntry = null; -// for (int j = 0, cpLength = classpath.length; j < cpLength; j++) { -// IClasspathEntry entry = classpath[j]; -// -// IPath entryPath = entry.getPath(); -// if ((innerMostEntry == null || innerMostEntry.getPath().isPrefixOf(entryPath)) -// && entryPath.isPrefixOf(fullPath)) { -// innerMostEntry = entry; -// } -// IPath entryOutput = classpath[j].getOutputLocation(); -// if (entryOutput != null && entryOutput.isPrefixOf(fullPath)) { -// innerMostOutput = entryOutput; -// } -// } -// if (innerMostEntry != null) { -// // special case prj==src and nested output location -// if (innerMostOutput != null && innerMostOutput.segmentCount() > 1 // output isn't project -// && innerMostEntry.getPath().segmentCount() == 1) { // 1 segment must be project name -// return false; -// } -// if (resource instanceof IFolder) { -// // folders are always included in src/lib entries -// return true; -// } -// switch (innerMostEntry.getEntryKind()) { -// case IClasspathEntry.CPE_SOURCE: -// // .class files are not visible in source folders -// return !Util.isClassFileName(fullPath.lastSegment()); -// case IClasspathEntry.CPE_LIBRARY: -// // .java files are not visible in library folders -// return !Util.isJavaFileName(fullPath.lastSegment()); -// } -// } -// if (innerMostOutput != null) { -// return false; -// } -// return true; -// } + public boolean contains(IResource resource) { + + IClasspathEntry[] classpath; + IPath output; + try { + classpath = getResolvedClasspath(true); + output = getOutputLocation(); + } catch (JavaModelException e) { + return false; + } + + IPath fullPath = resource.getFullPath(); + IPath innerMostOutput = output.isPrefixOf(fullPath) ? output : null; + IClasspathEntry innerMostEntry = null; + for (int j = 0, cpLength = classpath.length; j < cpLength; j++) { + IClasspathEntry entry = classpath[j]; + + IPath entryPath = entry.getPath(); + if ((innerMostEntry == null || innerMostEntry.getPath().isPrefixOf(entryPath)) + && entryPath.isPrefixOf(fullPath)) { + innerMostEntry = entry; + } + IPath entryOutput = classpath[j].getOutputLocation(); + if (entryOutput != null && entryOutput.isPrefixOf(fullPath)) { + innerMostOutput = entryOutput; + } + } + if (innerMostEntry != null) { + // special case prj==src and nested output location + if (innerMostOutput != null && innerMostOutput.segmentCount() > 1 // output isn't project + && innerMostEntry.getPath().segmentCount() == 1) { // 1 segment must be project name + return false; + } + if (resource instanceof IFolder) { + // folders are always included in src/lib entries + return true; + } + switch (innerMostEntry.getEntryKind()) { + case IClasspathEntry.CPE_SOURCE: + // .class files are not visible in source folders + return true; //!Util.isClassFileName(fullPath.lastSegment()); + case IClasspathEntry.CPE_LIBRARY: + // .java files are not visible in library folders + return !Util.isJavaFileName(fullPath.lastSegment()); + } + } + if (innerMostOutput != null) { + return false; + } + return true; + } /** * Record a new marker denoting a classpath problem */ -// IMarker createClasspathProblemMarker(IJavaModelStatus status) { -// -// IMarker marker = null; -// int severity; -// String[] arguments = new String[0]; -// boolean isCycleProblem = false, isClasspathFileFormatProblem = false; -// switch (status.getCode()) { -// -// case IJavaModelStatusConstants.CLASSPATH_CYCLE : -// isCycleProblem = true; -// if (JavaCore.ERROR.equals(getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true))) { -// severity = IMarker.SEVERITY_ERROR; -// } else { -// severity = IMarker.SEVERITY_WARNING; -// } -// break; -// -// case IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT : -// isClasspathFileFormatProblem = true; -// severity = IMarker.SEVERITY_ERROR; -// break; -// -// default: -// IPath path = status.getPath(); -// if (path != null) arguments = new String[] { path.toString() }; -// if (JavaCore.ERROR.equals(getOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, true))) { -// severity = IMarker.SEVERITY_ERROR; -// } else { -// severity = IMarker.SEVERITY_WARNING; -// } -// break; -// } -// -// try { -// marker = getProject().createMarker(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER); -// marker.setAttributes( -// new String[] { -// IMarker.MESSAGE, -// IMarker.SEVERITY, -// IMarker.LOCATION, -// IJavaModelMarker.CYCLE_DETECTED, -// IJavaModelMarker.CLASSPATH_FILE_FORMAT, -// IJavaModelMarker.ID, -// IJavaModelMarker.ARGUMENTS , -// }, -// new Object[] { -// status.getMessage(), -// new Integer(severity), -// Util.bind("classpath.buildPath"),//$NON-NLS-1$ -// isCycleProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$ -// isClasspathFileFormatProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$ -// new Integer(status.getCode()), -// Util.getProblemArgumentsForMarker(arguments) , -// } -// ); -// } catch (CoreException e) { -// } -// return marker; -// } + IMarker createClasspathProblemMarker(IJavaModelStatus status) { + + IMarker marker = null; + int severity; + String[] arguments = new String[0]; + boolean isCycleProblem = false, isClasspathFileFormatProblem = false; + switch (status.getCode()) { + + case IJavaModelStatusConstants.CLASSPATH_CYCLE : + isCycleProblem = true; + if (PHPCore.ERROR.equals(getOption(PHPCore.CORE_CIRCULAR_CLASSPATH, true))) { + severity = IMarker.SEVERITY_ERROR; + } else { + severity = IMarker.SEVERITY_WARNING; + } + break; + + case IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT : + isClasspathFileFormatProblem = true; + severity = IMarker.SEVERITY_ERROR; + break; + + default: + IPath path = status.getPath(); + if (path != null) arguments = new String[] { path.toString() }; + if (PHPCore.ERROR.equals(getOption(PHPCore.CORE_INCOMPLETE_CLASSPATH, true))) { + severity = IMarker.SEVERITY_ERROR; + } else { + severity = IMarker.SEVERITY_WARNING; + } + break; + } + + try { + marker = getProject().createMarker(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER); + marker.setAttributes( + new String[] { + IMarker.MESSAGE, + IMarker.SEVERITY, + IMarker.LOCATION, + IJavaModelMarker.CYCLE_DETECTED, + IJavaModelMarker.CLASSPATH_FILE_FORMAT, + IJavaModelMarker.ID, + IJavaModelMarker.ARGUMENTS , + }, + new Object[] { + status.getMessage(), + new Integer(severity), + Util.bind("classpath.buildPath"),//$NON-NLS-1$ + isCycleProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$ + isClasspathFileFormatProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$ + new Integer(status.getCode()), + Util.getProblemArgumentsForMarker(arguments) , + } + ); + } catch (CoreException e) { + } + return marker; + } /** * Returns a new element info for this element. */ -// protected OpenableElementInfo createElementInfo() { -// -// return new JavaProjectElementInfo(); -// } + protected OpenableElementInfo createElementInfo() { + + return new JavaProjectElementInfo(); + } /** * Reads and decode an XML classpath string */ -// protected IClasspathEntry[] decodeClasspath(String xmlClasspath, boolean createMarker, boolean logProblems) { -// -// ArrayList paths = new ArrayList(); -// IClasspathEntry defaultOutput = null; -// try { -// if (xmlClasspath == null) return null; -// StringReader reader = new StringReader(xmlClasspath); -// Element cpElement; -// -// try { -// DocumentBuilder parser = -// DocumentBuilderFactory.newInstance().newDocumentBuilder(); -// cpElement = parser.parse(new InputSource(reader)).getDocumentElement(); -// } catch (SAXException e) { -// throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$ -// } catch (ParserConfigurationException e) { -// throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$ -// } finally { -// reader.close(); -// } -// -// if (!cpElement.getNodeName().equalsIgnoreCase("classpath")) { //$NON-NLS-1$ -// throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$ -// } -// NodeList list = cpElement.getElementsByTagName("classpathentry"); //$NON-NLS-1$ -// int length = list.getLength(); -// -// for (int i = 0; i < length; ++i) { -// Node node = list.item(i); -// if (node.getNodeType() == Node.ELEMENT_NODE) { -// IClasspathEntry entry = ClasspathEntry.elementDecode((Element)node, this); -// if (entry != null){ -// if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) { -// defaultOutput = entry; // separate output -// } else { -// paths.add(entry); -// } -// } -// } -// } -// } catch (IOException e) { -// // bad format -// if (createMarker && this.getProject().isAccessible()) { -// this.createClasspathProblemMarker(new JavaModelStatus( -// IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, -// Util.bind("classpath.xmlFormatError", this.getElementName(), e.getMessage()))); //$NON-NLS-1$ -// } -// if (logProblems) { -// Util.log(e, -// "Exception while retrieving "+ this.getPath() //$NON-NLS-1$ -// +"/.classpath, will mark classpath as invalid"); //$NON-NLS-1$ -// } -// return INVALID_CLASSPATH; -// } catch (Assert.AssertionFailedException e) { -// // failed creating CP entries from file -// if (createMarker && this.getProject().isAccessible()) { -// this.createClasspathProblemMarker(new JavaModelStatus( -// IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, -// Util.bind("classpath.illegalEntryInClasspathFile", this.getElementName(), e.getMessage()))); //$NON-NLS-1$ -// } -// if (logProblems) { -// Util.log(e, -// "Exception while retrieving "+ this.getPath() //$NON-NLS-1$ -// +"/.classpath, will mark classpath as invalid"); //$NON-NLS-1$ -// } -// return INVALID_CLASSPATH; -// } -// int pathSize = paths.size(); -// if (pathSize > 0 || defaultOutput != null) { -// IClasspathEntry[] entries = new IClasspathEntry[pathSize + (defaultOutput == null ? 0 : 1)]; -// paths.toArray(entries); -// if (defaultOutput != null) entries[pathSize] = defaultOutput; // ensure output is last item -// return entries; -// } else { -// return null; -// } -// } + protected IClasspathEntry[] decodeClasspath(String xmlClasspath, boolean createMarker, boolean logProblems) { + + ArrayList paths = new ArrayList(); + IClasspathEntry defaultOutput = null; + try { + if (xmlClasspath == null) return null; + StringReader reader = new StringReader(xmlClasspath); + Element cpElement; + + try { + DocumentBuilder parser = + DocumentBuilderFactory.newInstance().newDocumentBuilder(); + cpElement = parser.parse(new InputSource(reader)).getDocumentElement(); + } catch (SAXException e) { + throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$ + } catch (ParserConfigurationException e) { + throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$ + } finally { + reader.close(); + } + + if (!cpElement.getNodeName().equalsIgnoreCase("classpath")) { //$NON-NLS-1$ + throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$ + } + NodeList list = cpElement.getElementsByTagName("classpathentry"); //$NON-NLS-1$ + int length = list.getLength(); + + for (int i = 0; i < length; ++i) { + Node node = list.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + IClasspathEntry entry = ClasspathEntry.elementDecode((Element)node, this); + if (entry != null){ + if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) { + defaultOutput = entry; // separate output + } else { + paths.add(entry); + } + } + } + } + } catch (IOException e) { + // bad format + if (createMarker && this.getProject().isAccessible()) { + this.createClasspathProblemMarker(new JavaModelStatus( + IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, + Util.bind("classpath.xmlFormatError", this.getElementName(), e.getMessage()))); //$NON-NLS-1$ + } + if (logProblems) { + Util.log(e, + "Exception while retrieving "+ this.getPath() //$NON-NLS-1$ + +"/.classpath, will mark classpath as invalid"); //$NON-NLS-1$ + } + return INVALID_CLASSPATH; + } catch (Assert.AssertionFailedException e) { + // failed creating CP entries from file + if (createMarker && this.getProject().isAccessible()) { + this.createClasspathProblemMarker(new JavaModelStatus( + IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, + Util.bind("classpath.illegalEntryInClasspathFile", this.getElementName(), e.getMessage()))); //$NON-NLS-1$ + } + if (logProblems) { + Util.log(e, + "Exception while retrieving "+ this.getPath() //$NON-NLS-1$ + +"/.classpath, will mark classpath as invalid"); //$NON-NLS-1$ + } + return INVALID_CLASSPATH; + } + int pathSize = paths.size(); + if (pathSize > 0 || defaultOutput != null) { + IClasspathEntry[] entries = new IClasspathEntry[pathSize + (defaultOutput == null ? 0 : 1)]; + paths.toArray(entries); + if (defaultOutput != null) entries[pathSize] = defaultOutput; // ensure output is last item + return entries; + } else { + return null; + } + } /** /** @@ -672,16 +828,16 @@ public class JavaProject // deregister Java builder removeFromBuildSpec(PHPeclipsePlugin.BUILDER_PARSER_ID); } -// -// /** -// * Returns a default class path. -// * This is the root of the project -// */ -// protected IClasspathEntry[] defaultClasspath() throws JavaModelException { -// -// return new IClasspathEntry[] { -// JavaCore.newSourceEntry(getProject().getFullPath())}; -// } + + /** + * Returns a default class path. + * This is the root of the project + */ + protected IClasspathEntry[] defaultClasspath() throws JavaModelException { + + return new IClasspathEntry[] { + PHPCore.newSourceEntry(getProject().getFullPath())}; + } /** * Returns a default output location. @@ -694,46 +850,46 @@ public class JavaProject /** * Returns the XML String encoding of the class path. */ -// protected String encodeClasspath(IClasspathEntry[] classpath, IPath outputLocation, boolean useLineSeparator) throws JavaModelException { -// -// Document document = new DocumentImpl(); -// Element cpElement = document.createElement("classpath"); //$NON-NLS-1$ -// document.appendChild(cpElement); -// -// for (int i = 0; i < classpath.length; ++i) { -// cpElement.appendChild(((ClasspathEntry)classpath[i]).elementEncode(document, getProject().getFullPath())); -// } -// -// if (outputLocation != null) { -// outputLocation = outputLocation.removeFirstSegments(1); -// outputLocation = outputLocation.makeRelative(); -// Element oElement = document.createElement("classpathentry"); //$NON-NLS-1$ -// oElement.setAttribute("kind", ClasspathEntry.kindToString(ClasspathEntry.K_OUTPUT)); //$NON-NLS-1$ -// oElement.setAttribute("path", outputLocation.toString()); //$NON-NLS-1$ -// cpElement.appendChild(oElement); -// } -// -// // produce a String output -// try { -// ByteArrayOutputStream s = new ByteArrayOutputStream(); -// OutputFormat format = new OutputFormat(); -// if (useLineSeparator) { -// format.setIndenting(true); -// format.setLineSeparator(System.getProperty("line.separator")); //$NON-NLS-1$ -// } else { -// format.setPreserveSpace(true); -// } -// Serializer serializer = -// SerializerFactory.getSerializerFactory(Method.XML).makeSerializer( -// new OutputStreamWriter(s, "UTF8"), //$NON-NLS-1$ -// format); -// serializer.asDOMSerializer().serialize(document); -// return s.toString("UTF8"); //$NON-NLS-1$ -// } catch (IOException e) { -// throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); -// } -// } -// + protected String encodeClasspath(IClasspathEntry[] classpath, IPath outputLocation, boolean useLineSeparator) throws JavaModelException { + + Document document = new DocumentImpl(); + Element cpElement = document.createElement("classpath"); //$NON-NLS-1$ + document.appendChild(cpElement); + + for (int i = 0; i < classpath.length; ++i) { + cpElement.appendChild(((ClasspathEntry)classpath[i]).elementEncode(document, getProject().getFullPath())); + } + + if (outputLocation != null) { + outputLocation = outputLocation.removeFirstSegments(1); + outputLocation = outputLocation.makeRelative(); + Element oElement = document.createElement("classpathentry"); //$NON-NLS-1$ + oElement.setAttribute("kind", ClasspathEntry.kindToString(ClasspathEntry.K_OUTPUT)); //$NON-NLS-1$ + oElement.setAttribute("path", outputLocation.toString()); //$NON-NLS-1$ + cpElement.appendChild(oElement); + } + + // produce a String output + try { + ByteArrayOutputStream s = new ByteArrayOutputStream(); + OutputFormat format = new OutputFormat(); + if (useLineSeparator) { + format.setIndenting(true); + format.setLineSeparator(System.getProperty("line.separator")); //$NON-NLS-1$ + } else { + format.setPreserveSpace(true); + } + Serializer serializer = + SerializerFactory.getSerializerFactory(Method.XML).makeSerializer( + new OutputStreamWriter(s, "UTF8"), //$NON-NLS-1$ + format); + serializer.asDOMSerializer().serialize(document); + return s.toString("UTF8"); //$NON-NLS-1$ + } catch (IOException e) { + throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); + } + } + /** * Returns true if this handle represents the same Java project * as the given handle. Two handles represent the same @@ -763,23 +919,23 @@ public class JavaProject /** * @see IJavaProject */ -// public IJavaElement findElement(IPath path) throws JavaModelException { -// -// if (path == null || path.isAbsolute()) { -// throw new JavaModelException( -// new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, path)); -// } + public IJavaElement findElement(IPath path) throws JavaModelException { + + if (path == null || path.isAbsolute()) { + throw new JavaModelException( + new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, path)); + } // try { -// -// String extension = path.getFileExtension(); -// if (extension == null) { -// String packageName = path.toString().replace(IPath.SEPARATOR, '.'); -// + + String extension = path.getFileExtension(); + if (extension == null) { + String packageName = path.toString().replace(IPath.SEPARATOR, '.'); + // IPackageFragment[] pkgFragments = // getNameLookup().findPackageFragments(packageName, false); // if (pkgFragments == null) { -// return null; -// + return null; + // } else { // // try to return one that is a child of this project // for (int i = 0, length = pkgFragments.length; i < length; i++) { @@ -792,19 +948,19 @@ public class JavaProject // // default to the first one // return pkgFragments[0]; // } -// } else if ( -// extension.equalsIgnoreCase("java") //$NON-NLS-1$ -// || extension.equalsIgnoreCase("class")) { //$NON-NLS-1$ -// IPath packagePath = path.removeLastSegments(1); -// String packageName = packagePath.toString().replace(IPath.SEPARATOR, '.'); -// String typeName = path.lastSegment(); -// typeName = typeName.substring(0, typeName.length() - extension.length() - 1); -// String qualifiedName = null; -// if (packageName.length() > 0) { -// qualifiedName = packageName + "." + typeName; //$NON-NLS-1$ -// } else { -// qualifiedName = typeName; -// } + } else if ( + extension.equalsIgnoreCase("java") //$NON-NLS-1$ + || extension.equalsIgnoreCase("class")) { //$NON-NLS-1$ + IPath packagePath = path.removeLastSegments(1); + String packageName = packagePath.toString().replace(IPath.SEPARATOR, '.'); + String typeName = path.lastSegment(); + typeName = typeName.substring(0, typeName.length() - extension.length() - 1); + String qualifiedName = null; + if (packageName.length() > 0) { + qualifiedName = packageName + "." + typeName; //$NON-NLS-1$ + } else { + qualifiedName = typeName; + } // IType type = // getNameLookup().findType( // qualifiedName, @@ -813,12 +969,12 @@ public class JavaProject // if (type != null) { // return type.getParent(); // } else { -// return null; + return null; // } -// } else { -// // unsupported extension -// return null; -// } + } else { + // unsupported extension + return null; + } // } catch (JavaModelException e) { // if (e.getStatus().getCode() // == IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST) { @@ -827,7 +983,7 @@ public class JavaProject // throw e; // } // } -// } + } /** * @see IJavaProject @@ -837,10 +993,10 @@ public class JavaProject // // return findPackageFragment0(JavaProject.canonicalizedPath(path)); // } - - /** - * non path canonicalizing version - */ +// +// /** +// * non path canonicalizing version +// */ // public IPackageFragment findPackageFragment0(IPath path) // throws JavaModelException { // @@ -850,49 +1006,49 @@ public class JavaProject /** * @see IJavaProject */ -// public IPackageFragmentRoot findPackageFragmentRoot(IPath path) -// throws JavaModelException { -// -// return findPackageFragmentRoot0(JavaProject.canonicalizedPath(path)); -// } + public IPackageFragmentRoot findPackageFragmentRoot(IPath path) + throws JavaModelException { + + return findPackageFragmentRoot0(JavaProject.canonicalizedPath(path)); + } /** * no path canonicalization */ -// public IPackageFragmentRoot findPackageFragmentRoot0(IPath path) -// throws JavaModelException { -// -// IPackageFragmentRoot[] allRoots = this.getAllPackageFragmentRoots(); -// if (!path.isAbsolute()) { -// throw new IllegalArgumentException(Util.bind("path.mustBeAbsolute")); //$NON-NLS-1$ -// } -// for (int i= 0; i < allRoots.length; i++) { -// IPackageFragmentRoot classpathRoot= allRoots[i]; -// if (classpathRoot.getPath().equals(path)) { -// return classpathRoot; -// } -// } -// return null; -// } + public IPackageFragmentRoot findPackageFragmentRoot0(IPath path) + throws JavaModelException { + + IPackageFragmentRoot[] allRoots = this.getAllPackageFragmentRoots(); + if (!path.isAbsolute()) { + throw new IllegalArgumentException(Util.bind("path.mustBeAbsolute")); //$NON-NLS-1$ + } + for (int i= 0; i < allRoots.length; i++) { + IPackageFragmentRoot classpathRoot= allRoots[i]; + if (classpathRoot.getPath().equals(path)) { + return classpathRoot; + } + } + return null; + } /** * @see IJavaProject */ -// public IPackageFragmentRoot[] findPackageFragmentRoots(IClasspathEntry entry) { -// try { -// IClasspathEntry[] classpath = this.getRawClasspath(); -// for (int i = 0, length = classpath.length; i < length; i++) { -// if (classpath[i].equals(entry)) { // entry may need to be resolved -// return -// computePackageFragmentRoots( -// getResolvedClasspath(new IClasspathEntry[] {entry}, null, true, false, null/*no reverse map*/), -// false); // don't retrieve exported roots -// } -// } -// } catch (JavaModelException e) { -// } -// return new IPackageFragmentRoot[] {}; -// } -// + public IPackageFragmentRoot[] findPackageFragmentRoots(IClasspathEntry entry) { + try { + IClasspathEntry[] classpath = this.getRawClasspath(); + for (int i = 0, length = classpath.length; i < length; i++) { + if (classpath[i].equals(entry)) { // entry may need to be resolved + return + computePackageFragmentRoots( + getResolvedClasspath(new IClasspathEntry[] {entry}, null, true, false, null/*no reverse map*/), + false); // don't retrieve exported roots + } + } + } catch (JavaModelException e) { + } + return new IPackageFragmentRoot[] {}; + } + /** * @see IJavaProject#findType(String) */ @@ -929,150 +1085,150 @@ public class JavaProject // NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES); // } // -// /** -// * Remove all markers denoting classpath problems -// */ -// protected void flushClasspathProblemMarkers(boolean flushCycleMarkers, boolean flushClasspathFormatMarkers) { -// try { -// IProject project = getProject(); -// if (project.exists()) { -// IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); -// for (int i = 0, length = markers.length; i < length; i++) { -// IMarker marker = markers[i]; -// if (flushCycleMarkers && flushClasspathFormatMarkers) { -// marker.delete(); -// } else { -// String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED); -// String classpathFileFormatAttr = (String)marker.getAttribute(IJavaModelMarker.CLASSPATH_FILE_FORMAT); -// if ((flushCycleMarkers == (cycleAttr != null && cycleAttr.equals("true"))) //$NON-NLS-1$ -// && (flushClasspathFormatMarkers == (classpathFileFormatAttr != null && classpathFileFormatAttr.equals("true")))){ //$NON-NLS-1$ -// marker.delete(); -// } -// } -// } -// } -// } catch (CoreException e) { -// } -// } -// -// /** -// * @see Openable -// */ -// protected boolean generateInfos( -// OpenableElementInfo info, -// IProgressMonitor pm, -// Map newElements, -// IResource underlyingResource) throws JavaModelException { -// -// boolean validInfo = false; -// try { -// if (getProject().isOpen()) { -// // put the info now, because computing the roots requires it -// JavaModelManager.getJavaModelManager().putInfo(this, info); -// -// // compute the pkg fragment roots -// updatePackageFragmentRoots(); -// -// // remember the timestamps of external libraries the first time they are looked up -// IClasspathEntry[] resolvedClasspath = getResolvedClasspath(true/*ignore unresolved variable*/); -// for (int i = 0, length = resolvedClasspath.length; i < length; i++) { -// IClasspathEntry entry = resolvedClasspath[i]; -// if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { -// IPath path = entry.getPath(); -// Object target = JavaModel.getTarget(ResourcesPlugin.getWorkspace().getRoot(), path, true); -// if (target instanceof java.io.File) { -// Map externalTimeStamps = JavaModelManager.getJavaModelManager().deltaProcessor.externalTimeStamps; -// if (externalTimeStamps.get(path) == null) { -// long timestamp = DeltaProcessor.getTimeStamp((java.io.File)target); -// externalTimeStamps.put(path, new Long(timestamp)); -// } -// } -// } -// } -// -// // only valid if reaches here -// validInfo = true; -// } -// } finally { -// if (!validInfo) -// JavaModelManager.getJavaModelManager().removeInfo(this); -// } -// return validInfo; -// } + /** + * Remove all markers denoting classpath problems + */ + protected void flushClasspathProblemMarkers(boolean flushCycleMarkers, boolean flushClasspathFormatMarkers) { + try { + IProject project = getProject(); + if (project.exists()) { + IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); + for (int i = 0, length = markers.length; i < length; i++) { + IMarker marker = markers[i]; + if (flushCycleMarkers && flushClasspathFormatMarkers) { + marker.delete(); + } else { + String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED); + String classpathFileFormatAttr = (String)marker.getAttribute(IJavaModelMarker.CLASSPATH_FILE_FORMAT); + if ((flushCycleMarkers == (cycleAttr != null && cycleAttr.equals("true"))) //$NON-NLS-1$ + && (flushClasspathFormatMarkers == (classpathFileFormatAttr != null && classpathFileFormatAttr.equals("true")))){ //$NON-NLS-1$ + marker.delete(); + } + } + } + } + } catch (CoreException e) { + } + } + + /** + * @see Openable + */ + protected boolean generateInfos( + OpenableElementInfo info, + IProgressMonitor pm, + Map newElements, + IResource underlyingResource) throws JavaModelException { + + boolean validInfo = false; + try { + if (getProject().isOpen()) { + // put the info now, because computing the roots requires it + JavaModelManager.getJavaModelManager().putInfo(this, info); + + // compute the pkg fragment roots + updatePackageFragmentRoots(); + + // remember the timestamps of external libraries the first time they are looked up + IClasspathEntry[] resolvedClasspath = getResolvedClasspath(true/*ignore unresolved variable*/); + for (int i = 0, length = resolvedClasspath.length; i < length; i++) { + IClasspathEntry entry = resolvedClasspath[i]; + if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { + IPath path = entry.getPath(); + Object target = JavaModel.getTarget(ResourcesPlugin.getWorkspace().getRoot(), path, true); + if (target instanceof java.io.File) { + Map externalTimeStamps = JavaModelManager.getJavaModelManager().deltaProcessor.externalTimeStamps; + if (externalTimeStamps.get(path) == null) { + long timestamp = DeltaProcessor.getTimeStamp((java.io.File)target); + externalTimeStamps.put(path, new Long(timestamp)); + } + } + } + } + + // only valid if reaches here + validInfo = true; + } + } finally { + if (!validInfo) + JavaModelManager.getJavaModelManager().removeInfo(this); + } + return validInfo; + } /** * @see IJavaProject */ -// public IPackageFragmentRoot[] getAllPackageFragmentRoots() -// throws JavaModelException { -// -// return computePackageFragmentRoots(getResolvedClasspath(true), true); -// } -// -// /** -// * Returns the classpath entry that refers to the given path -// * or null if there is no reference to the path. -// */ -// public IClasspathEntry getClasspathEntryFor(IPath path) -// throws JavaModelException { -// -// IClasspathEntry[] entries = getExpandedClasspath(true); -// for (int i = 0; i < entries.length; i++) { -// if (entries[i].getPath().equals(path)) { -// return entries[i]; -// } -// } -// return null; -// } + public IPackageFragmentRoot[] getAllPackageFragmentRoots() + throws JavaModelException { + + return computePackageFragmentRoots(getResolvedClasspath(true), true); + } + + /** + * Returns the classpath entry that refers to the given path + * or null if there is no reference to the path. + */ + public IClasspathEntry getClasspathEntryFor(IPath path) + throws JavaModelException { + + IClasspathEntry[] entries = getExpandedClasspath(true); + for (int i = 0; i < entries.length; i++) { + if (entries[i].getPath().equals(path)) { + return entries[i]; + } + } + return null; + } /* * Returns the cycle marker associated with this project or null if none. */ -// public IMarker getCycleMarker(){ -// try { -// IProject project = getProject(); -// if (project.exists()) { -// IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); -// for (int i = 0, length = markers.length; i < length; i++) { -// IMarker marker = markers[i]; -// String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED); -// if (cycleAttr != null && cycleAttr.equals("true")){ //$NON-NLS-1$ -// return marker; -// } -// } -// } -// } catch (CoreException e) { -// } -// return null; -// } -// -// /** -// * This is a helper method returning the expanded classpath for the project, as a list of classpath entries, -// * where all classpath variable entries have been resolved and substituted with their final target entries. -// * All project exports have been appended to project entries. -// */ -// public IClasspathEntry[] getExpandedClasspath(boolean ignoreUnresolvedVariable) throws JavaModelException { -// -// return getExpandedClasspath(ignoreUnresolvedVariable, false); -// } + public IMarker getCycleMarker(){ + try { + IProject project = getProject(); + if (project.exists()) { + IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); + for (int i = 0, length = markers.length; i < length; i++) { + IMarker marker = markers[i]; + String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED); + if (cycleAttr != null && cycleAttr.equals("true")){ //$NON-NLS-1$ + return marker; + } + } + } + } catch (CoreException e) { + } + return null; + } + + /** + * This is a helper method returning the expanded classpath for the project, as a list of classpath entries, + * where all classpath variable entries have been resolved and substituted with their final target entries. + * All project exports have been appended to project entries. + */ + public IClasspathEntry[] getExpandedClasspath(boolean ignoreUnresolvedVariable) throws JavaModelException { + + return getExpandedClasspath(ignoreUnresolvedVariable, false); + } /** * Internal variant which can create marker on project for invalid entries, * it will also perform classpath expansion in presence of project prerequisites * exporting their entries. */ -// public IClasspathEntry[] getExpandedClasspath( -// boolean ignoreUnresolvedVariable, -// boolean generateMarkerOnError) throws JavaModelException { -// -// ObjectVector accumulatedEntries = new ObjectVector(); -// computeExpandedClasspath(this, ignoreUnresolvedVariable, generateMarkerOnError, new HashSet(5), accumulatedEntries); -// -// IClasspathEntry[] expandedPath = new IClasspathEntry[accumulatedEntries.size()]; -// accumulatedEntries.copyInto(expandedPath); -// -// return expandedPath; -// } + public IClasspathEntry[] getExpandedClasspath( + boolean ignoreUnresolvedVariable, + boolean generateMarkerOnError) throws JavaModelException { + + ObjectVector accumulatedEntries = new ObjectVector(); + computeExpandedClasspath(this, ignoreUnresolvedVariable, generateMarkerOnError, new HashSet(5), accumulatedEntries); + + IClasspathEntry[] expandedPath = new IClasspathEntry[accumulatedEntries.size()]; + accumulatedEntries.copyInto(expandedPath); + + return expandedPath; + } /** * Returns the char that marks the start of this handles @@ -1097,31 +1253,31 @@ public class JavaProject } return null; } -// -// /** -// * Convenience method that returns the specific type of info for a Java project. -// */ -// protected JavaProjectElementInfo getJavaProjectElementInfo() -// throws JavaModelException { -// -// return (JavaProjectElementInfo) getElementInfo(); -// } + + /** + * Convenience method that returns the specific type of info for a Java project. + */ + protected JavaProjectElementInfo getJavaProjectElementInfo() + throws JavaModelException { + + return (JavaProjectElementInfo) getElementInfo(); + } /** * @see IJavaProject */ -// public NameLookup getNameLookup() throws JavaModelException { -// -// JavaProjectElementInfo info = getJavaProjectElementInfo(); -// // lock on the project info to avoid race condition -// synchronized(info){ -// NameLookup nameLookup; -// if ((nameLookup = info.getNameLookup()) == null){ -// info.setNameLookup(nameLookup = new NameLookup(this)); -// } -// return nameLookup; -// } -// } + public NameLookup getNameLookup() throws JavaModelException { + + JavaProjectElementInfo info = getJavaProjectElementInfo(); + // lock on the project info to avoid race condition + synchronized(info){ + NameLookup nameLookup; + if ((nameLookup = info.getNameLookup()) == null){ + info.setNameLookup(nameLookup = new NameLookup(this)); + } + return nameLookup; + } + } // // /** // * Returns an array of non-java resources contained in the receiver. @@ -1134,91 +1290,91 @@ public class JavaProject /** * @see org.eclipse.jdt.core.IJavaProject#getOption(String, boolean) */ -// public String getOption(String optionName, boolean inheritJavaCoreOptions) { -// -// if (JavaModelManager.OptionNames.contains(optionName)){ -// -// Preferences preferences = getPreferences(); -// if (preferences == null || preferences.isDefault(optionName)) { -// return inheritJavaCoreOptions ? PHPCore.getOption(optionName) : null; -// } -// return preferences.getString(optionName).trim(); -// } -// return null; -// } + public String getOption(String optionName, boolean inheritJavaCoreOptions) { + + if (JavaModelManager.OptionNames.contains(optionName)){ + + Preferences preferences = getPreferences(); + if (preferences == null || preferences.isDefault(optionName)) { + return inheritJavaCoreOptions ? PHPCore.getOption(optionName) : null; + } + return preferences.getString(optionName).trim(); + } + return null; + } /** * @see org.eclipse.jdt.core.IJavaProject#getOptions(boolean) */ -// public Map getOptions(boolean inheritJavaCoreOptions) { -// -// // initialize to the defaults from JavaCore options pool -// Map options = inheritJavaCoreOptions ? PHPCore.getOptions() : new Hashtable(5); -// -// Preferences preferences = getPreferences(); -// if (preferences == null) return options; // cannot do better (non-Java project) -// HashSet optionNames = JavaModelManager.OptionNames; -// -// // get preferences set to their default -// if (inheritJavaCoreOptions){ -// String[] defaultPropertyNames = preferences.defaultPropertyNames(); -// for (int i = 0; i < defaultPropertyNames.length; i++){ -// String propertyName = defaultPropertyNames[i]; -// if (optionNames.contains(propertyName)){ -// options.put(propertyName, preferences.getDefaultString(propertyName).trim()); -// } -// } -// } -// // get custom preferences not set to their default -// String[] propertyNames = preferences.propertyNames(); -// for (int i = 0; i < propertyNames.length; i++){ -// String propertyName = propertyNames[i]; -// if (optionNames.contains(propertyName)){ -// options.put(propertyName, preferences.getString(propertyName).trim()); -// } -// } -// return options; -// } + public Map getOptions(boolean inheritJavaCoreOptions) { + + // initialize to the defaults from JavaCore options pool + Map options = inheritJavaCoreOptions ? PHPCore.getOptions() : new Hashtable(5); + + Preferences preferences = getPreferences(); + if (preferences == null) return options; // cannot do better (non-Java project) + HashSet optionNames = JavaModelManager.OptionNames; + + // get preferences set to their default + if (inheritJavaCoreOptions){ + String[] defaultPropertyNames = preferences.defaultPropertyNames(); + for (int i = 0; i < defaultPropertyNames.length; i++){ + String propertyName = defaultPropertyNames[i]; + if (optionNames.contains(propertyName)){ + options.put(propertyName, preferences.getDefaultString(propertyName).trim()); + } + } + } + // get custom preferences not set to their default + String[] propertyNames = preferences.propertyNames(); + for (int i = 0; i < propertyNames.length; i++){ + String propertyName = propertyNames[i]; + if (optionNames.contains(propertyName)){ + options.put(propertyName, preferences.getString(propertyName).trim()); + } + } + return options; + } /** * @see IJavaProject */ -// public IPath getOutputLocation() throws JavaModelException { -// -// JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject); -// IPath outputLocation = perProjectInfo.outputLocation; -// if (outputLocation != null) return outputLocation; -// -// // force to read classpath - will position output location as well -// this.getRawClasspath(); -// outputLocation = perProjectInfo.outputLocation; -// if (outputLocation == null) { -// return defaultOutputLocation(); -// } -// return outputLocation; -// } -// -// /** -// * @return A handle to the package fragment root identified by the given path. -// * This method is handle-only and the element may or may not exist. Returns -// * null if unable to generate a handle from the path (for example, -// * an absolute path that has less than 1 segment. The path may be relative or -// * absolute. -// */ -// public IPackageFragmentRoot getPackageFragmentRoot(IPath path) { -// if (!path.isAbsolute()) { -// path = getPath().append(path); -// } -// int segmentCount = path.segmentCount(); -// switch (segmentCount) { -// case 0: -// return null; -// case 1: -// // default root -// return getPackageFragmentRoot(getProject()); -// default: -// // a path ending with .jar/.zip is still ambiguous and could still resolve to a source/lib folder -// // thus will try to guess based on existing resource + public IPath getOutputLocation() throws JavaModelException { + + JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject); + IPath outputLocation = perProjectInfo.outputLocation; + if (outputLocation != null) return outputLocation; + + // force to read classpath - will position output location as well + this.getRawClasspath(); + outputLocation = perProjectInfo.outputLocation; + if (outputLocation == null) { + return defaultOutputLocation(); + } + return outputLocation; + } + + /** + * @return A handle to the package fragment root identified by the given path. + * This method is handle-only and the element may or may not exist. Returns + * null if unable to generate a handle from the path (for example, + * an absolute path that has less than 1 segment. The path may be relative or + * absolute. + */ + public IPackageFragmentRoot getPackageFragmentRoot(IPath path) { + if (!path.isAbsolute()) { + path = getPath().append(path); + } + int segmentCount = path.segmentCount(); + switch (segmentCount) { + case 0: + return null; + case 1: + // default root + return getPackageFragmentRoot(getProject()); + default: + // a path ending with .jar/.zip is still ambiguous and could still resolve to a source/lib folder + // thus will try to guess based on existing resource // if (Util.isArchiveFileName(path.lastSegment())) { // IResource resource = getProject().getWorkspace().getRoot().findMember(path); // if (resource != null && resource.getType() == IResource.FOLDER){ @@ -1226,45 +1382,45 @@ public class JavaProject // } // return getPackageFragmentRoot0(path); // } else { -// return getPackageFragmentRoot(getProject().getWorkspace().getRoot().getFolder(path)); + return getPackageFragmentRoot(getProject().getWorkspace().getRoot().getFolder(path)); // } -// } -// } -// -// /** -// * The path is known to match a source/library folder entry. -// */ -// public IPackageFragmentRoot getFolderPackageFragmentRoot(IPath path) { -// if (path.segmentCount() == 1) { // default project root -// return getPackageFragmentRoot(getProject()); -// } -// return getPackageFragmentRoot(getProject().getWorkspace().getRoot().getFolder(path)); -// } -// -// /** -// * @see IJavaProject -// */ -// public IPackageFragmentRoot getPackageFragmentRoot(IResource resource) { -// -// switch (resource.getType()) { -// case IResource.FILE: + } + } + + /** + * The path is known to match a source/library folder entry. + */ + public IPackageFragmentRoot getFolderPackageFragmentRoot(IPath path) { + if (path.segmentCount() == 1) { // default project root + return getPackageFragmentRoot(getProject()); + } + return getPackageFragmentRoot(getProject().getWorkspace().getRoot().getFolder(path)); + } + + /** + * @see IJavaProject + */ + public IPackageFragmentRoot getPackageFragmentRoot(IResource resource) { + + switch (resource.getType()) { + case IResource.FILE: // if (Util.isArchiveFileName(resource.getName())) { // return new JarPackageFragmentRoot(resource, this); // } else { -// return null; + return null; // } -// case IResource.FOLDER: -// return new PackageFragmentRoot(resource, this, resource.getName()); -// case IResource.PROJECT: -// return new PackageFragmentRoot(resource, this, ""); //$NON-NLS-1$ -// default: -// return null; -// } -// } -// -// /** -// * @see IJavaProject -// */ + case IResource.FOLDER: + return new PackageFragmentRoot(resource, this, resource.getName()); + case IResource.PROJECT: + return new PackageFragmentRoot(resource, this, ""); //$NON-NLS-1$ + default: + return null; + } + } + + /** + * @see IJavaProject + */ // public IPackageFragmentRoot getPackageFragmentRoot(String jarPath) { // // return getPackageFragmentRoot0(JavaProject.canonicalizedPath(new Path(jarPath))); @@ -1277,86 +1433,86 @@ public class JavaProject // // return new JarPackageFragmentRoot(jarPath, this); // } -// -// /** -// * @see IJavaProject -// */ -// public IPackageFragmentRoot[] getPackageFragmentRoots() -// throws JavaModelException { -// -// Object[] children; -// int length; -// IPackageFragmentRoot[] roots; -// -// System.arraycopy( -// children = getChildren(), -// 0, -// roots = new IPackageFragmentRoot[length = children.length], -// 0, -// length); -// -// return roots; -// } + + /** + * @see IJavaProject + */ + public IPackageFragmentRoot[] getPackageFragmentRoots() + throws JavaModelException { + + Object[] children; + int length; + IPackageFragmentRoot[] roots; + + System.arraycopy( + children = getChildren(), + 0, + roots = new IPackageFragmentRoot[length = children.length], + 0, + length); + + return roots; + } /** * @see IJavaProject * @deprecated */ -// public IPackageFragmentRoot[] getPackageFragmentRoots(IClasspathEntry entry) { -// return findPackageFragmentRoots(entry); -// } + public IPackageFragmentRoot[] getPackageFragmentRoots(IClasspathEntry entry) { + return findPackageFragmentRoots(entry); + } /** * Returns the package fragment root prefixed by the given path, or * an empty collection if there are no such elements in the model. */ -// protected IPackageFragmentRoot[] getPackageFragmentRoots(IPath path) -// -// throws JavaModelException { -// IPackageFragmentRoot[] roots = getAllPackageFragmentRoots(); -// ArrayList matches = new ArrayList(); -// -// for (int i = 0; i < roots.length; ++i) { -// if (path.isPrefixOf(roots[i].getPath())) { -// matches.add(roots[i]); -// } -// } -// IPackageFragmentRoot[] copy = new IPackageFragmentRoot[matches.size()]; -// matches.toArray(copy); -// return copy; -// } + protected IPackageFragmentRoot[] getPackageFragmentRoots(IPath path) + + throws JavaModelException { + IPackageFragmentRoot[] roots = getAllPackageFragmentRoots(); + ArrayList matches = new ArrayList(); + + for (int i = 0; i < roots.length; ++i) { + if (path.isPrefixOf(roots[i].getPath())) { + matches.add(roots[i]); + } + } + IPackageFragmentRoot[] copy = new IPackageFragmentRoot[matches.size()]; + matches.toArray(copy); + return copy; + } /** * @see IJavaProject */ -// public IPackageFragment[] getPackageFragments() throws JavaModelException { -// -// IPackageFragmentRoot[] roots = getPackageFragmentRoots(); -// return getPackageFragmentsInRoots(roots); -// } + public IPackageFragment[] getPackageFragments() throws JavaModelException { + + IPackageFragmentRoot[] roots = getPackageFragmentRoots(); + return getPackageFragmentsInRoots(roots); + } /** * Returns all the package fragments found in the specified * package fragment roots. */ -// public IPackageFragment[] getPackageFragmentsInRoots(IPackageFragmentRoot[] roots) { -// -// ArrayList frags = new ArrayList(); -// for (int i = 0; i < roots.length; i++) { -// IPackageFragmentRoot root = roots[i]; -// try { -// IJavaElement[] rootFragments = root.getChildren(); -// for (int j = 0; j < rootFragments.length; j++) { -// frags.add(rootFragments[j]); -// } -// } catch (JavaModelException e) { -// // do nothing -// } -// } -// IPackageFragment[] fragments = new IPackageFragment[frags.size()]; -// frags.toArray(fragments); -// return fragments; -// } + public IPackageFragment[] getPackageFragmentsInRoots(IPackageFragmentRoot[] roots) { + + ArrayList frags = new ArrayList(); + for (int i = 0; i < roots.length; i++) { + IPackageFragmentRoot root = roots[i]; + try { + IJavaElement[] rootFragments = root.getChildren(); + for (int j = 0; j < rootFragments.length; j++) { + frags.add(rootFragments[j]); + } + } catch (JavaModelException e) { + // do nothing + } + } + IPackageFragment[] fragments = new IPackageFragment[frags.size()]; + frags.toArray(fragments); + return fragments; + } /* * @see IJavaElement @@ -1372,166 +1528,183 @@ public class JavaProject return fProject; } + + protected IProject getProject(String name) { + return PHPeclipsePlugin.getWorkspace().getRoot().getProject(name); + } + + public List getReferencedProjects() { + List referencedProjects = new ArrayList(); + + Iterator iterator = getLoadPathEntries().iterator(); + while (iterator.hasNext()) { + LoadPathEntry pathEntry = (LoadPathEntry) iterator.next(); + if (pathEntry.getType() == LoadPathEntry.TYPE_PROJECT) + referencedProjects.add(pathEntry.getProject()); + } + return referencedProjects; + } + /** * Returns the project custom preference pool. * Project preferences may include custom encoding. */ -// public Preferences getPreferences(){ -// IProject project = getProject(); -// if (!JavaProject.hasJavaNature(project)) return null; -// JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(project, true); -// Preferences preferences = perProjectInfo.preferences; -// if (preferences != null) return preferences; -// preferences = loadPreferences(); -// if (preferences == null) preferences = new Preferences(); -// perProjectInfo.preferences = preferences; -// return preferences; -// } + public Preferences getPreferences(){ + IProject project = getProject(); + if (!JavaProject.hasJavaNature(project)) return null; + JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(project, true); + Preferences preferences = perProjectInfo.preferences; + if (preferences != null) return preferences; + preferences = loadPreferences(); + if (preferences == null) preferences = new Preferences(); + perProjectInfo.preferences = preferences; + return preferences; + } /** * @see IJavaProject */ -// public IClasspathEntry[] getRawClasspath() throws JavaModelException { -// -// JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject); -// IClasspathEntry[] classpath = perProjectInfo.classpath; -// if (classpath != null) return classpath; -// classpath = this.readClasspathFile(false/*don't create markers*/, true/*log problems*/); -// -// // extract out the output location -// IPath outputLocation = null; -// if (classpath != null && classpath.length > 0) { -// IClasspathEntry entry = classpath[classpath.length - 1]; -// if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) { -// outputLocation = entry.getPath(); -// IClasspathEntry[] copy = new IClasspathEntry[classpath.length - 1]; -// System.arraycopy(classpath, 0, copy, 0, copy.length); -// classpath = copy; -// } -// } -// if (classpath == null) { -// return defaultClasspath(); -// } -// /* Disable validate: classpath can contain CP variables and container that need to be resolved -// if (classpath != INVALID_CLASSPATH -// && !JavaConventions.validateClasspath(this, classpath, outputLocation).isOK()) { -// classpath = INVALID_CLASSPATH; -// } -// */ -// perProjectInfo.classpath = classpath; -// perProjectInfo.outputLocation = outputLocation; -// return classpath; -// } + public IClasspathEntry[] getRawClasspath() throws JavaModelException { + + JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject); + IClasspathEntry[] classpath = perProjectInfo.classpath; + if (classpath != null) return classpath; + classpath = this.readClasspathFile(false/*don't create markers*/, true/*log problems*/); + + // extract out the output location + IPath outputLocation = null; + if (classpath != null && classpath.length > 0) { + IClasspathEntry entry = classpath[classpath.length - 1]; + if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) { + outputLocation = entry.getPath(); + IClasspathEntry[] copy = new IClasspathEntry[classpath.length - 1]; + System.arraycopy(classpath, 0, copy, 0, copy.length); + classpath = copy; + } + } + if (classpath == null) { + return defaultClasspath(); + } + /* Disable validate: classpath can contain CP variables and container that need to be resolved + if (classpath != INVALID_CLASSPATH + && !JavaConventions.validateClasspath(this, classpath, outputLocation).isOK()) { + classpath = INVALID_CLASSPATH; + } + */ + perProjectInfo.classpath = classpath; + perProjectInfo.outputLocation = outputLocation; + return classpath; + } /** * @see IJavaProject#getRequiredProjectNames */ -// public String[] getRequiredProjectNames() throws JavaModelException { -// -// return this.projectPrerequisites(getResolvedClasspath(true)); -// } + public String[] getRequiredProjectNames() throws JavaModelException { + + return this.projectPrerequisites(getResolvedClasspath(true)); + } /** * @see IJavaProject */ -// public IClasspathEntry[] getResolvedClasspath(boolean ignoreUnresolvedEntry) -// throws JavaModelException { -// -// return -// this.getResolvedClasspath( -// ignoreUnresolvedEntry, -// false); // generateMarkerOnError -// } + public IClasspathEntry[] getResolvedClasspath(boolean ignoreUnresolvedEntry) + throws JavaModelException { + + return + this.getResolvedClasspath( + ignoreUnresolvedEntry, + false); // generateMarkerOnError + } /** * Internal variant which can create marker on project for invalid entries * and caches the resolved classpath on perProjectInfo */ -// public IClasspathEntry[] getResolvedClasspath( -// boolean ignoreUnresolvedEntry, -// boolean generateMarkerOnError) -// throws JavaModelException { -// -// JavaModelManager manager = JavaModelManager.getJavaModelManager(); -// JavaModelManager.PerProjectInfo perProjectInfo = manager.getPerProjectInfoCheckExistence(fProject); -// -// // reuse cache if not needing to refresh markers or checking bound variables -// if (ignoreUnresolvedEntry && !generateMarkerOnError && perProjectInfo != null){ -// // resolved path is cached on its info -// IClasspathEntry[] infoPath = perProjectInfo.lastResolvedClasspath; -// if (infoPath != null) return infoPath; -// } -// Map reverseMap = perProjectInfo == null ? null : new HashMap(5); -// IClasspathEntry[] resolvedPath = getResolvedClasspath( -// getRawClasspath(), -// generateMarkerOnError ? getOutputLocation() : null, -// ignoreUnresolvedEntry, -// generateMarkerOnError, -// reverseMap); -// -// if (perProjectInfo != null){ -// if (perProjectInfo.classpath == null // .classpath file could not be read -// && generateMarkerOnError -// && JavaProject.hasJavaNature(fProject)) { -// this.createClasspathProblemMarker(new JavaModelStatus( -// IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, -// Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$ -// } -// -// perProjectInfo.lastResolvedClasspath = resolvedPath; -// perProjectInfo.resolvedPathToRawEntries = reverseMap; -// } -// return resolvedPath; -// } + public IClasspathEntry[] getResolvedClasspath( + boolean ignoreUnresolvedEntry, + boolean generateMarkerOnError) + throws JavaModelException { + + JavaModelManager manager = JavaModelManager.getJavaModelManager(); + JavaModelManager.PerProjectInfo perProjectInfo = manager.getPerProjectInfoCheckExistence(fProject); + + // reuse cache if not needing to refresh markers or checking bound variables + if (ignoreUnresolvedEntry && !generateMarkerOnError && perProjectInfo != null){ + // resolved path is cached on its info + IClasspathEntry[] infoPath = perProjectInfo.lastResolvedClasspath; + if (infoPath != null) return infoPath; + } + Map reverseMap = perProjectInfo == null ? null : new HashMap(5); + IClasspathEntry[] resolvedPath = getResolvedClasspath( + getRawClasspath(), + generateMarkerOnError ? getOutputLocation() : null, + ignoreUnresolvedEntry, + generateMarkerOnError, + reverseMap); + + if (perProjectInfo != null){ + if (perProjectInfo.classpath == null // .classpath file could not be read + && generateMarkerOnError + && JavaProject.hasJavaNature(fProject)) { + this.createClasspathProblemMarker(new JavaModelStatus( + IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, + Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$ + } + + perProjectInfo.lastResolvedClasspath = resolvedPath; + perProjectInfo.resolvedPathToRawEntries = reverseMap; + } + return resolvedPath; + } /** * Internal variant which can process any arbitrary classpath */ -// public IClasspathEntry[] getResolvedClasspath( -// IClasspathEntry[] classpathEntries, -// IPath projectOutputLocation, // only set if needing full classpath validation (and markers) -// boolean ignoreUnresolvedEntry, // if unresolved entries are met, should it trigger initializations -// boolean generateMarkerOnError, -// Map reverseMap) // can be null if not interested in reverse mapping -// throws JavaModelException { -// -// IJavaModelStatus status; -// if (generateMarkerOnError){ -// flushClasspathProblemMarkers(false, false); -// } -// -// int length = classpathEntries.length; -// ArrayList resolvedEntries = new ArrayList(); -// -// for (int i = 0; i < length; i++) { -// -// IClasspathEntry rawEntry = classpathEntries[i]; -// IPath resolvedPath; -// status = null; -// -// /* validation if needed */ + public IClasspathEntry[] getResolvedClasspath( + IClasspathEntry[] classpathEntries, + IPath projectOutputLocation, // only set if needing full classpath validation (and markers) + boolean ignoreUnresolvedEntry, // if unresolved entries are met, should it trigger initializations + boolean generateMarkerOnError, + Map reverseMap) // can be null if not interested in reverse mapping + throws JavaModelException { + + IJavaModelStatus status; + if (generateMarkerOnError){ + flushClasspathProblemMarkers(false, false); + } + + int length = classpathEntries.length; + ArrayList resolvedEntries = new ArrayList(); + + for (int i = 0; i < length; i++) { + + IClasspathEntry rawEntry = classpathEntries[i]; + IPath resolvedPath; + status = null; + + /* validation if needed */ // if (generateMarkerOnError || !ignoreUnresolvedEntry) { // status = JavaConventions.validateClasspathEntry(this, rawEntry, false); // if (generateMarkerOnError && !status.isOK()) createClasspathProblemMarker(status); // } -// -// switch (rawEntry.getEntryKind()){ -// -// case IClasspathEntry.CPE_VARIABLE : -// -// IClasspathEntry resolvedEntry = JavaCore.getResolvedClasspathEntry(rawEntry); -// if (resolvedEntry == null) { -// if (!ignoreUnresolvedEntry) throw new JavaModelException(status); -// } else { -// if (reverseMap != null && reverseMap.get(resolvedPath = resolvedEntry.getPath()) == null) reverseMap.put(resolvedPath , rawEntry); -// resolvedEntries.add(resolvedEntry); -// } -// break; -// + + switch (rawEntry.getEntryKind()){ + + case IClasspathEntry.CPE_VARIABLE : + + IClasspathEntry resolvedEntry = PHPCore.getResolvedClasspathEntry(rawEntry); + if (resolvedEntry == null) { + if (!ignoreUnresolvedEntry) throw new JavaModelException(status); + } else { + if (reverseMap != null && reverseMap.get(resolvedPath = resolvedEntry.getPath()) == null) reverseMap.put(resolvedPath , rawEntry); + resolvedEntries.add(resolvedEntry); + } + break; + // case IClasspathEntry.CPE_CONTAINER : // -// IClasspathContainer container = JavaCore.getClasspathContainer(rawEntry.getPath(), this); +// IClasspathContainer container = PHPCore.getClasspathContainer(rawEntry.getPath(), this); // if (container == null){ // if (!ignoreUnresolvedEntry) throw new JavaModelException(status); // break; @@ -1560,24 +1733,24 @@ public class JavaProject // resolvedEntries.add(cEntry); // } // break; -// -// default : -// -// if (reverseMap != null && reverseMap.get(resolvedPath = rawEntry.getPath()) == null) reverseMap.put(resolvedPath, rawEntry); -// resolvedEntries.add(rawEntry); -// -// } -// } -// -// IClasspathEntry[] resolvedPath = new IClasspathEntry[resolvedEntries.size()]; -// resolvedEntries.toArray(resolvedPath); -// + + default : + + if (reverseMap != null && reverseMap.get(resolvedPath = rawEntry.getPath()) == null) reverseMap.put(resolvedPath, rawEntry); + resolvedEntries.add(rawEntry); + + } + } + + IClasspathEntry[] resolvedPath = new IClasspathEntry[resolvedEntries.size()]; + resolvedEntries.toArray(resolvedPath); + // if (generateMarkerOnError && projectOutputLocation != null) { // status = JavaConventions.validateClasspath(this, resolvedPath, projectOutputLocation); // if (!status.isOK()) createClasspathProblemMarker(status); // } -// return resolvedPath; -// } + return resolvedPath; + } /* * @see IJavaElement @@ -1589,15 +1762,15 @@ public class JavaProject /** * @see IJavaProject */ -// public ISearchableNameEnvironment getSearchableNameEnvironment() -// throws JavaModelException { -// -// JavaProjectElementInfo info = getJavaProjectElementInfo(); -// if (info.getSearchableEnvironment() == null) { -// info.setSearchableEnvironment(new SearchableEnvironment(this)); -// } -// return info.getSearchableEnvironment(); -// } + public ISearchableNameEnvironment getSearchableNameEnvironment() + throws JavaModelException { + + JavaProjectElementInfo info = getJavaProjectElementInfo(); + if (info.getSearchableEnvironment() == null) { + info.setSearchableEnvironment(new SearchableEnvironment(this)); + } + return info.getSearchableEnvironment(); + } /** * Retrieve a shared property on a project. If the property is not defined, answers null. @@ -1607,15 +1780,15 @@ public class JavaProject * * @see JavaProject#setSharedProperty(String, String) */ -// public String getSharedProperty(String key) throws CoreException { -// -// String property = null; -// IFile rscFile = getProject().getFile(key); -// if (rscFile.exists()) { -// property = new String(Util.getResourceContentsAsByteArray(rscFile)); -// } -// return property; -// } + public String getSharedProperty(String key) throws CoreException { + + String property = null; + IFile rscFile = getProject().getFile(key); + if (rscFile.exists()) { + property = new String(Util.getResourceContentsAsByteArray(rscFile)); + } + return property; + } /** * @see JavaElement @@ -1636,23 +1809,23 @@ public class JavaProject /** * @see IJavaProject */ -// public boolean hasBuildState() { -// -// return JavaModelManager.getJavaModelManager().getLastBuiltState(this.getProject(), null) != null; -// } + public boolean hasBuildState() { + + return JavaModelManager.getJavaModelManager().getLastBuiltState(this.getProject(), null) != null; + } /** * @see IJavaProject */ -// public boolean hasClasspathCycle(IClasspathEntry[] preferredClasspath) { -// HashSet cycleParticipants = new HashSet(); -// updateCycleParticipants(preferredClasspath, new ArrayList(2), cycleParticipants, ResourcesPlugin.getWorkspace().getRoot(), new HashSet(2)); -// return !cycleParticipants.isEmpty(); -// } + public boolean hasClasspathCycle(IClasspathEntry[] preferredClasspath) { + HashSet cycleParticipants = new HashSet(); + updateCycleParticipants(preferredClasspath, new ArrayList(2), cycleParticipants, ResourcesPlugin.getWorkspace().getRoot(), new HashSet(2)); + return !cycleParticipants.isEmpty(); + } -// public boolean hasCycleMarker(){ -// return this.getCycleMarker() != null; -// } + public boolean hasCycleMarker(){ + return this.getCycleMarker() != null; + } public int hashCode() { return fProject.hashCode(); @@ -1674,104 +1847,104 @@ public class JavaProject /** * Answers true if the project potentially contains any source. A project which has no source is immutable. */ -// public boolean hasSource() { -// -// // look if any source folder on the classpath -// // no need for resolved path given source folder cannot be abstracted -// IClasspathEntry[] entries; -// try { -// entries = this.getRawClasspath(); -// } catch (JavaModelException e) { -// return true; // unsure -// } -// for (int i = 0, max = entries.length; i < max; i++) { -// if (entries[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) { -// return true; -// } -// } -// return false; -// } + public boolean hasSource() { + + // look if any source folder on the classpath + // no need for resolved path given source folder cannot be abstracted + IClasspathEntry[] entries; + try { + entries = this.getRawClasspath(); + } catch (JavaModelException e) { + return true; // unsure + } + for (int i = 0, max = entries.length; i < max; i++) { + if (entries[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) { + return true; + } + } + return false; + } /** * Compare current classpath with given one to see if any different. * Note that the argument classpath contains its binary output. */ -// public boolean isClasspathEqualsTo(IClasspathEntry[] newClasspath, IPath newOutputLocation, IClasspathEntry[] otherClasspathWithOutput) -// throws JavaModelException { -// -// if (otherClasspathWithOutput != null && otherClasspathWithOutput.length > 0) { -// -// int length = otherClasspathWithOutput.length; -// if (length == newClasspath.length + 1) { -// // output is amongst file entries (last one) -// -// // compare classpath entries -// for (int i = 0; i < length - 1; i++) { -// if (!otherClasspathWithOutput[i].equals(newClasspath[i])) -// return false; -// } -// // compare binary outputs -// IClasspathEntry output = otherClasspathWithOutput[length - 1]; -// if (output.getContentKind() == ClasspathEntry.K_OUTPUT -// && output.getPath().equals(newOutputLocation)) -// return true; -// } -// } -// return false; -// } + public boolean isClasspathEqualsTo(IClasspathEntry[] newClasspath, IPath newOutputLocation, IClasspathEntry[] otherClasspathWithOutput) + throws JavaModelException { + + if (otherClasspathWithOutput != null && otherClasspathWithOutput.length > 0) { + + int length = otherClasspathWithOutput.length; + if (length == newClasspath.length + 1) { + // output is amongst file entries (last one) + + // compare classpath entries + for (int i = 0; i < length - 1; i++) { + if (!otherClasspathWithOutput[i].equals(newClasspath[i])) + return false; + } + // compare binary outputs + IClasspathEntry output = otherClasspathWithOutput[length - 1]; + if (output.getContentKind() == ClasspathEntry.K_OUTPUT + && output.getPath().equals(newOutputLocation)) + return true; + } + } + return false; + } /* * @see IJavaProject */ -// public boolean isOnClasspath(IJavaElement element) { -// IPath path = element.getPath(); -// switch (element.getElementType()) { -// case IJavaElement.PACKAGE_FRAGMENT_ROOT: -// if (!((IPackageFragmentRoot)element).isArchive()) { -// // ensure that folders are only excluded if all of their children are excluded -// path = path.append("*"); //$NON-NLS-1$ -// } -// break; -// case IJavaElement.PACKAGE_FRAGMENT: -// if (!((IPackageFragmentRoot)element.getParent()).isArchive()) { -// // ensure that folders are only excluded if all of their children are excluded -// path = path.append("*"); //$NON-NLS-1$ -// } -// break; -// } -// return this.isOnClasspath(path); -// } -// private boolean isOnClasspath(IPath path) { -// IClasspathEntry[] classpath; -// try { -// classpath = this.getResolvedClasspath(true/*ignore unresolved variable*/); -// } catch(JavaModelException e){ -// return false; // not a Java project -// } -// for (int i = 0; i < classpath.length; i++) { -// IClasspathEntry entry = classpath[i]; -// if (entry.getPath().isPrefixOf(path) -// && !Util.isExcluded(path, ((ClasspathEntry)entry).fullExclusionPatternChars())) { -// return true; -// } -// } -// return false; -// } + public boolean isOnClasspath(IJavaElement element) { + IPath path = element.getPath(); + switch (element.getElementType()) { + case IJavaElement.PACKAGE_FRAGMENT_ROOT: + if (!((IPackageFragmentRoot)element).isArchive()) { + // ensure that folders are only excluded if all of their children are excluded + path = path.append("*"); //$NON-NLS-1$ + } + break; + case IJavaElement.PACKAGE_FRAGMENT: + if (!((IPackageFragmentRoot)element.getParent()).isArchive()) { + // ensure that folders are only excluded if all of their children are excluded + path = path.append("*"); //$NON-NLS-1$ + } + break; + } + return this.isOnClasspath(path); + } + private boolean isOnClasspath(IPath path) { + IClasspathEntry[] classpath; + try { + classpath = this.getResolvedClasspath(true/*ignore unresolved variable*/); + } catch(JavaModelException e){ + return false; // not a Java project + } + for (int i = 0; i < classpath.length; i++) { + IClasspathEntry entry = classpath[i]; + if (entry.getPath().isPrefixOf(path) + && !Util.isExcluded(path, ((ClasspathEntry)entry).fullExclusionPatternChars())) { + return true; + } + } + return false; + } /* * @see IJavaProject */ -// public boolean isOnClasspath(IResource resource) { -// IPath path = resource.getFullPath(); -// -// // ensure that folders are only excluded if all of their children are excluded -// if (resource.getType() == IResource.FOLDER) { -// path = path.append("*"); //$NON-NLS-1$ -// } -// -// return this.isOnClasspath(path); -// } + public boolean isOnClasspath(IResource resource) { + IPath path = resource.getFullPath(); + + // ensure that folders are only excluded if all of their children are excluded + if (resource.getType() == IResource.FOLDER) { + path = path.append("*"); //$NON-NLS-1$ + } + + return this.isOnClasspath(path); + } /* @@ -1854,36 +2027,36 @@ public class JavaProject /** * Open project if resource isn't closed */ -// protected void openWhenClosed(IProgressMonitor pm) throws JavaModelException { -// -// if (!this.fProject.isOpen()) { -// throw newNotPresentException(); -// } else { -// super.openWhenClosed(pm); -// } -// } + protected void openWhenClosed(IProgressMonitor pm) throws JavaModelException { -// public String[] projectPrerequisites(IClasspathEntry[] entries) -// throws JavaModelException { -// -// ArrayList prerequisites = new ArrayList(); -// // need resolution -// entries = getResolvedClasspath(entries, null, true, false, null/*no reverse map*/); -// for (int i = 0, length = entries.length; i < length; i++) { -// IClasspathEntry entry = entries[i]; -// if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) { -// prerequisites.add(entry.getPath().lastSegment()); -// } -// } -// int size = prerequisites.size(); -// if (size == 0) { -// return NO_PREREQUISITES; -// } else { -// String[] result = new String[size]; -// prerequisites.toArray(result); -// return result; -// } -// } + if (!this.fProject.isOpen()) { + throw newNotPresentException(); + } else { + super.openWhenClosed(pm); + } + } + + public String[] projectPrerequisites(IClasspathEntry[] entries) + throws JavaModelException { + + ArrayList prerequisites = new ArrayList(); + // need resolution + entries = getResolvedClasspath(entries, null, true, false, null/*no reverse map*/); + for (int i = 0, length = entries.length; i < length; i++) { + IClasspathEntry entry = entries[i]; + if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) { + prerequisites.add(entry.getPath().lastSegment()); + } + } + int size = prerequisites.size(); + if (size == 0) { + return NO_PREREQUISITES; + } else { + String[] result = new String[size]; + prerequisites.toArray(result); + return result; + } + } /** @@ -1891,27 +2064,27 @@ public class JavaProject * Returns null if .classfile is not present. * Returns INVALID_CLASSPATH if it has a format problem. */ -// protected IClasspathEntry[] readClasspathFile(boolean createMarker, boolean logProblems) { -// -// try { -// String xmlClasspath = getSharedProperty(CLASSPATH_FILENAME); -// if (xmlClasspath == null) return null; -// return decodeClasspath(xmlClasspath, createMarker, logProblems); -// } catch(CoreException e) { -// // file does not exist (or not accessible) -// if (createMarker && this.getProject().isAccessible()) { -// this.createClasspathProblemMarker(new JavaModelStatus( -// IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, -// Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$ -// } -// if (logProblems) { -// Util.log(e, -// "Exception while retrieving "+ this.getPath() //$NON-NLS-1$ -// +"/.classpath, will revert to default classpath"); //$NON-NLS-1$ -// } -// } -// return null; -// } + protected IClasspathEntry[] readClasspathFile(boolean createMarker, boolean logProblems) { + + try { + String xmlClasspath = getSharedProperty(CLASSPATH_FILENAME); + if (xmlClasspath == null) return null; + return decodeClasspath(xmlClasspath, createMarker, logProblems); + } catch(CoreException e) { + // file does not exist (or not accessible) + if (createMarker && this.getProject().isAccessible()) { + this.createClasspathProblemMarker(new JavaModelStatus( + IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, + Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$ + } + if (logProblems) { + Util.log(e, + "Exception while retrieving "+ this.getPath() //$NON-NLS-1$ + +"/.classpath, will revert to default classpath"); //$NON-NLS-1$ + } + } + return null; + } /** * Removes the given builder from the build spec for the given project. @@ -1955,24 +2128,24 @@ public class JavaProject * * @return Return whether the .classpath file was modified. */ -// public boolean saveClasspath(IClasspathEntry[] newClasspath, IPath newOutputLocation) throws JavaModelException { -// -// if (!getProject().exists()) return false; -// -// IClasspathEntry[] fileEntries = readClasspathFile(false /*don't create markers*/, false/*don't log problems*/); -// if (fileEntries != null && isClasspathEqualsTo(newClasspath, newOutputLocation, fileEntries)) { -// // no need to save it, it is the same -// return false; -// } -// -// // actual file saving -// try { -// setSharedProperty(CLASSPATH_FILENAME, encodeClasspath(newClasspath, newOutputLocation, true)); -// return true; -// } catch (CoreException e) { -// throw new JavaModelException(e); -// } -// } + public boolean saveClasspath(IClasspathEntry[] newClasspath, IPath newOutputLocation) throws JavaModelException { + + if (!getProject().exists()) return false; + + IClasspathEntry[] fileEntries = readClasspathFile(false /*don't create markers*/, false/*don't log problems*/); + if (fileEntries != null && isClasspathEqualsTo(newClasspath, newOutputLocation, fileEntries)) { + // no need to save it, it is the same + return false; + } + + // actual file saving + try { + setSharedProperty(CLASSPATH_FILENAME, encodeClasspath(newClasspath, newOutputLocation, true)); + return true; + } catch (CoreException e) { + throw new JavaModelException(e); + } + } /** * Save project custom preferences to shareable file (.jprefs) @@ -2055,50 +2228,50 @@ public class JavaProject /** * @see org.eclipse.jdt.core.IJavaProject#setOptions(Map) */ -// public void setOptions(Map newOptions) { -// -// Preferences preferences; -// setPreferences(preferences = new Preferences()); // always reset (26255) -// if (newOptions != null){ -// Iterator keys = newOptions.keySet().iterator(); -// while (keys.hasNext()){ -// String key = (String)keys.next(); -// if (!JavaModelManager.OptionNames.contains(key)) continue; // unrecognized option -// // no filtering for encoding (custom encoding for project is allowed) -// String value = (String)newOptions.get(key); -// preferences.setDefault(key, CUSTOM_DEFAULT_OPTION_VALUE); // empty string isn't the default (26251) -// preferences.setValue(key, value); -// } -// } -// -// // persist options -// savePreferences(preferences); -// } + public void setOptions(Map newOptions) { + + Preferences preferences; + setPreferences(preferences = new Preferences()); // always reset (26255) + if (newOptions != null){ + Iterator keys = newOptions.keySet().iterator(); + while (keys.hasNext()){ + String key = (String)keys.next(); + if (!JavaModelManager.OptionNames.contains(key)) continue; // unrecognized option + // no filtering for encoding (custom encoding for project is allowed) + String value = (String)newOptions.get(key); + preferences.setDefault(key, CUSTOM_DEFAULT_OPTION_VALUE); // empty string isn't the default (26251) + preferences.setValue(key, value); + } + } + + // persist options + savePreferences(preferences); + } /** * @see IJavaProject */ -// public void setOutputLocation(IPath path, IProgressMonitor monitor) -// throws JavaModelException { -// -// if (path == null) { -// throw new IllegalArgumentException(Util.bind("path.nullpath")); //$NON-NLS-1$ -// } -// if (path.equals(getOutputLocation())) { -// return; -// } -// this.setRawClasspath(SetClasspathOperation.ReuseClasspath, path, monitor); -// } + public void setOutputLocation(IPath path, IProgressMonitor monitor) + throws JavaModelException { + + if (path == null) { + throw new IllegalArgumentException(Util.bind("path.nullpath")); //$NON-NLS-1$ + } + if (path.equals(getOutputLocation())) { + return; + } + this.setRawClasspath(SetClasspathOperation.ReuseClasspath, path, monitor); + } /* * Set cached preferences, no preference file is saved, only info is updated */ -// public void setPreferences(Preferences preferences) { -// IProject project = getProject(); -// if (!JavaProject.hasJavaNature(project)) return; // ignore -// JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(project, true); -// perProjectInfo.preferences = preferences; -// } + public void setPreferences(Preferences preferences) { + IProject project = getProject(); + if (!JavaProject.hasJavaNature(project)) return; // ignore + JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(project, true); + perProjectInfo.preferences = preferences; + } /** * Sets the underlying kernel project of this Java project, @@ -2117,73 +2290,73 @@ public class JavaProject /** * @see IJavaProject */ -// public void setRawClasspath( -// IClasspathEntry[] entries, -// IPath outputLocation, -// IProgressMonitor monitor) -// throws JavaModelException { -// -// setRawClasspath( -// entries, -// outputLocation, -// monitor, -// true, // canChangeResource (as per API contract) -// getResolvedClasspath(true), // ignoreUnresolvedVariable -// true, // needValidation -// true); // need to save -// } + public void setRawClasspath( + IClasspathEntry[] entries, + IPath outputLocation, + IProgressMonitor monitor) + throws JavaModelException { + + setRawClasspath( + entries, + outputLocation, + monitor, + true, // canChangeResource (as per API contract) + getResolvedClasspath(true), // ignoreUnresolvedVariable + true, // needValidation + true); // need to save + } -// public void setRawClasspath( -// IClasspathEntry[] newEntries, -// IPath newOutputLocation, -// IProgressMonitor monitor, -// boolean canChangeResource, -// IClasspathEntry[] oldResolvedPath, -// boolean needValidation, -// boolean needSave) -// throws JavaModelException { -// -// JavaModelManager manager = -// (JavaModelManager) JavaModelManager.getJavaModelManager(); -// try { -// IClasspathEntry[] newRawPath = newEntries; -// if (newRawPath == null) { //are we already with the default classpath -// newRawPath = defaultClasspath(); -// } -// SetClasspathOperation op = -// new SetClasspathOperation( -// this, -// oldResolvedPath, -// newRawPath, -// newOutputLocation, -// canChangeResource, -// needValidation, -// needSave); -// runOperation(op, monitor); -// -// } catch (JavaModelException e) { -// manager.flush(); -// throw e; -// } -// } + public void setRawClasspath( + IClasspathEntry[] newEntries, + IPath newOutputLocation, + IProgressMonitor monitor, + boolean canChangeResource, + IClasspathEntry[] oldResolvedPath, + boolean needValidation, + boolean needSave) + throws JavaModelException { + + JavaModelManager manager = + (JavaModelManager) JavaModelManager.getJavaModelManager(); + try { + IClasspathEntry[] newRawPath = newEntries; + if (newRawPath == null) { //are we already with the default classpath + newRawPath = defaultClasspath(); + } + SetClasspathOperation op = + new SetClasspathOperation( + this, + oldResolvedPath, + newRawPath, + newOutputLocation, + canChangeResource, + needValidation, + needSave); + runOperation(op, monitor); + + } catch (JavaModelException e) { + manager.flush(); + throw e; + } + } /** * @see IJavaProject */ -// public void setRawClasspath( -// IClasspathEntry[] entries, -// IProgressMonitor monitor) -// throws JavaModelException { -// -// setRawClasspath( -// entries, -// SetClasspathOperation.ReuseOutputLocation, -// monitor, -// true, // canChangeResource (as per API contract) -// getResolvedClasspath(true), // ignoreUnresolvedVariable -// true, // needValidation -// true); // need to save -// } + public void setRawClasspath( + IClasspathEntry[] entries, + IProgressMonitor monitor) + throws JavaModelException { + + setRawClasspath( + entries, + SetClasspathOperation.ReuseOutputLocation, + monitor, + true, // canChangeResource (as per API contract) + getResolvedClasspath(true), // ignoreUnresolvedVariable + true, // needValidation + true); // need to save + } /** * NOTE: null specifies default classpath, and an empty @@ -2191,21 +2364,21 @@ public class JavaProject * * @exception NotPresentException if this project does not exist. */ -// protected void setRawClasspath0(IClasspathEntry[] rawEntries) -// throws JavaModelException { -// -// JavaModelManager.PerProjectInfo info = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject); -// -// synchronized (info) { -// if (rawEntries != null) { -// info.classpath = rawEntries; -// } -// -// // clear cache of resolved classpath -// info.lastResolvedClasspath = null; -// info.resolvedPathToRawEntries = null; -// } -// } + protected void setRawClasspath0(IClasspathEntry[] rawEntries) + throws JavaModelException { + + JavaModelManager.PerProjectInfo info = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject); + + synchronized (info) { + if (rawEntries != null) { + info.classpath = rawEntries; + } + + // clear cache of resolved classpath + info.lastResolvedClasspath = null; + info.resolvedPathToRawEntries = null; + } + } /** * Record a shared persistent property onto a project. @@ -2237,109 +2410,109 @@ public class JavaProject /** * Update cycle markers for all java projects */ -// public static void updateAllCycleMarkers() throws JavaModelException { -// -// //long start = System.currentTimeMillis(); -// -// JavaModelManager manager = JavaModelManager.getJavaModelManager(); -// IJavaProject[] projects = manager.getJavaModel().getJavaProjects(); -// IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); -// -// HashSet cycleParticipants = new HashSet(); -// HashSet traversed = new HashSet(); -// int length = projects.length; -// -// // compute cycle participants -// ArrayList prereqChain = new ArrayList(); -// for (int i = 0; i < length; i++){ -// JavaProject project = (JavaProject)projects[i]; -// if (!traversed.contains(project.getPath())){ -// prereqChain.clear(); -// project.updateCycleParticipants(null, prereqChain, cycleParticipants, workspaceRoot, traversed); -// } -// } -// //System.out.println("updateAllCycleMarkers: " + (System.currentTimeMillis() - start) + " ms"); -// -// for (int i = 0; i < length; i++){ -// JavaProject project = (JavaProject)projects[i]; -// -// if (cycleParticipants.contains(project.getPath())){ -// IMarker cycleMarker = project.getCycleMarker(); -// String circularCPOption = project.getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true); -// int circularCPSeverity = JavaCore.ERROR.equals(circularCPOption) ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING; -// if (cycleMarker != null) { -// // update existing cycle marker if needed -// try { -// int existingSeverity = ((Integer)cycleMarker.getAttribute(IMarker.SEVERITY)).intValue(); -// if (existingSeverity != circularCPSeverity) { -// cycleMarker.setAttribute(IMarker.SEVERITY, circularCPSeverity); -// } -// } catch (CoreException e) { -// throw new JavaModelException(e); -// } -// } else { -// // create new marker -// project.createClasspathProblemMarker( -// new JavaModelStatus(IJavaModelStatusConstants.CLASSPATH_CYCLE, project)); -// } -// } else { -// project.flushClasspathProblemMarkers(true, false); -// } -// } -// } -// -// /** -// * If a cycle is detected, then cycleParticipants contains all the paths of projects involved in this cycle (directly and indirectly), -// * no cycle if the set is empty (and started empty) -// */ -// public void updateCycleParticipants( -// IClasspathEntry[] preferredClasspath, -// ArrayList prereqChain, -// HashSet cycleParticipants, -// IWorkspaceRoot workspaceRoot, -// HashSet traversed){ -// -// IPath path = this.getPath(); -// prereqChain.add(path); -// traversed.add(path); -// try { -// IClasspathEntry[] classpath = preferredClasspath == null ? getResolvedClasspath(true) : preferredClasspath; -// for (int i = 0, length = classpath.length; i < length; i++) { -// IClasspathEntry entry = classpath[i]; -// -// if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT){ -// IPath prereqProjectPath = entry.getPath(); -// int index = cycleParticipants.contains(prereqProjectPath) ? 0 : prereqChain.indexOf(prereqProjectPath); -// if (index >= 0) { // refer to cycle, or in cycle itself -// for (int size = prereqChain.size(); index < size; index++) { -// cycleParticipants.add(prereqChain.get(index)); -// } -// } else { -// if (!traversed.contains(prereqProjectPath)) { -// IResource member = workspaceRoot.findMember(prereqProjectPath); -// if (member != null && member.getType() == IResource.PROJECT){ -// JavaProject project = (JavaProject)JavaCore.create((IProject)member); -// project.updateCycleParticipants(null, prereqChain, cycleParticipants, workspaceRoot, traversed); -// } -// } -// } -// } -// } -// } catch(JavaModelException e){ -// } -// prereqChain.remove(path); -// } + public static void updateAllCycleMarkers() throws JavaModelException { + + //long start = System.currentTimeMillis(); + + JavaModelManager manager = JavaModelManager.getJavaModelManager(); + IJavaProject[] projects = manager.getJavaModel().getJavaProjects(); + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + + HashSet cycleParticipants = new HashSet(); + HashSet traversed = new HashSet(); + int length = projects.length; + + // compute cycle participants + ArrayList prereqChain = new ArrayList(); + for (int i = 0; i < length; i++){ + JavaProject project = (JavaProject)projects[i]; + if (!traversed.contains(project.getPath())){ + prereqChain.clear(); + project.updateCycleParticipants(null, prereqChain, cycleParticipants, workspaceRoot, traversed); + } + } + //System.out.println("updateAllCycleMarkers: " + (System.currentTimeMillis() - start) + " ms"); + + for (int i = 0; i < length; i++){ + JavaProject project = (JavaProject)projects[i]; + + if (cycleParticipants.contains(project.getPath())){ + IMarker cycleMarker = project.getCycleMarker(); + String circularCPOption = project.getOption(PHPCore.CORE_CIRCULAR_CLASSPATH, true); + int circularCPSeverity = PHPCore.ERROR.equals(circularCPOption) ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING; + if (cycleMarker != null) { + // update existing cycle marker if needed + try { + int existingSeverity = ((Integer)cycleMarker.getAttribute(IMarker.SEVERITY)).intValue(); + if (existingSeverity != circularCPSeverity) { + cycleMarker.setAttribute(IMarker.SEVERITY, circularCPSeverity); + } + } catch (CoreException e) { + throw new JavaModelException(e); + } + } else { + // create new marker + project.createClasspathProblemMarker( + new JavaModelStatus(IJavaModelStatusConstants.CLASSPATH_CYCLE, project)); + } + } else { + project.flushClasspathProblemMarkers(true, false); + } + } + } + + /** + * If a cycle is detected, then cycleParticipants contains all the paths of projects involved in this cycle (directly and indirectly), + * no cycle if the set is empty (and started empty) + */ + public void updateCycleParticipants( + IClasspathEntry[] preferredClasspath, + ArrayList prereqChain, + HashSet cycleParticipants, + IWorkspaceRoot workspaceRoot, + HashSet traversed){ + + IPath path = this.getPath(); + prereqChain.add(path); + traversed.add(path); + try { + IClasspathEntry[] classpath = preferredClasspath == null ? getResolvedClasspath(true) : preferredClasspath; + for (int i = 0, length = classpath.length; i < length; i++) { + IClasspathEntry entry = classpath[i]; + + if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT){ + IPath prereqProjectPath = entry.getPath(); + int index = cycleParticipants.contains(prereqProjectPath) ? 0 : prereqChain.indexOf(prereqProjectPath); + if (index >= 0) { // refer to cycle, or in cycle itself + for (int size = prereqChain.size(); index < size; index++) { + cycleParticipants.add(prereqChain.get(index)); + } + } else { + if (!traversed.contains(prereqProjectPath)) { + IResource member = workspaceRoot.findMember(prereqProjectPath); + if (member != null && member.getType() == IResource.PROJECT){ + JavaProject project = (JavaProject)PHPCore.create((IProject)member); + project.updateCycleParticipants(null, prereqChain, cycleParticipants, workspaceRoot, traversed); + } + } + } + } + } + } catch(JavaModelException e){ + } + prereqChain.remove(path); + } /** * Reset the collection of package fragment roots (local ones) - only if opened. * Need to check *all* package fragment roots in order to reset NameLookup */ -// public void updatePackageFragmentRoots(){ -// -// if (this.isOpen()) { -// try { -// JavaProjectElementInfo info = getJavaProjectElementInfo(); -// -// IClasspathEntry[] classpath = getResolvedClasspath(true); + public void updatePackageFragmentRoots(){ + + if (this.isOpen()) { + try { + JavaProjectElementInfo info = getJavaProjectElementInfo(); + + IClasspathEntry[] classpath = getResolvedClasspath(true); // NameLookup lookup = info.getNameLookup(); // if (lookup != null){ // IPackageFragmentRoot[] oldRoots = lookup.fPackageFragmentRoots; @@ -2356,16 +2529,42 @@ public class JavaProject // } // info.setNameLookup(null); // discard name lookup (hold onto roots) // } -// info.setNonJavaResources(null); -// info.setChildren( -// computePackageFragmentRoots(classpath, false)); -// -// } catch(JavaModelException e){ -// try { -// close(); // could not do better -// } catch(JavaModelException ex){ -// } -// } -// } -// } + info.setNonJavaResources(null); + info.setChildren( + computePackageFragmentRoots(classpath, false)); + + } catch(JavaModelException e){ + try { + close(); // could not do better + } catch(JavaModelException ex){ + } + } + } + } + + public void removeLoadPathEntry(IProject anotherPHPProject) { + Iterator entries = getLoadPathEntries().iterator(); + while (entries.hasNext()) { + LoadPathEntry entry = (LoadPathEntry) entries.next(); + if (entry.getType() == LoadPathEntry.TYPE_PROJECT && entry.getProject().getName().equals(anotherPHPProject.getName())) { + getLoadPathEntries().remove(entry); + fScratched = true; + break; + } + } + } + + public void save() throws CoreException { + if (fScratched) { + InputStream xmlPath = new ByteArrayInputStream(getLoadPathXML().getBytes()); + IFile loadPathsFile = getLoadPathEntriesFile(); + if (!loadPathsFile.exists()) + loadPathsFile.create(xmlPath, true, null); + else + loadPathsFile.setContents(xmlPath, true, false, null); + + fScratched = false; + } + } + } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaProjectElementInfo.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaProjectElementInfo.java new file mode 100644 index 0000000..c4ff0ad --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaProjectElementInfo.java @@ -0,0 +1,225 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.IClasspathEntry; +import net.sourceforge.phpdt.core.JavaModelException; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +/** + * Info for IJavaProject. + *

        + * Note: getChildren() returns all of the IPackageFragmentRoots + * specified on the classpath for the project. This can include roots external to the + * project. See JavaProject#getAllPackageFragmentRoots() and + * JavaProject#getPackageFragmentRoots(). To get only the IPackageFragmentRoots + * that are internal to the project, use JavaProject#getChildren(). + */ + +/* package */ +class JavaProjectElementInfo extends OpenableElementInfo { + + /** + * The name lookup facility to use with this project. + */ + protected NameLookup fNameLookup = null; + + /** + * The searchable builder environment facility used + * with this project (doubles as the builder environment). + */ + protected SearchableEnvironment fSearchableEnvironment = null; + + /** + * A array with all the non-java resources contained by this PackageFragment + */ + private Object[] fNonJavaResources; + + /** + * Create and initialize a new instance of the receiver + */ + public JavaProjectElementInfo() { + fNonJavaResources = null; + } + + /** + * Compute the non-java resources contained in this java project. + */ + private Object[] computeNonJavaResources(JavaProject project) { + + // determine if src == project and/or if bin == project + IPath projectPath = project.getProject().getFullPath(); + boolean srcIsProject = false; + boolean binIsProject = false; + char[][] exclusionPatterns = null; + IClasspathEntry[] classpath = null; + IPath projectOutput = null; + try { + classpath = project.getResolvedClasspath(true/*ignore unresolved variable*/); + for (int i = 0; i < classpath.length; i++) { + IClasspathEntry entry = classpath[i]; + if (projectPath.equals(entry.getPath())) { + srcIsProject = true; + exclusionPatterns = ((ClasspathEntry)entry).fullExclusionPatternChars(); + break; + } + } + projectOutput = project.getOutputLocation(); + binIsProject = projectPath.equals(projectOutput); + } catch (JavaModelException e) { + // ignore + } + + Object[] nonJavaResources = new IResource[5]; + int nonJavaResourcesCounter = 0; + try { + IResource[] members = ((IContainer) project.getResource()).members(); + for (int i = 0, max = members.length; i < max; i++) { + IResource res = members[i]; + switch (res.getType()) { + case IResource.FILE : + IPath resFullPath = res.getFullPath(); + String resName = res.getName(); + + // ignore a jar file on the classpath +// if (Util.isArchiveFileName(resName) && this.isClasspathEntryOrOutputLocation(resFullPath, classpath, projectOutput)) { +// break; +// } + // ignore .java file if src == project + if (srcIsProject +// && Util.isValidCompilationUnitName(resName) + && !Util.isExcluded(res, exclusionPatterns)) { + break; + } + // ignore .class file if bin == project +// if (binIsProject && Util.isValidClassFileName(resName)) { +// break; +// } + // else add non java resource + if (nonJavaResources.length == nonJavaResourcesCounter) { + // resize + System.arraycopy( + nonJavaResources, + 0, + (nonJavaResources = new IResource[nonJavaResourcesCounter * 2]), + 0, + nonJavaResourcesCounter); + } + nonJavaResources[nonJavaResourcesCounter++] = res; + break; + case IResource.FOLDER : + resFullPath = res.getFullPath(); + + // ignore non-excluded folders on the classpath or that correspond to an output location + if ((srcIsProject && !Util.isExcluded(res, exclusionPatterns) && Util.isValidFolderNameForPackage(res.getName())) + || this.isClasspathEntryOrOutputLocation(resFullPath, classpath, projectOutput)) { + break; + } + // else add non java resource + if (nonJavaResources.length == nonJavaResourcesCounter) { + // resize + System.arraycopy( + nonJavaResources, + 0, + (nonJavaResources = new IResource[nonJavaResourcesCounter * 2]), + 0, + nonJavaResourcesCounter); + } + nonJavaResources[nonJavaResourcesCounter++] = res; + } + } + if (nonJavaResources.length != nonJavaResourcesCounter) { + System.arraycopy( + nonJavaResources, + 0, + (nonJavaResources = new IResource[nonJavaResourcesCounter]), + 0, + nonJavaResourcesCounter); + } + } catch (CoreException e) { + nonJavaResources = NO_NON_JAVA_RESOURCES; + nonJavaResourcesCounter = 0; + } + return nonJavaResources; + } + + /** + * @see IJavaProject + */ + protected NameLookup getNameLookup() { + + return fNameLookup; + } + + /** + * Returns an array of non-java resources contained in the receiver. + */ + Object[] getNonJavaResources(JavaProject project) { + + Object[] nonJavaResources = fNonJavaResources; + if (nonJavaResources == null) { + nonJavaResources = computeNonJavaResources(project); + fNonJavaResources = nonJavaResources; + } + return nonJavaResources; + } + + /** + * @see IJavaProject + */ + protected SearchableEnvironment getSearchableEnvironment() { + + return fSearchableEnvironment; + } + /* + * Returns whether the given path is a classpath entry or an output location. + */ + private boolean isClasspathEntryOrOutputLocation(IPath path, IClasspathEntry[] resolvedClasspath, IPath projectOutput) { + if (projectOutput.equals(path)) return true; + for (int i = 0, length = resolvedClasspath.length; i < length; i++) { + IClasspathEntry entry = resolvedClasspath[i]; + if (entry.getPath().equals(path)) { + return true; + } + IPath output; + if ((output = entry.getOutputLocation()) != null && output.equals(path)) { + return true; + } + } + return false; + } + + protected void setNameLookup(NameLookup newNameLookup) { + + fNameLookup = newNameLookup; + + // Reinitialize the searchable name environment since it caches + // the name lookup. + fSearchableEnvironment = null; + } + + /** + * Set the fNonJavaResources to res value + */ + synchronized void setNonJavaResources(Object[] resources) { + + fNonJavaResources = resources; + } + + protected void setSearchableEnvironment(SearchableEnvironment newSearchableEnvironment) { + + fSearchableEnvironment = newSearchableEnvironment; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Member.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Member.java new file mode 100644 index 0000000..1d53b70 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Member.java @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.util.ArrayList; + +import net.sourceforge.phpdt.core.Flags; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IMember; +import net.sourceforge.phpdt.core.IMethod; +import net.sourceforge.phpdt.core.ISourceRange; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.Signature; +import net.sourceforge.phpdt.core.jdom.IDOMNode; + +import com.sun.corba.se.internal.core.Constant; + + +/** + * @see IMember + */ + +/* package */ abstract class Member extends SourceRefElement implements IMember { +protected Member(int type, IJavaElement parent, String name) { + super(type, parent, name); +} +protected boolean areSimilarMethods( + String name1, String[] params1, + String name2, String[] params2, + String[] simpleNames1) { + + if (name1.equals(name2)) { + int params1Length = params1.length; + if (params1Length == params2.length) { + for (int i = 0; i < params1Length; i++) { + String simpleName1 = + simpleNames1 == null ? + Signature.getSimpleName(Signature.toString(params1[i])) : + simpleNames1[i]; + String simpleName2 = Signature.getSimpleName(Signature.toString(params2[i])); + if (!simpleName1.equals(simpleName2)) { + return false; + } + } + return true; + } + } + return false; +} +/** + * Converts a field constant from the compiler's representation + * to the Java Model constant representation (Number or String). + */ +//protected static Object convertConstant(Constant constant) { +// if (constant == null) +// return null; +// if (constant == Constant.NotAConstant) { +// return null; +// } +// switch (constant.typeID()) { +// case TypeIds.T_boolean : +// return constant.booleanValue() ? Boolean.TRUE : Boolean.FALSE; +// case TypeIds.T_byte : +// return new Byte(constant.byteValue()); +// case TypeIds.T_char : +// return new Character(constant.charValue()); +// case TypeIds.T_double : +// return new Double(constant.doubleValue()); +// case TypeIds.T_float : +// return new Float(constant.floatValue()); +// case TypeIds.T_int : +// return new Integer(constant.intValue()); +// case TypeIds.T_long : +// return new Long(constant.longValue()); +// case TypeIds.T_short : +// return new Short(constant.shortValue()); +// case TypeIds.T_String : +// return constant.stringValue(); +// default : +// return null; +// } +//} +/** + * @see JavaElement#equalsDOMNode + */ +protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException { + return getElementName().equals(node.getName()); +} +/* + * Helper method for SourceType.findMethods and BinaryType.findMethods + */ +protected IMethod[] findMethods(IMethod method, IMethod[] methods) { + String elementName = method.getElementName(); + String[] parameters = method.getParameterTypes(); + int paramLength = parameters.length; + String[] simpleNames = new String[paramLength]; + for (int i = 0; i < paramLength; i++) { + simpleNames[i] = Signature.getSimpleName(Signature.toString(parameters[i])); + } + ArrayList list = new ArrayList(); + next: for (int i = 0, length = methods.length; i < length; i++) { + IMethod existingMethod = methods[i]; + if (this.areSimilarMethods( + elementName, + parameters, + existingMethod.getElementName(), + existingMethod.getParameterTypes(), + simpleNames)) { + list.add(existingMethod); + } + } + int size = list.size(); + if (size == 0) { + return null; + } else { + IMethod[] result = new IMethod[size]; + list.toArray(result); + return result; + } +} +/** + * @see IMember + */ +//public IClassFile getClassFile() { +// return ((JavaElement)getParent()).getClassFile(); +//} +/** + * @see IMember + */ +public IType getDeclaringType() { + JavaElement parent = (JavaElement)getParent(); + if (parent.fLEType == TYPE) { + return (IType) parent; + } + return null; +} +/** + * @see IMember + */ +public int getFlags() throws JavaModelException { + MemberElementInfo info = (MemberElementInfo) getElementInfo(); + return info.getModifiers(); +} +/** + * @see JavaElement#getHandleMemento() + */ +protected char getHandleMementoDelimiter() { + return JavaElement.JEM_TYPE; +} +/** + * @see IMember + */ +public ISourceRange getNameRange() throws JavaModelException { + MemberElementInfo info= (MemberElementInfo)getElementInfo(); + return new SourceRange(info.getNameSourceStart(), info.getNameSourceEnd() - info.getNameSourceStart() + 1); +} +/** + * @see IMember + */ +public boolean isBinary() { + return false; +} +protected boolean isMainMethod(IMethod method) throws JavaModelException { + if ("main".equals(method.getElementName()) && Signature.SIG_VOID.equals(method.getReturnType())) { //$NON-NLS-1$ + int flags= method.getFlags(); + if (Flags.isStatic(flags) && Flags.isPublic(flags)) { + String[] paramTypes= method.getParameterTypes(); + if (paramTypes.length == 1) { + String name= Signature.toString(paramTypes[0]); + return "String[]".equals(Signature.getSimpleName(name)); //$NON-NLS-1$ + } + } + } + return false; +} +/** + * @see IJavaElement + */ +public boolean isReadOnly() { + return false; //getClassFile() != null; +} +/** + */ +public String readableName() { + + IJavaElement declaringType = getDeclaringType(); + if (declaringType != null) { + String declaringName = ((JavaElement) getDeclaringType()).readableName(); + StringBuffer buffer = new StringBuffer(declaringName); + buffer.append('.'); + buffer.append(this.getElementName()); + return buffer.toString(); + } else { + return super.readableName(); + } +} +/** + * Updates the name range for this element. + */ +protected void updateNameRange(int nameStart, int nameEnd) { + try { + MemberElementInfo info = (MemberElementInfo) getElementInfo(); + info.setNameSourceStart(nameStart); + info.setNameSourceEnd(nameEnd); + } catch (JavaModelException npe) { + return; + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/MemberElementInfo.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/MemberElementInfo.java new file mode 100644 index 0000000..33d7f16 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/MemberElementInfo.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +/** + *Element info for IMember elements. + */ +/* package */ abstract class MemberElementInfo extends SourceRefElementInfo { + /** + * The modifiers associated with this member. + * + * @see IConstants + */ + protected int flags; + + /** + * The start position of this member's name in the its + * openable's buffer. + */ + protected int nameStart= -1; + + /** + * The last position of this member's name in the its + * openable's buffer. + */ + protected int nameEnd= -1; + + /** + * This member's name + */ + protected char[] name; + /** + * @see org.eclipse.jdt.internal.compiler.env.IGenericType#getModifiers() + * @see org.eclipse.jdt.internal.compiler.env.IGenericMethod#getModifiers() + * @see org.eclipse.jdt.internal.compiler.env.IGenericField#getModifiers() + */ + public int getModifiers() { + return this.flags; + } + /** + * @see org.eclipse.jdt.internal.compiler.env.ISourceType#getName() + */ + public char[] getName() { + return this.name; + } + /** + * @see org.eclipse.jdt.internal.compiler.env.ISourceType#getNameSourceEnd() + * @see org.eclipse.jdt.internal.compiler.env.ISourceMethod#getNameSourceEnd() + * @see org.eclipse.jdt.internal.compiler.env.ISourceField#getNameSourceEnd() + */ + public int getNameSourceEnd() { + return this.nameEnd; + } + /** + * @see org.eclipse.jdt.internal.compiler.env.ISourceType#getNameSourceStart() + * @see org.eclipse.jdt.internal.compiler.env.ISourceMethod#getNameSourceStart() + * @see org.eclipse.jdt.internal.compiler.env.ISourceField#getNameSourceStart() + */ + public int getNameSourceStart() { + return this.nameStart; + } + protected void setFlags(int flags) { + this.flags = flags; + } + /** + * Sets this member's name + */ + protected void setName(char[] name) { + this.name= name; + } + /** + * Sets the last position of this member's name, relative + * to its openable's source buffer. + */ + protected void setNameSourceEnd(int end) { + this.nameEnd= end; + } + /** + * Sets the start position of this member's name, relative + * to its openable's source buffer. + */ + protected void setNameSourceStart(int start) { + this.nameStart= start; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/MoveElementsOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/MoveElementsOperation.java new file mode 100644 index 0000000..d1aad40 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/MoveElementsOperation.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.IJavaElement; + +/** + * This operation moves elements from their current + * container to a specified destination container, optionally renaming the + * elements. + * A move operation is equivalent to a copy operation, where + * the source elements are deleted after the copy. + *

        This operation can be used for reorganizing elements within the same container. + * + * @see CopyElementsOperation + */ +public class MoveElementsOperation extends CopyElementsOperation { +/** + * When executed, this operation will move the given elements to the given containers. + */ +public MoveElementsOperation(IJavaElement[] elementsToMove, IJavaElement[] destContainers, boolean force) { + super(elementsToMove, destContainers, force); +} +/** + * Returns the String to use as the main task name + * for progress monitoring. + */ +protected String getMainTaskName() { + return Util.bind("operation.moveElementProgress"); //$NON-NLS-1$ +} +/** + * @see CopyElementsOperation#isMove() + */ +protected boolean isMove() { + return true; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/MoveResourceElementsOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/MoveResourceElementsOperation.java new file mode 100644 index 0000000..943b1dc --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/MoveResourceElementsOperation.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.IJavaElement; + +/** + * This operation moves resources (package fragments and compilation units) from their current + * container to a specified destination container, optionally renaming the + * elements. + * A move resource operation is equivalent to a copy resource operation, where + * the source resources are deleted after the copy. + *

        This operation can be used for reorganizing resources within the same container. + * + * @see CopyResourceElementsOperation + */ +public class MoveResourceElementsOperation extends CopyResourceElementsOperation { +/** + * When executed, this operation will move the given elements to the given containers. + */ +public MoveResourceElementsOperation(IJavaElement[] elementsToMove, IJavaElement[] destContainers, boolean force) { + super(elementsToMove, destContainers, force); +} +/** + * @see MultiOperation + */ +protected String getMainTaskName() { + return Util.bind("operation.moveResourceProgress"); //$NON-NLS-1$ +} +/** + * @see CopyResourceElementsOperation#isMove() + */ +protected boolean isMove() { + return true; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/MultiOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/MultiOperation.java new file mode 100644 index 0000000..5fe4c7c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/MultiOperation.java @@ -0,0 +1,310 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelStatus; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.JavaModelException; + +import org.eclipse.core.runtime.IStatus; + + +/** + * This class is used to perform operations on multiple IJavaElement. + * It is responible for running each operation in turn, collecting + * the errors and merging the corresponding JavaElementDeltas. + *

        + * If several errors occured, they are collected in a multi-status + * JavaModelStatus. Otherwise, a simple JavaModelStatus + * is thrown. + */ +public abstract class MultiOperation extends JavaModelOperation { + /** + * The list of renamings supplied to the operation + */ + protected String[] fRenamingsList= null; + /** + * Table specifying the new parent for elements being + * copied/moved/renamed. + * Keyed by elements being processed, and + * values are the corresponding destination parent. + */ + protected Map fParentElements; + /** + * Table specifying insertion positions for elements being + * copied/moved/renamed. Keyed by elements being processed, and + * values are the corresponding insertion point. + * @see processElements(IProgressMonitor) + */ + protected Map fInsertBeforeElements= new HashMap(1); + /** + * This table presents the data in fRenamingList in a more + * convenient way. + */ + protected Map fRenamings; + /** + * Creates a new MultiOperation. + */ + protected MultiOperation(IJavaElement[] elementsToProcess, IJavaElement[] parentElements, boolean force) { + super(elementsToProcess, parentElements, force); + fParentElements = new HashMap(elementsToProcess.length); + if (elementsToProcess.length == parentElements.length) { + for (int i = 0; i < elementsToProcess.length; i++) { + fParentElements.put(elementsToProcess[i], parentElements[i]); + } + } else { //same destination for all elements to be moved/copied/renamed + for (int i = 0; i < elementsToProcess.length; i++) { + fParentElements.put(elementsToProcess[i], parentElements[0]); + } + } + + } + /** + * Creates a new MultiOperation on elementsToProcess. + */ + protected MultiOperation(IJavaElement[] elementsToProcess, boolean force) { + super(elementsToProcess, force); + } + /** + * Convenience method to create a JavaModelException + * embending a JavaModelStatus. + */ + protected void error(int code, IJavaElement element) throws JavaModelException { + throw new JavaModelException(new JavaModelStatus(code, element)); + } + /** + * Executes the operation. + * + * @exception JavaModelException if one or several errors occured during the operation. + * If multiple errors occured, the corresponding JavaModelStatus is a + * multi-status. Otherwise, it is a simple one. + */ + protected void executeOperation() throws JavaModelException { + processElements(); + } + /** + * Returns the parent of the element being copied/moved/renamed. + */ + protected IJavaElement getDestinationParent(IJavaElement child) { + return (IJavaElement)fParentElements.get(child); + } + /** + * Returns the name to be used by the progress monitor. + */ + protected abstract String getMainTaskName(); + /** + * Returns the new name for element, or null + * if there are no renamings specified. + */ + protected String getNewNameFor(IJavaElement element) { + if (fRenamings != null) + return (String) fRenamings.get(element); + else + return null; + } + /** + * Sets up the renamings hashtable - keys are the elements and + * values are the new name. + */ + private void initializeRenamings() { + if (fRenamingsList != null && fRenamingsList.length == fElementsToProcess.length) { + fRenamings = new HashMap(fRenamingsList.length); + for (int i = 0; i < fRenamingsList.length; i++) { + if (fRenamingsList[i] != null) { + fRenamings.put(fElementsToProcess[i], fRenamingsList[i]); + } + } + } + } + /** + * Returns true if this operation represents a move or rename, false + * if this operation represents a copy.
        + * Note: a rename is just a move within the same parent with a name change. + */ + protected boolean isMove() { + return false; + } + /** + * Returns true if this operation represents a rename, false + * if this operation represents a copy or move. + */ + protected boolean isRename() { + return false; + } + + /** + * Subclasses must implement this method to process a given IJavaElement. + */ + protected abstract void processElement(IJavaElement element) throws JavaModelException; + /** + * Processes all the IJavaElements in turn, collecting errors + * and updating the progress monitor. + * + * @exception JavaModelException if one or several operation(s) was unable to + * be completed. + */ + protected void processElements() throws JavaModelException { + beginTask(getMainTaskName(), fElementsToProcess.length); + IJavaModelStatus[] errors = new IJavaModelStatus[3]; + int errorsCounter = 0; + for (int i = 0; i < fElementsToProcess.length; i++) { + try { + verify(fElementsToProcess[i]); + processElement(fElementsToProcess[i]); + } catch (JavaModelException jme) { + if (errorsCounter == errors.length) { + // resize + System.arraycopy(errors, 0, (errors = new IJavaModelStatus[errorsCounter*2]), 0, errorsCounter); + } + errors[errorsCounter++] = jme.getJavaModelStatus(); + } finally { + worked(1); + } + } + done(); + if (errorsCounter == 1) { + throw new JavaModelException(errors[0]); + } else if (errorsCounter > 1) { + if (errorsCounter != errors.length) { + // resize + System.arraycopy(errors, 0, (errors = new IJavaModelStatus[errorsCounter]), 0, errorsCounter); + } + throw new JavaModelException(JavaModelStatus.newMultiStatus(errors)); + } + } + /** + * Sets the insertion position in the new container for the modified element. The element + * being modified will be inserted before the specified new sibling. The given sibling + * must be a child of the destination container specified for the modified element. + * The default is null, which indicates that the element is to be + * inserted at the end of the container. + */ + public void setInsertBefore(IJavaElement modifiedElement, IJavaElement newSibling) { + fInsertBeforeElements.put(modifiedElement, newSibling); + } + /** + * Sets the new names to use for each element being copied. The renamings + * correspond to the elements being processed, and the number of + * renamings must match the number of elements being processed. + * A null entry in the list indicates that an element + * is not to be renamed. + * + *

        Note that some renamings may not be used. If both a parent + * and a child have been selected for copy/move, only the parent + * is changed. Therefore, if a new name is specified for the child, + * the child's name will not be changed. + */ + public void setRenamings(String[] renamings) { + fRenamingsList = renamings; + initializeRenamings(); + } + /** + * This method is called for each IJavaElement before + * processElement. It should check that this element + * can be processed. + */ + protected abstract void verify(IJavaElement element) throws JavaModelException; + /** + * Verifies that the destination specified for the element is valid for the types of the + * element and destination. + */ + protected void verifyDestination(IJavaElement element, IJavaElement destination) throws JavaModelException { + if (destination == null || !destination.exists()) + error(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, destination); + + int destType = destination.getElementType(); + switch (element.getElementType()) { + case IJavaElement.PACKAGE_DECLARATION : + case IJavaElement.IMPORT_DECLARATION : + if (destType != IJavaElement.COMPILATION_UNIT) + error(IJavaModelStatusConstants.INVALID_DESTINATION, element); + break; + case IJavaElement.TYPE : + if (destType != IJavaElement.COMPILATION_UNIT && destType != IJavaElement.TYPE) + error(IJavaModelStatusConstants.INVALID_DESTINATION, element); + break; + case IJavaElement.METHOD : + case IJavaElement.FIELD : +// case IJavaElement.INITIALIZER : +// if (destType != IJavaElement.TYPE || destination instanceof BinaryType) +// error(IJavaModelStatusConstants.INVALID_DESTINATION, element); +// break; + case IJavaElement.COMPILATION_UNIT : + if (destType != IJavaElement.PACKAGE_FRAGMENT) + error(IJavaModelStatusConstants.INVALID_DESTINATION, element); + else if (isMove() && ((ICompilationUnit) element).isWorkingCopy()) + error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element); + break; + case IJavaElement.PACKAGE_FRAGMENT : + IPackageFragment fragment = (IPackageFragment) element; + IJavaElement parent = fragment.getParent(); + if (parent.isReadOnly()) + error(IJavaModelStatusConstants.READ_ONLY, element); + else if (destType != IJavaElement.PACKAGE_FRAGMENT_ROOT) + error(IJavaModelStatusConstants.INVALID_DESTINATION, element); + break; + default : + error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element); + } + } + /** + * Verify that the new name specified for element is + * valid for that type of Java element. + */ + protected void verifyRenaming(IJavaElement element) throws JavaModelException { + String newName = getNewNameFor(element); + boolean isValid = true; + + switch (element.getElementType()) { + case IJavaElement.PACKAGE_FRAGMENT : + if (element.getElementName().equals(IPackageFragment.DEFAULT_PACKAGE_NAME)) { + // don't allow renaming of default package (see PR #1G47GUM) + throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, element)); + } +// isValid = JavaConventions.validatePackageName(newName).getSeverity() != IStatus.ERROR; + isValid = true; + break; + case IJavaElement.COMPILATION_UNIT : +// isValid = JavaConventions.validateCompilationUnitName(newName).getSeverity() != IStatus.ERROR; + isValid = true; + break; + case IJavaElement.INITIALIZER : + isValid = false; //cannot rename initializers + break; + default : +// isValid = JavaConventions.validateIdentifier(newName).getSeverity() != IStatus.ERROR; + isValid = true; + break; + } + + if (!isValid) { + throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_NAME, element, newName)); + } + } + /** + * Verifies that the positioning sibling specified for the element is exists and + * its parent is the destination container of this element. + */ + protected void verifySibling(IJavaElement element, IJavaElement destination) throws JavaModelException { + IJavaElement insertBeforeElement = (IJavaElement) fInsertBeforeElements.get(element); + if (insertBeforeElement != null) { + if (!insertBeforeElement.exists() || !insertBeforeElement.getParent().equals(destination)) { + error(IJavaModelStatusConstants.INVALID_SIBLING, insertBeforeElement); + } + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/NameLookup.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/NameLookup.java new file mode 100644 index 0000000..d32a9d3 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/NameLookup.java @@ -0,0 +1,765 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.phpdt.core.IClasspathEntry; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.IWorkingCopy; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.internal.core.util.PerThreadObject; +import net.sourceforge.phpeclipse.PHPCore; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +/** + * A NameLookup provides name resolution within a Java project. + * The name lookup facility uses the project's classpath to prioritize the + * order in which package fragments are searched when resolving a name. + * + *

        Name lookup only returns a handle when the named element actually + * exists in the model; otherwise null is returned. + * + *

        There are two logical sets of methods within this interface. Methods + * which start with find* are intended to be convenience methods for quickly + * finding an element within another element; for instance, for finding a class within a + * package. The other set of methods all begin with seek*. These methods + * do comprehensive searches of the IJavaProject returning hits + * in real time through an IJavaElementRequestor. + * + */ +public class NameLookup { + /** + * Accept flag for specifying classes. + */ + public static final int ACCEPT_CLASSES = 0x00000002; + + /** + * Accept flag for specifying interfaces. + */ + public static final int ACCEPT_INTERFACES = 0x00000004; + + /** + * The IPackageFragmentRoot's associated + * with the classpath of this NameLookup facility's + * project. + */ + protected IPackageFragmentRoot[] fPackageFragmentRoots= null; + + /** + * Table that maps package names to lists of package fragments for + * all package fragments in the package fragment roots known + * by this name lookup facility. To allow > 1 package fragment + * with the same name, values are arrays of package fragments + * ordered as they appear on the classpath. + */ + protected Map fPackageFragments; + + /** + * The IWorkspace that this NameLookup + * is configure within. + */ + protected IWorkspace workspace; + + /** + * A map from compilation unit handles to units to look inside (compilation + * units or working copies). + * Allows working copies to take precedence over compilation units. + * The cache is a 2-level cache, first keyed by thread. + */ + protected PerThreadObject unitsToLookInside = new PerThreadObject(); + + public NameLookup(IJavaProject project) throws JavaModelException { + configureFromProject(project); + } + + /** + * Returns true if:

          + *
        • the given type is an existing class and the flag's ACCEPT_CLASSES + * bit is on + *
        • the given type is an existing interface and the ACCEPT_INTERFACES + * bit is on + *
        • neither the ACCEPT_CLASSES or ACCEPT_INTERFACES + * bit is on + *
        + * Otherwise, false is returned. + */ + protected boolean acceptType(IType type, int acceptFlags) { + if (acceptFlags == 0) + return true; // no flags, always accepted + try { + if (type.isClass()) { + return (acceptFlags & ACCEPT_CLASSES) != 0; + } else { + return (acceptFlags & ACCEPT_INTERFACES) != 0; + } + } catch (JavaModelException npe) { + return false; // the class is not present, do not accept. + } + } + + /** + * Configures this NameLookup based on the + * info of the given IJavaProject. + * + * @throws JavaModelException if the IJavaProject has no classpath. + */ + private void configureFromProject(IJavaProject project) throws JavaModelException { + workspace= ResourcesPlugin.getWorkspace(); + fPackageFragmentRoots= ((JavaProject) project).getAllPackageFragmentRoots(); + fPackageFragments= new HashMap(); + IPackageFragment[] frags = this.getPackageFragmentsInRoots(fPackageFragmentRoots, project); + for (int i= 0; i < frags.length; i++) { + IPackageFragment fragment= frags[i]; + IPackageFragment[] entry= (IPackageFragment[]) fPackageFragments.get(fragment.getElementName()); + if (entry == null) { + entry= new IPackageFragment[1]; + entry[0]= fragment; + fPackageFragments.put(fragment.getElementName(), entry); + } else { + IPackageFragment[] copy= new IPackageFragment[entry.length + 1]; + System.arraycopy(entry, 0, copy, 0, entry.length); + copy[entry.length]= fragment; + fPackageFragments.put(fragment.getElementName(), copy); + } + } + } + + /** + * Finds every type in the project whose simple name matches + * the prefix, informing the requestor of each hit. The requestor + * is polled for cancellation at regular intervals. + * + *

        The partialMatch argument indicates partial matches + * should be considered. + */ + private void findAllTypes(String prefix, boolean partialMatch, int acceptFlags, IJavaElementRequestor requestor) { + int count= fPackageFragmentRoots.length; + for (int i= 0; i < count; i++) { + if (requestor.isCanceled()) + return; + IPackageFragmentRoot root= fPackageFragmentRoots[i]; + IJavaElement[] packages= null; + try { + packages= root.getChildren(); + } catch (JavaModelException npe) { + continue; // the root is not present, continue; + } + if (packages != null) { + for (int j= 0, packageCount= packages.length; j < packageCount; j++) { + if (requestor.isCanceled()) + return; + seekTypes(prefix, (IPackageFragment) packages[j], partialMatch, acceptFlags, requestor); + } + } + } + } + + /** + * Returns the ICompilationUnit which defines the type + * named qualifiedTypeName, or null if + * none exists. The domain of the search is bounded by the classpath + * of the IJavaProject this NameLookup was + * obtained from. + *

        + * The name must be fully qualified (eg "java.lang.Object", "java.util.Hashtable$Entry") + */ + public ICompilationUnit findCompilationUnit(String qualifiedTypeName) { + String pkgName= IPackageFragment.DEFAULT_PACKAGE_NAME; + String cuName= qualifiedTypeName; + + int index= qualifiedTypeName.lastIndexOf('.'); + if (index != -1) { + pkgName= qualifiedTypeName.substring(0, index); + cuName= qualifiedTypeName.substring(index + 1); + } + index= cuName.indexOf('$'); + if (index != -1) { + cuName= cuName.substring(0, index); + } + cuName += ".java"; //$NON-NLS-1$ + IPackageFragment[] frags= (IPackageFragment[]) fPackageFragments.get(pkgName); + if (frags != null) { + for (int i= 0; i < frags.length; i++) { + IPackageFragment frag= frags[i]; +// if (!(frag instanceof JarPackageFragment)) { +// ICompilationUnit cu= frag.getCompilationUnit(cuName); +// if (cu != null && cu.exists()) { +// return cu; +// } +// } + } + } + return null; + } + + /** + * Returns the package fragment whose path matches the given + * (absolute) path, or null if none exist. The domain of + * the search is bounded by the classpath of the IJavaProject + * this NameLookup was obtained from. + * The path can be: + * - internal to the workbench: "/Project/src" + * - external to the workbench: "c:/jdk/classes.zip/java/lang" + */ + public IPackageFragment findPackageFragment(IPath path) { + if (!path.isAbsolute()) { + throw new IllegalArgumentException(Util.bind("path.mustBeAbsolute")); //$NON-NLS-1$ + } +/* + * this code should rather use the package fragment map to find the candidate package, then + * check if the respective enclosing root maps to the one on this given IPath. + */ + IResource possibleFragment = workspace.getRoot().findMember(path); + if (possibleFragment == null) { + //external jar + for (int i = 0; i < fPackageFragmentRoots.length; i++) { + IPackageFragmentRoot root = fPackageFragmentRoots[i]; + if (!root.isExternal()) { + continue; + } + IPath rootPath = root.getPath(); + int matchingCount = rootPath.matchingFirstSegments(path); + if (matchingCount != 0) { + String name = path.toOSString(); + // + 1 is for the File.separatorChar + name = name.substring(rootPath.toOSString().length() + 1, name.length()); + name = name.replace(File.separatorChar, '.'); + IJavaElement[] list = null; + try { + list = root.getChildren(); + } catch (JavaModelException npe) { + continue; // the package fragment root is not present; + } + int elementCount = list.length; + for (int j = 0; j < elementCount; j++) { + IPackageFragment packageFragment = (IPackageFragment) list[j]; + if (nameMatches(name, packageFragment, false)) { + return packageFragment; + } + } + } + } + } else { + IJavaElement fromFactory = PHPCore.create(possibleFragment); + if (fromFactory == null) { + return null; + } + if (fromFactory instanceof IPackageFragment) { + return (IPackageFragment) fromFactory; + } else + if (fromFactory instanceof IJavaProject) { + // default package in a default root + JavaProject project = (JavaProject) fromFactory; + try { + IClasspathEntry entry = project.getClasspathEntryFor(path); + if (entry != null) { + IPackageFragmentRoot root = + project.getPackageFragmentRoot(project.getResource()); + IPackageFragment[] pkgs = (IPackageFragment[]) fPackageFragments.get(IPackageFragment.DEFAULT_PACKAGE_NAME); + if (pkgs == null) { + return null; + } + for (int i = 0; i < pkgs.length; i++) { + if (pkgs[i].getParent().equals(root)) { + return pkgs[i]; + } + } + } + } catch (JavaModelException e) { + return null; + } + } + } + return null; + } + + /** + * Returns the package fragments whose name matches the given + * (qualified) name, or null if none exist. + * + * The name can be: + * - empty: "" + * - qualified: "pack.pack1.pack2" + * @param partialMatch partial name matches qualify when true, + * only exact name matches qualify when false + */ + public IPackageFragment[] findPackageFragments(String name, boolean partialMatch) { + int count= fPackageFragmentRoots.length; + if (partialMatch) { + name= name.toLowerCase(); + for (int i= 0; i < count; i++) { + IPackageFragmentRoot root= fPackageFragmentRoots[i]; + IJavaElement[] list= null; + try { + list= root.getChildren(); + } catch (JavaModelException npe) { + continue; // the package fragment root is not present; + } + int elementCount= list.length; + IPackageFragment[] result = new IPackageFragment[elementCount]; + int resultLength = 0; + for (int j= 0; j < elementCount; j++) { + IPackageFragment packageFragment= (IPackageFragment) list[j]; + if (nameMatches(name, packageFragment, true)) { + result[resultLength++] = packageFragment; + } + } + if (resultLength > 0) { + System.arraycopy(result, 0, result = new IPackageFragment[resultLength], 0, resultLength); + return result; + } else { + return null; + } + } + } else { + IPackageFragment[] fragments= (IPackageFragment[]) fPackageFragments.get(name); + if (fragments != null) { + IPackageFragment[] result = new IPackageFragment[fragments.length]; + int resultLength = 0; + for (int i= 0; i < fragments.length; i++) { + IPackageFragment packageFragment= fragments[i]; + result[resultLength++] = packageFragment; + } + if (resultLength > 0) { + System.arraycopy(result, 0, result = new IPackageFragment[resultLength], 0, resultLength); + return result; + } else { + return null; + } + } + } + return null; + } + + /** + * + */ + public IType findType(String typeName, String packageName, boolean partialMatch, int acceptFlags) { + if (packageName == null) { + packageName= IPackageFragment.DEFAULT_PACKAGE_NAME; + } + JavaElementRequestor elementRequestor = new JavaElementRequestor(); + seekPackageFragments(packageName, false, elementRequestor); + IPackageFragment[] packages= elementRequestor.getPackageFragments(); + + for (int i= 0, length= packages.length; i < length; i++) { + IType type= findType(typeName, packages[i], partialMatch, acceptFlags); + if (type != null) + return type; + } + return null; + } + /** + * Returns all the package fragments found in the specified + * package fragment roots. Make sure the returned fragments have the given + * project as great parent. This ensures the name lookup will not refer to another + * project (through jar package fragment roots) + */ + private IPackageFragment[] getPackageFragmentsInRoots(IPackageFragmentRoot[] roots, IJavaProject project) { + + // The following code assumes that all the roots have the given project as their parent + ArrayList frags = new ArrayList(); + for (int i = 0; i < roots.length; i++) { + IPackageFragmentRoot root = roots[i]; + try { + IJavaElement[] children = root.getChildren(); + + /* 2 jar package fragment roots can be equals but not belonging + to the same project. As a result, they share the same element info. + So this jar package fragment root could get the children of + another jar package fragment root. + The following code ensures that the children of this jar package + fragment root have the given project as a great parent. + */ + int length = children.length; + if (length == 0) continue; + if (children[0].getParent().getParent().equals(project)) { + // the children have the right parent, simply add them to the list + for (int j = 0; j < length; j++) { + frags.add(children[j]); + } + } else { + // create a new handle with the root as the parent + for (int j = 0; j < length; j++) { + frags.add(root.getPackageFragment(children[j].getElementName())); + } + } + } catch (JavaModelException e) { + // do nothing + } + } + IPackageFragment[] fragments = new IPackageFragment[frags.size()]; + frags.toArray(fragments); + return fragments; + } + + /** + * Returns the first type in the given package whose name + * matches the given (unqualified) name, or null if none + * exist. Specifying a null package will result in no matches. + * The domain of the search is bounded by the Java project from which + * this name lookup was obtained. + * + * @param name the name of the type to find + * @param pkg the package to search + * @param partialMatch partial name matches qualify when true, + * only exact name matches qualify when false + * @param acceptFlags a bit mask describing if classes, interfaces or both classes and interfaces + * are desired results. If no flags are specified, all types are returned. + * + * @see #ACCEPT_CLASSES + * @see #ACCEPT_INTERFACES + */ + public IType findType(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags) { + if (pkg == null) { + return null; + } + // Return first found (ignore duplicates). +//synchronized(JavaModelManager.getJavaModelManager()){ +// SingleTypeRequestor typeRequestor = new SingleTypeRequestor(); +// seekTypes(name, pkg, partialMatch, acceptFlags, typeRequestor); +// IType type= typeRequestor.getType(); +// return type; +//} + return null; + } + + /** + * Returns the type specified by the qualified name, or null + * if none exist. The domain of + * the search is bounded by the Java project from which this name lookup was obtained. + * + * @param name the name of the type to find + * @param partialMatch partial name matches qualify when true, + * only exact name matches qualify when false + * @param acceptFlags a bit mask describing if classes, interfaces or both classes and interfaces + * are desired results. If no flags are specified, all types are returned. + * + * @see #ACCEPT_CLASSES + * @see #ACCEPT_INTERFACES + */ + public IType findType(String name, boolean partialMatch, int acceptFlags) { + int index= name.lastIndexOf('.'); + String className= null, packageName= null; + if (index == -1) { + packageName= IPackageFragment.DEFAULT_PACKAGE_NAME; + className= name; + } else { + packageName= name.substring(0, index); + className= name.substring(index + 1); + } + return findType(className, packageName, partialMatch, acceptFlags); + } + + /** + * Returns true if the given element's name matches the + * specified searchName, otherwise false. + * + *

        The partialMatch argument indicates partial matches + * should be considered. + * NOTE: in partialMatch mode, the case will be ignored, and the searchName must already have + * been lowercased. + */ + protected boolean nameMatches(String searchName, IJavaElement element, boolean partialMatch) { + if (partialMatch) { + // partial matches are used in completion mode, thus case insensitive mode + return element.getElementName().toLowerCase().startsWith(searchName); + } else { + return element.getElementName().equals(searchName); + } + } + + /** + * Notifies the given requestor of all package fragments with the + * given name. Checks the requestor at regular intervals to see if the + * requestor has canceled. The domain of + * the search is bounded by the IJavaProject + * this NameLookup was obtained from. + * + * @param partialMatch partial name matches qualify when true; + * only exact name matches qualify when false + */ + public void seekPackageFragments(String name, boolean partialMatch, IJavaElementRequestor requestor) { + int count= fPackageFragmentRoots.length; + String matchName= partialMatch ? name.toLowerCase() : name; + for (int i= 0; i < count; i++) { + if (requestor.isCanceled()) + return; + IPackageFragmentRoot root= fPackageFragmentRoots[i]; + IJavaElement[] list= null; + try { + list= root.getChildren(); + } catch (JavaModelException npe) { + continue; // this root package fragment is not present + } + int elementCount= list.length; + for (int j= 0; j < elementCount; j++) { + if (requestor.isCanceled()) + return; + IPackageFragment packageFragment= (IPackageFragment) list[j]; + if (nameMatches(matchName, packageFragment, partialMatch)) + requestor.acceptPackageFragment(packageFragment); + } + } + } + + /** + * Notifies the given requestor of all types (classes and interfaces) in the + * given package fragment with the given (unqualified) name. + * Checks the requestor at regular intervals to see if the requestor + * has canceled. If the given package fragment is null, all types in the + * project whose simple name matches the given name are found. + * + * @param name The name to search + * @param pkg The corresponding package fragment + * @param partialMatch partial name matches qualify when true; + * only exact name matches qualify when false + * @param acceptFlags a bit mask describing if classes, interfaces or both classes and interfaces + * are desired results. If no flags are specified, all types are returned. + * @param requestor The requestor that collects the result + * + * @see #ACCEPT_CLASSES + * @see #ACCEPT_INTERFACES + */ + public void seekTypes(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags, IJavaElementRequestor requestor) { + + String matchName= partialMatch ? name.toLowerCase() : name; + if (matchName.indexOf('.') >= 0) { //looks for member type A.B + matchName= matchName.replace('.', '$'); + } + if (pkg == null) { + findAllTypes(matchName, partialMatch, acceptFlags, requestor); + return; + } + IPackageFragmentRoot root= (IPackageFragmentRoot) pkg.getParent(); + try { + int packageFlavor= root.getKind(); + switch (packageFlavor) { +// case IPackageFragmentRoot.K_BINARY : +// seekTypesInBinaryPackage(matchName, pkg, partialMatch, acceptFlags, requestor); +// break; + case IPackageFragmentRoot.K_SOURCE : + seekTypesInSourcePackage(matchName, pkg, partialMatch, acceptFlags, requestor); + break; + default : + return; + } + } catch (JavaModelException e) { + return; + } + } + + /** + * Performs type search in a binary package. + */ +// protected void seekTypesInBinaryPackage(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags, IJavaElementRequestor requestor) { +// IClassFile[] classFiles= null; +// try { +// classFiles= pkg.getClassFiles(); +// } catch (JavaModelException npe) { +// return; // the package is not present +// } +// int length= classFiles.length; +// +// String unqualifiedName= name; +// int index= name.lastIndexOf('$'); +// if (index != -1) { +// //the type name of the inner type +// unqualifiedName= name.substring(index + 1, name.length()); +// // unqualifiedName is empty if the name ends with a '$' sign. +// // See http://dev.eclipse.org/bugs/show_bug.cgi?id=14642 +// if ((unqualifiedName.length() > 0 && Character.isDigit(unqualifiedName.charAt(0))) || unqualifiedName.length() == 0){ +// unqualifiedName = name; +// } +// } +// String matchName= partialMatch ? name.toLowerCase() : name; +// for (int i= 0; i < length; i++) { +// if (requestor.isCanceled()) +// return; +// IClassFile classFile= classFiles[i]; +// String elementName = classFile.getElementName(); +// if (partialMatch) elementName = elementName.toLowerCase(); +// +// /** +// * Must use startWith because matchName will never have the +// * extension ".class" and the elementName always will. +// */ +// if (elementName.startsWith(matchName)) { +// IType type= null; +// try { +// type= classFile.getType(); +// } catch (JavaModelException npe) { +// continue; // the classFile is not present +// } +// if (!partialMatch || (type.getElementName().length() > 0 && !Character.isDigit(type.getElementName().charAt(0)))) { //not an anonymous type +// if (nameMatches(unqualifiedName, type, partialMatch) && acceptType(type, acceptFlags)) +// requestor.acceptType(type); +// } +// } +// } +// } + + /** + * Performs type search in a source package. + */ + protected void seekTypesInSourcePackage(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags, IJavaElementRequestor requestor) { + ICompilationUnit[] compilationUnits = null; + try { + compilationUnits = pkg.getCompilationUnits(); + } catch (JavaModelException npe) { + return; // the package is not present + } + int length= compilationUnits.length; + String matchName = name; + int index= name.indexOf('$'); + boolean potentialMemberType = false; + String potentialMatchName = null; + if (index != -1) { + //the compilation unit name of the inner type + potentialMatchName = name.substring(0, index); + potentialMemberType = true; + } + + /** + * In the following, matchName will never have the extension ".java" and + * the compilationUnits always will. So add it if we're looking for + * an exact match. + */ + String unitName = partialMatch ? matchName.toLowerCase() : matchName + ".java"; //$NON-NLS-1$ + String potentialUnitName = null; + if (potentialMemberType) { + potentialUnitName = partialMatch ? potentialMatchName.toLowerCase() : potentialMatchName + ".java"; //$NON-NLS-1$ + } + + for (int i= 0; i < length; i++) { + if (requestor.isCanceled()) + return; + ICompilationUnit compilationUnit= compilationUnits[i]; + + // unit to look inside + ICompilationUnit unitToLookInside = null; + Map workingCopies = (Map) this.unitsToLookInside.getCurrent(); + if (workingCopies != null + && (unitToLookInside = (ICompilationUnit)workingCopies.get(compilationUnit)) != null){ + compilationUnit = unitToLookInside; + } + if ((unitToLookInside != null && !potentialMemberType) || nameMatches(unitName, compilationUnit, partialMatch)) { + IType[] types= null; + try { + types= compilationUnit.getTypes(); + } catch (JavaModelException npe) { + continue; // the compilation unit is not present + } + int typeLength= types.length; + for (int j= 0; j < typeLength; j++) { + if (requestor.isCanceled()) + return; + IType type= types[j]; + if (nameMatches(matchName, type, partialMatch)) { + if (acceptType(type, acceptFlags)) requestor.acceptType(type); + } + } + } else if (potentialMemberType && nameMatches(potentialUnitName, compilationUnit, partialMatch)) { + IType[] types= null; + try { + types= compilationUnit.getTypes(); + } catch (JavaModelException npe) { + continue; // the compilation unit is not present + } + int typeLength= types.length; + for (int j= 0; j < typeLength; j++) { + if (requestor.isCanceled()) + return; + IType type= types[j]; + if (nameMatches(potentialMatchName, type, partialMatch)) { + seekQualifiedMemberTypes(name.substring(index + 1, name.length()), type, partialMatch, requestor, acceptFlags); + } + } + } + + } + } +/** + * Remembers a set of compilation units that will be looked inside + * when looking up a type. If they are working copies, they take + * precedence of their compilation units. + * null means that no special compilation units should be used. + */ +public void setUnitsToLookInside(IWorkingCopy[] unitsToLookInside) { + + if (unitsToLookInside == null) { + this.unitsToLookInside.setCurrent(null); + } else { + HashMap workingCopies = new HashMap(); + this.unitsToLookInside.setCurrent(workingCopies); + for (int i = 0, length = unitsToLookInside.length; i < length; i++) { + IWorkingCopy unitToLookInside = unitsToLookInside[i]; + ICompilationUnit original = (ICompilationUnit)unitToLookInside.getOriginalElement(); + if (original != null) { + workingCopies.put(original, unitToLookInside); + } else { + workingCopies.put(unitToLookInside, unitToLookInside); + } + } + } +} + + /** + * Notifies the given requestor of all types (classes and interfaces) in the + * given type with the given (possibly qualified) name. Checks + * the requestor at regular intervals to see if the requestor + * has canceled. + * + * @param partialMatch partial name matches qualify when true, + * only exact name matches qualify when false + */ + protected void seekQualifiedMemberTypes(String qualifiedName, IType type, boolean partialMatch, IJavaElementRequestor requestor, int acceptFlags) { + if (type == null) + return; + IType[] types= null; + try { + types= type.getTypes(); + } catch (JavaModelException npe) { + return; // the enclosing type is not present + } + String matchName= qualifiedName; + int index= qualifiedName.indexOf('$'); + boolean nested= false; + if (index != -1) { + matchName= qualifiedName.substring(0, index); + nested= true; + } + int length= types.length; + for (int i= 0; i < length; i++) { + if (requestor.isCanceled()) + return; + IType memberType= types[i]; + if (nameMatches(matchName, memberType, partialMatch)) + if (nested) { + seekQualifiedMemberTypes(qualifiedName.substring(index + 1, qualifiedName.length()), memberType, partialMatch, requestor, acceptFlags); + } else { + if (acceptType(memberType, acceptFlags)) requestor.acceptMemberType(memberType); + } + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Openable.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Openable.java index a8ed665..79481b1 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Openable.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Openable.java @@ -10,15 +10,26 @@ *******************************************************************************/ package net.sourceforge.phpdt.internal.core; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + import net.sourceforge.phpdt.core.BufferChangedEvent; import net.sourceforge.phpdt.core.IBuffer; import net.sourceforge.phpdt.core.IBufferChangedListener; +import net.sourceforge.phpdt.core.IBufferFactory; import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; import net.sourceforge.phpdt.core.IOpenable; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.codeassist.ISearchableNameEnvironment; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IProgressMonitor; /** @@ -42,57 +53,57 @@ protected Openable(int type, IJavaElement parent, String name) { */ public void bufferChanged(BufferChangedEvent event) { if (event.getBuffer().isClosed()) { -// JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this); -// getBufferManager().removeBuffer(event.getBuffer()); + JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this); + getBufferManager().removeBuffer(event.getBuffer()); } else { -// JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().put(this, this); + JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().put(this, this); } } -///** -// * Updates the info objects for this element and all of its children by -// * removing the current infos, generating new infos, and then placing -// * the new infos into the Java Model cache tables. -// */ -//protected void buildStructure(OpenableElementInfo info, IProgressMonitor monitor) throws JavaModelException { -// -// if (monitor != null && monitor.isCanceled()) return; -// -// // remove existing (old) infos -// removeInfo(); -// HashMap newElements = new HashMap(11); -// info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource())); -// JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this); -// for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) { -// IJavaElement key = (IJavaElement) iter.next(); -// Object value = newElements.get(key); -// JavaModelManager.getJavaModelManager().putInfo(key, value); -// } -// -// // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs -// // to be flushed. Might lead to performance issues. -// // see PR 1G2K5S7: ITPJCORE:ALL - NPE when accessing source for a binary type -// JavaModelManager.getJavaModelManager().putInfo(this, info); -//} -///** -// * Close the buffer associated with this element, if any. -// */ -//protected void closeBuffer(OpenableElementInfo info) { -// if (!hasBuffer()) return; // nothing to do -// IBuffer buffer = null; -// buffer = getBufferManager().getBuffer(this); -// if (buffer != null) { -// buffer.close(); -// buffer.removeBufferChangedListener(this); -// } -//} -///** -// * This element is being closed. Do any necessary cleanup. -// */ -//protected void closing(Object info) throws JavaModelException { -// OpenableElementInfo openableInfo = (OpenableElementInfo) info; -// closeBuffer(openableInfo); -// super.closing(info); -//} +/** + * Updates the info objects for this element and all of its children by + * removing the current infos, generating new infos, and then placing + * the new infos into the Java Model cache tables. + */ +protected void buildStructure(OpenableElementInfo info, IProgressMonitor monitor) throws JavaModelException { + + if (monitor != null && monitor.isCanceled()) return; + + // remove existing (old) infos + removeInfo(); + HashMap newElements = new HashMap(11); + info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource())); + JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this); + for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) { + IJavaElement key = (IJavaElement) iter.next(); + Object value = newElements.get(key); + JavaModelManager.getJavaModelManager().putInfo(key, value); + } + + // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs + // to be flushed. Might lead to performance issues. + // see PR 1G2K5S7: ITPJCORE:ALL - NPE when accessing source for a binary type + JavaModelManager.getJavaModelManager().putInfo(this, info); +} +/** + * Close the buffer associated with this element, if any. + */ +protected void closeBuffer(OpenableElementInfo info) { + if (!hasBuffer()) return; // nothing to do + IBuffer buffer = null; + buffer = getBufferManager().getBuffer(this); + if (buffer != null) { + buffer.close(); + buffer.removeBufferChangedListener(this); + } +} +/** + * This element is being closed. Do any necessary cleanup. + */ +protected void closing(Object info) throws JavaModelException { + OpenableElementInfo openableInfo = (OpenableElementInfo) info; + closeBuffer(openableInfo); + super.closing(info); +} ///** // * @see ICodeAssist // */ @@ -116,18 +127,18 @@ protected Openable(int type, IJavaElement parent, String name) { // engine.complete(cu, position, 0); // environment.unitToSkip = null; //} -///** -// * @see ICodeAssist -// */ -//protected IJavaElement[] codeSelect(org.eclipse.jdt.internal.compiler.env.ICompilationUnit cu, int offset, int length) throws JavaModelException { +/** + * @see ICodeAssist + */ +//protected IJavaElement[] codeSelect(net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit cu, int offset, int length) throws JavaModelException { // SelectionRequestor requestor= new SelectionRequestor(((JavaProject)getJavaProject()).getNameLookup(), this); // this.codeSelect(cu, offset, length, requestor); // return requestor.getElements(); //} -///** -// * @see ICodeAssist -// */ -//protected void codeSelect(org.eclipse.jdt.internal.compiler.env.ICompilationUnit cu, int offset, int length, ISelectionRequestor requestor) throws JavaModelException { +/** + * @see ICodeAssist + */ +//protected void codeSelect(net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit cu, int offset, int length, ISelectionRequestor requestor) throws JavaModelException { // IBuffer buffer = getBuffer(); // if (buffer == null) { // return; @@ -145,24 +156,24 @@ protected Openable(int type, IJavaElement parent, String name) { // SelectionEngine engine = new SelectionEngine(environment, requestor, project.getOptions(true)); // engine.select(cu, offset, offset + length - 1); //} -///** -// * Returns a new element info for this element. -// */ -//protected OpenableElementInfo createElementInfo() { -// return new OpenableElementInfo(); -//} -// -///** -// * Builds this element's structure and properties in the given -// * info object, based on this element's current contents (reuse buffer -// * contents if this element has an open buffer, or resource contents -// * if this element does not have an open buffer). Children -// * are placed in the given newElements table (note, this element -// * has already been placed in the newElements table). Returns true -// * if successful, or false if an error is encountered while determining -// * the structure of this element. -// */ -//protected abstract boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException; +/** + * Returns a new element info for this element. + */ +protected OpenableElementInfo createElementInfo() { + return new OpenableElementInfo(); +} + +/** + * Builds this element's structure and properties in the given + * info object, based on this element's current contents (reuse buffer + * contents if this element has an open buffer, or resource contents + * if this element does not have an open buffer). Children + * are placed in the given newElements table (note, this element + * has already been placed in the newElements table). Returns true + * if successful, or false if an error is encountered while determining + * the structure of this element. + */ +protected abstract boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException; /** * Note: a buffer with no unsaved changes can be closed by the Java Model * since it has a finite number of buffers allowed open at one time. If this @@ -188,14 +199,14 @@ public IBuffer getBuffer() throws JavaModelException { return null; } } -// -///** -// * Answers the buffer factory to use for creating new buffers -// */ -//public IBufferFactory getBufferFactory(){ -// return getBufferManager().getDefaultBufferFactory(); -//} -// + +/** + * Answers the buffer factory to use for creating new buffers + */ +public IBufferFactory getBufferFactory(){ + return getBufferManager().getDefaultBufferFactory(); +} + /** * Returns the buffer manager for this element. */ @@ -211,15 +222,15 @@ protected BufferManager getBufferManager() { public IResource getCorrespondingResource() throws JavaModelException { return getUnderlyingResource(); } -///* -// * @see IJavaElement -// */ -//public IOpenable getOpenable() { -// return this; -//} -// -// -// +/* + * @see IJavaElement + */ +public IOpenable getOpenable() { + return this; +} + + + /** * @see IJavaElement */ @@ -242,15 +253,15 @@ public IResource getUnderlyingResource() throws JavaModelException { } } -//public boolean exists() { -// -// IPackageFragmentRoot root = this.getPackageFragmentRoot(); -// if (root == null || root == this || !root.isArchive()) { -// return parentExists() && resourceExists(); -// } else { -// return super.exists(); -// } -//} +public boolean exists() { + + IPackageFragmentRoot root = this.getPackageFragmentRoot(); + if (root == null || root == this || !root.isArchive()) { + return parentExists() && resourceExists(); + } else { + return super.exists(); + } +} /** * Returns true if this element may have an associated source buffer, @@ -259,44 +270,44 @@ public IResource getUnderlyingResource() throws JavaModelException { protected boolean hasBuffer() { return false; } -///** -// * @see IParent -// */ -//public boolean hasChildren() throws JavaModelException { -// return getChildren().length > 0; -//} -///** -// * @see IOpenable -// */ -//public boolean hasUnsavedChanges() throws JavaModelException{ -// -// if (isReadOnly() || !isOpen()) { -// return false; -// } -// IBuffer buf = this.getBuffer(); -// if (buf != null && buf.hasUnsavedChanges()) { -// return true; -// } -// // for package fragments, package fragment roots, and projects must check open buffers -// // to see if they have an child with unsaved changes -// if (fLEType == PACKAGE_FRAGMENT || -// fLEType == PACKAGE_FRAGMENT_ROOT || -// fLEType == JAVA_PROJECT || -// fLEType == JAVA_MODEL) { // fix for 1FWNMHH -// Enumeration openBuffers= getBufferManager().getOpenBuffers(); -// while (openBuffers.hasMoreElements()) { -// IBuffer buffer= (IBuffer)openBuffers.nextElement(); -// if (buffer.hasUnsavedChanges()) { -// IJavaElement owner= (IJavaElement)buffer.getOwner(); -// if (isAncestorOf(owner)) { -// return true; -// } -// } -// } -// } -// -// return false; -//} +/** + * @see IParent + */ +public boolean hasChildren() throws JavaModelException { + return getChildren().length > 0; +} +/** + * @see IOpenable + */ +public boolean hasUnsavedChanges() throws JavaModelException{ + + if (isReadOnly() || !isOpen()) { + return false; + } + IBuffer buf = this.getBuffer(); + if (buf != null && buf.hasUnsavedChanges()) { + return true; + } + // for package fragments, package fragment roots, and projects must check open buffers + // to see if they have an child with unsaved changes + if (fLEType == PACKAGE_FRAGMENT || + fLEType == PACKAGE_FRAGMENT_ROOT || + fLEType == JAVA_PROJECT || + fLEType == JAVA_MODEL) { // fix for 1FWNMHH + Enumeration openBuffers= getBufferManager().getOpenBuffers(); + while (openBuffers.hasMoreElements()) { + IBuffer buffer= (IBuffer)openBuffers.nextElement(); + if (buffer.hasUnsavedChanges()) { + IJavaElement owner= (IJavaElement)buffer.getOwner(); + if (isAncestorOf(owner)) { + return true; + } + } + } + } + + return false; +} /** * Subclasses must override as required. * @@ -310,39 +321,37 @@ public boolean isConsistent() throws JavaModelException { * @see IOpenable */ public boolean isOpen() { - // TODO isOpen - Openable needs JavaModelManager -// synchronized(JavaModelManager.getJavaModelManager()){ -// return JavaModelManager.getJavaModelManager().getInfo(this) != null; -// } - return false; + synchronized(JavaModelManager.getJavaModelManager()){ + return JavaModelManager.getJavaModelManager().getInfo(this) != null; + } +} +/** + * Returns true if this represents a source element. + * Openable source elements have an associated buffer created + * when they are opened. + */ +protected boolean isSourceElement() { + return false; } -///** -// * Returns true if this represents a source element. -// * Openable source elements have an associated buffer created -// * when they are opened. -// */ -//protected boolean isSourceElement() { -// return false; -//} -///** -// * @see IOpenable -// */ -//public void makeConsistent(IProgressMonitor pm) throws JavaModelException { -// if (!isConsistent()) { -// buildStructure((OpenableElementInfo)getElementInfo(), pm); -// } -//} -///** -// * @see IOpenable -// */ -//public void open(IProgressMonitor pm) throws JavaModelException { -// if (!isOpen()) { -// // TODO: need to synchronize (IOpenable.open(IProgressMonitor) is API -// // TODO: could use getElementInfo instead -// this.openWhenClosed(pm); -// } -//} -// +/** + * @see IOpenable + */ +public void makeConsistent(IProgressMonitor pm) throws JavaModelException { + if (!isConsistent()) { + buildStructure((OpenableElementInfo)getElementInfo(), pm); + } +} +/** + * @see IOpenable + */ +public void open(IProgressMonitor pm) throws JavaModelException { + if (!isOpen()) { + // TODO: need to synchronize (IOpenable.open(IProgressMonitor) is API + // TODO: could use getElementInfo instead + this.openWhenClosed(pm); + } +} + /** * Opens a buffer on the contents of this element, and returns * the buffer, or returns null if opening fails. @@ -352,98 +361,98 @@ public boolean isOpen() { protected IBuffer openBuffer(IProgressMonitor pm) throws JavaModelException { return null; } -// -///** -// * Open the parent element if necessary -// * -// */ -//protected void openParent(IProgressMonitor pm) throws JavaModelException { -// -// Openable openableParent = (Openable)getOpenableParent(); -// if (openableParent != null) { -// if (!openableParent.isOpen()){ -// openableParent.openWhenClosed(pm); -// } -// } -//} -// -///** -// * Open an Openable that is known to be closed (no check for isOpen()). -// */ -//protected void openWhenClosed(IProgressMonitor pm) throws JavaModelException { -// try { -// -// if (JavaModelManager.VERBOSE){ -// System.out.println("OPENING Element ("+ Thread.currentThread()+"): " + this.toStringWithAncestors()); //$NON-NLS-1$//$NON-NLS-2$ -// } -// -// // 1) Parent must be open - open the parent if necessary -// openParent(pm); -// -// // 2) create the new element info and open a buffer if needed -// OpenableElementInfo info = createElementInfo(); -// if (isSourceElement()) { -// this.openBuffer(pm); -// } -// -// // 3) build the structure of the openable -// buildStructure(info, pm); -// -// // 4) anything special -// opening(info); -// + +/** + * Open the parent element if necessary + * + */ +protected void openParent(IProgressMonitor pm) throws JavaModelException { + + Openable openableParent = (Openable)getOpenableParent(); + if (openableParent != null) { + if (!openableParent.isOpen()){ + openableParent.openWhenClosed(pm); + } + } +} + +/** + * Open an Openable that is known to be closed (no check for isOpen()). + */ +protected void openWhenClosed(IProgressMonitor pm) throws JavaModelException { + try { + + if (JavaModelManager.VERBOSE){ + System.out.println("OPENING Element ("+ Thread.currentThread()+"): " + this.toStringWithAncestors()); //$NON-NLS-1$//$NON-NLS-2$ + } + + // 1) Parent must be open - open the parent if necessary + openParent(pm); + + // 2) create the new element info and open a buffer if needed + OpenableElementInfo info = createElementInfo(); + if (isSourceElement()) { + this.openBuffer(pm); + } + + // 3) build the structure of the openable + buildStructure(info, pm); + + // 4) anything special + opening(info); + // if (JavaModelManager.VERBOSE) { // System.out.println("-> Package cache size = " + JavaModelManager.getJavaModelManager().cache.pkgSize()); //$NON-NLS-1$ // System.out.println("-> Openable cache filling ratio = " + JavaModelManager.getJavaModelManager().cache.openableFillingRatio() + "%"); //$NON-NLS-1$//$NON-NLS-2$ // } -// -// // if any problems occuring openning the element, ensure that it's info -// // does not remain in the cache (some elements, pre-cache their info -// // as they are being opened). -// } catch (JavaModelException e) { -// JavaModelManager.getJavaModelManager().removeInfo(this); -// throw e; -// } -//} -// -///** -// * Answers true if the parent exists (null parent is answering true) -// * -// */ -//protected boolean parentExists(){ -// -// IJavaElement parent = this.getParent(); -// if (parent == null) return true; -// return parent.exists(); -//} -// -///** -// * Returns whether the corresponding resource or associated file exists -// */ -//protected boolean resourceExists() { -// IWorkspace workspace = ResourcesPlugin.getWorkspace(); -// if (workspace == null) return false; // workaround for http://bugs.eclipse.org/bugs/show_bug.cgi?id=34069 -// return -// JavaModel.getTarget( -// workspace.getRoot(), -// this.getPath().makeRelative(), // ensure path is relative (see http://dev.eclipse.org/bugs/show_bug.cgi?id=22517) -// true) != null; -//} -// -///** -// * @see IOpenable -// */ -//public void save(IProgressMonitor pm, boolean force) throws JavaModelException { -// if (isReadOnly() || this.getResource().isReadOnly()) { -// throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this)); -// } -// IBuffer buf = getBuffer(); -// if (buf != null) { // some Openables (like a JavaProject) don't have a buffer -// buf.save(pm, force); -// this.makeConsistent(pm); // update the element info of this element -// } -//} -// + + // if any problems occuring openning the element, ensure that it's info + // does not remain in the cache (some elements, pre-cache their info + // as they are being opened). + } catch (JavaModelException e) { + JavaModelManager.getJavaModelManager().removeInfo(this); + throw e; + } +} + +/** + * Answers true if the parent exists (null parent is answering true) + * + */ +protected boolean parentExists(){ + + IJavaElement parent = this.getParent(); + if (parent == null) return true; + return parent.exists(); +} + +/** + * Returns whether the corresponding resource or associated file exists + */ +protected boolean resourceExists() { + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + if (workspace == null) return false; // workaround for http://bugs.eclipse.org/bugs/show_bug.cgi?id=34069 + return + JavaModel.getTarget( + workspace.getRoot(), + this.getPath().makeRelative(), // ensure path is relative (see http://dev.eclipse.org/bugs/show_bug.cgi?id=22517) + true) != null; +} + +/** + * @see IOpenable + */ +public void save(IProgressMonitor pm, boolean force) throws JavaModelException { + if (isReadOnly() || this.getResource().isReadOnly()) { + throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this)); + } + IBuffer buf = getBuffer(); + if (buf != null) { // some Openables (like a JavaProject) don't have a buffer + buf.save(pm, force); + this.makeConsistent(pm); // update the element info of this element + } +} + /** * Find enclosing package fragment root if any */ diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/OpenableElementInfo.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/OpenableElementInfo.java new file mode 100644 index 0000000..660c9f1 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/OpenableElementInfo.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +/** Element info for IOpenable elements. */ +/* package */ class OpenableElementInfo extends JavaElementInfo { + + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/OverflowingLRUCache.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/OverflowingLRUCache.java index 8b415c0..e7d92f2 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/OverflowingLRUCache.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/OverflowingLRUCache.java @@ -13,7 +13,7 @@ package net.sourceforge.phpdt.internal.core; import java.util.Enumeration; import java.util.Iterator; -import net.sourceforge.phpdt.core.util.LRUCache; +import net.sourceforge.phpdt.internal.core.util.LRUCache; /** * The OverflowingLRUCache is an LRUCache which attempts diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageDeclaration.java new file mode 100644 index 0000000..e79c736 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageDeclaration.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IPackageDeclaration; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.jdom.IDOMNode; + +/** + * @see IPackageDeclaration + */ + +/* package */ class PackageDeclaration extends SourceRefElement implements IPackageDeclaration { +protected PackageDeclaration(ICompilationUnit parent, String name) { + super(PACKAGE_DECLARATION, parent, name); +} +/** + * @see JavaElement#equalsDOMNode + */ +protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException { + return (node.getNodeType() == IDOMNode.PACKAGE) && getElementName().equals(node.getName()); +} +/** + * @see JavaElement#getHandleMemento() + */ +protected char getHandleMementoDelimiter() { + return JavaElement.JEM_PACKAGEDECLARATION; +} +/** + * @private Debugging purposes + */ +protected void toStringInfo(int tab, StringBuffer buffer, Object info) { + buffer.append(this.tabString(tab)); + buffer.append("package "); //$NON-NLS-1$ + buffer.append(getElementName()); + if (info == null) { + buffer.append(" (not open)"); //$NON-NLS-1$ + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragment.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragment.java index 2b559f5..6b75157 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragment.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragment.java @@ -10,6 +10,9 @@ *******************************************************************************/ package net.sourceforge.phpdt.internal.core; +import java.util.ArrayList; +import java.util.Map; + import net.sourceforge.phpdt.core.ICompilationUnit; import net.sourceforge.phpdt.core.IJavaElement; import net.sourceforge.phpdt.core.IJavaProject; @@ -19,6 +22,8 @@ import net.sourceforge.phpdt.core.JavaModelException; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; @@ -37,7 +42,7 @@ public class PackageFragment extends Openable implements IPackageFragment { * @see IPackageFragment */ protected PackageFragment(IPackageFragmentRoot root, String name) { - super(PACKAGE_FRAGMENT, null, name); + super(PACKAGE_FRAGMENT, root, name); } /** * Compute the children of this package fragment. @@ -47,26 +52,26 @@ protected PackageFragment(IPackageFragmentRoot root, String name) { *

        Package fragments which are in a jar only recognize .class files ( * @see JarPackageFragment). */ -//protected boolean computeChildren(OpenableElementInfo info, IResource resource) throws JavaModelException { -// ArrayList vChildren = new ArrayList(); +protected boolean computeChildren(OpenableElementInfo info, IResource resource) throws JavaModelException { + ArrayList vChildren = new ArrayList(); // int kind = getKind(); -// String extType; + String extType; // if (kind == IPackageFragmentRoot.K_SOURCE) { -// extType = "java"; //$NON-NLS-1$ + extType = "php"; //$NON-NLS-1$ // } else { // extType = "class"; //$NON-NLS-1$ // } -// try { -// char[][] exclusionPatterns = ((PackageFragmentRoot)getPackageFragmentRoot()).fullExclusionPatternChars(); -// IResource[] members = ((IContainer) resource).members(); -// for (int i = 0, max = members.length; i < max; i++) { -// IResource child = members[i]; -// if (child.getType() != IResource.FOLDER -// && !Util.isExcluded(child, exclusionPatterns)) { -// String extension = child.getProjectRelativePath().getFileExtension(); -// if (extension != null) { -// if (extension.equalsIgnoreCase(extType)) { -// IJavaElement childElement; + try { + char[][] exclusionPatterns = ((PackageFragmentRoot)getPackageFragmentRoot()).fullExclusionPatternChars(); + IResource[] members = ((IContainer) resource).members(); + for (int i = 0, max = members.length; i < max; i++) { + IResource child = members[i]; + if (child.getType() != IResource.FOLDER + && !Util.isExcluded(child, exclusionPatterns)) { + String extension = child.getProjectRelativePath().getFileExtension(); + if (extension != null) { + if (extension.equalsIgnoreCase(extType)) { + IJavaElement childElement; // if (kind == IPackageFragmentRoot.K_SOURCE && Util.isValidCompilationUnitName(child.getName())) { // childElement = getCompilationUnit(child.getName()); // vChildren.add(childElement); @@ -74,18 +79,18 @@ protected PackageFragment(IPackageFragmentRoot root, String name) { // childElement = getClassFile(child.getName()); // vChildren.add(childElement); // } -// } -// } -// } -// } -// } catch (CoreException e) { -// throw new JavaModelException(e); -// } -// IJavaElement[] children = new IJavaElement[vChildren.size()]; -// vChildren.toArray(children); -// info.setChildren(children); -// return true; -//} + } + } + } + } + } catch (CoreException e) { + throw new JavaModelException(e); + } + IJavaElement[] children = new IJavaElement[vChildren.size()]; + vChildren.toArray(children); + info.setChildren(children); + return true; +} /** * Returns true if this fragment contains at least one java resource. * Returns false otherwise. @@ -124,9 +129,9 @@ public ICompilationUnit createCompilationUnit(String name, String contents, bool /** * @see JavaElement */ -//protected OpenableElementInfo createElementInfo() { -// return new PackageFragmentInfo(); -//} +protected OpenableElementInfo createElementInfo() { + return new PackageFragmentInfo(); +} /** * @see ISourceManipulation */ @@ -137,10 +142,10 @@ public ICompilationUnit createCompilationUnit(String name, String contents, bool /** * @see Openable */ -//protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException { -// -// return computeChildren(info, underlyingResource); -//} +protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException { + + return computeChildren(info, underlyingResource); +} ///** // * @see IPackageFragment#getClassFile(String) // */ @@ -173,16 +178,16 @@ public ICompilationUnit getCompilationUnit(String name) { /** * @see IPackageFragment#getCompilationUnits() */ -//public ICompilationUnit[] getCompilationUnits() throws JavaModelException { -// if (getKind() == IPackageFragmentRoot.K_BINARY) { -// return fgEmptyCompilationUnitList; -// } -// -// ArrayList list = getChildrenOfType(COMPILATION_UNIT); -// ICompilationUnit[] array= new ICompilationUnit[list.size()]; -// list.toArray(array); -// return array; -//} +public ICompilationUnit[] getCompilationUnits() throws JavaModelException { + if (getKind() == IPackageFragmentRoot.K_BINARY) { + return fgEmptyCompilationUnitList; + } + + ArrayList list = getChildrenOfType(COMPILATION_UNIT); + ICompilationUnit[] array= new ICompilationUnit[list.size()]; + list.toArray(array); + return array; +} /** * @see JavaElement#getHandleMementoDelimiter() */ @@ -192,9 +197,9 @@ protected char getHandleMementoDelimiter() { /** * @see IPackageFragment#getKind() */ -//public int getKind() throws JavaModelException { -// return ((IPackageFragmentRoot)getParent()).getKind(); -//} +public int getKind() throws JavaModelException { + return ((IPackageFragmentRoot)getParent()).getKind(); +} /** * Returns an array of non-java resources contained in the receiver. */ @@ -209,14 +214,14 @@ protected char getHandleMementoDelimiter() { /** * @see IJavaElement#getPath() */ -//public IPath getPath() { -// PackageFragmentRoot root = this.getPackageFragmentRoot(); -// if (root.isArchive()) { -// return root.getPath(); -// } else { -// return root.getPath().append(this.getElementName().replace('.', '/')); -// } -//} +public IPath getPath() { + PackageFragmentRoot root = this.getPackageFragmentRoot(); + if (root.isArchive()) { + return root.getPath(); + } else { + return root.getPath().append(this.getElementName().replace('.', '/')); + } +} /** * @see IJavaElement#getResource() */ diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragmentInfo.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragmentInfo.java new file mode 100644 index 0000000..01a8258 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragmentInfo.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.JavaModelException; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; + + +/** + * Element info for PackageFragments. + */ +class PackageFragmentInfo extends OpenableElementInfo { + + /** + * A array with all the non-java resources contained by this PackageFragment + */ + protected Object[] fNonJavaResources; + +/** + * Create and initialize a new instance of the receiver + */ +public PackageFragmentInfo() { + fNonJavaResources = null; +} +/** + */ +boolean containsJavaResources() { + return fChildren.length != 0; +} +/** + * Returns an array of non-java resources contained in the receiver. + */ +Object[] getNonJavaResources(IResource underlyingResource, PackageFragmentRoot rootHandle) { + Object[] nonJavaResources = fNonJavaResources; + if (nonJavaResources == null) { + try { + nonJavaResources = + PackageFragmentRootInfo.computeFolderNonJavaResources( + (JavaProject)rootHandle.getJavaProject(), + (IContainer)underlyingResource, + rootHandle.fullExclusionPatternChars()); + } catch (JavaModelException e) { + } + fNonJavaResources = nonJavaResources; + } + return nonJavaResources; +} +/** + * Set the fNonJavaResources to res value + */ +synchronized void setNonJavaResources(Object[] resources) { + fNonJavaResources = resources; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragmentRoot.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragmentRoot.java index cf729bb..11aec11 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragmentRoot.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragmentRoot.java @@ -10,19 +10,22 @@ *******************************************************************************/ package net.sourceforge.phpdt.internal.core; +import java.util.Map; + import net.sourceforge.phpdt.core.IJavaElement; import net.sourceforge.phpdt.core.IJavaProject; import net.sourceforge.phpdt.core.IPackageFragment; import net.sourceforge.phpdt.core.IPackageFragmentRoot; -import net.sourceforge.phpdt.core.JavaCore; import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpeclipse.PHPCore; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.QualifiedName; @@ -292,9 +295,9 @@ protected PackageFragmentRoot(IResource resource, IJavaProject project, String n /** * Returns a new element info for this element. */ -//protected OpenableElementInfo createElementInfo() { -// return new PackageFragmentRootInfo(); -//} +protected OpenableElementInfo createElementInfo() { + return new PackageFragmentRootInfo(); +} /** * @see IPackageFragmentRoot @@ -425,8 +428,10 @@ public boolean equals(Object o) { /* * Returns the exclusion patterns from the classpath entry associated with this root. */ -//char[][] fullExclusionPatternChars() { +char[][] fullExclusionPatternChars() { + return null; // try { + // if (this.isOpen() && this.getKind() != IPackageFragmentRoot.K_SOURCE) return null; // ClasspathEntry entry = (ClasspathEntry)getRawClasspathEntry(); // if (entry == null) { @@ -437,16 +442,17 @@ public boolean equals(Object o) { // } catch (JavaModelException e) { // return null; // } -//} +} /** * @see Openable */ -//protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException { -// +protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException { + // ((PackageFragmentRootInfo) info).setRootKind(determineKind(underlyingResource)); // return computeChildren(info); -//} + return false; +} /** * @see JavaElement#getHandleMemento() @@ -479,9 +485,9 @@ public String getHandleMemento(){ /** * @see IPackageFragmentRoot */ -//public int getKind() throws JavaModelException { -// return ((PackageFragmentRootInfo)getElementInfo()).getRootKind(); -//} +public int getKind() throws JavaModelException { + return ((PackageFragmentRootInfo)getElementInfo()).getRootKind(); +} /** * Returns an array of non-java resources contained in the receiver. @@ -617,7 +623,7 @@ public IResource getResource() { * of this root. */ protected QualifiedName getSourceAttachmentPropertyName() throws JavaModelException { - return new QualifiedName(JavaCore.PLUGIN_ID, "sourceattachment: " + this.getPath().toOSString()); //$NON-NLS-1$ + return new QualifiedName(PHPCore.PLUGIN_ID, "sourceattachment: " + this.getPath().toOSString()); //$NON-NLS-1$ } public void setSourceAttachmentProperty(String property) { diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragmentRootInfo.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragmentRootInfo.java new file mode 100644 index 0000000..061a5f3 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragmentRootInfo.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.IClasspathEntry; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; +import net.sourceforge.phpdt.core.JavaModelException; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +/** + * The element info for PackageFragmentRoots. + */ +class PackageFragmentRootInfo extends OpenableElementInfo { + + /** + * The SourceMapper for this JAR (or null if + * this JAR does not have source attached). + */ +// protected SourceMapper sourceMapper = null; + + /** + * The kind of the root associated with this info. + * Valid kinds are:

          + *
        • IPackageFragmentRoot.K_SOURCE + *
        • IPackageFragmentRoot.K_BINARY
        + */ + protected int fRootKind= IPackageFragmentRoot.K_SOURCE; + + /** + * A array with all the non-java resources contained by this PackageFragment + */ + protected Object[] fNonJavaResources; +/** + * Create and initialize a new instance of the receiver + */ +public PackageFragmentRootInfo() { + fNonJavaResources = null; +} +/** + * Starting at this folder, create non-java resources for this package fragment root + * and add them to the non-java resources collection. + * + * @exception JavaModelException The resource associated with this package fragment does not exist + */ +static Object[] computeFolderNonJavaResources(JavaProject project, IContainer folder, char[][] exclusionPatterns) throws JavaModelException { + Object[] nonJavaResources = new IResource[5]; + int nonJavaResourcesCounter = 0; + try { + IClasspathEntry[] classpath = project.getResolvedClasspath(true/*ignore unresolved variable*/); + IResource[] members = folder.members(); + nextResource: for (int i = 0, max = members.length; i < max; i++) { + IResource member = members[i]; + switch (member.getType()) { + case IResource.FILE : + String fileName = member.getName(); + + // ignore .java files that are not excluded + if (Util.isValidCompilationUnitName(fileName) && !Util.isExcluded(member, exclusionPatterns)) + continue nextResource; + // ignore .class files +// if (Util.isValidClassFileName(fileName)) +// continue nextResource; +// // ignore .zip or .jar file on classpath +// if (Util.isArchiveFileName(fileName) && isClasspathEntry(member.getFullPath(), classpath)) +// continue nextResource; + break; + + case IResource.FOLDER : + // ignore valid packages or excluded folders that correspond to a nested pkg fragment root +// if (Util.isValidFolderNameForPackage(member.getName()) +// && (!Util.isExcluded(member, exclusionPatterns) +// || isClasspathEntry(member.getFullPath(), classpath))) +// continue nextResource; + break; + } + if (nonJavaResources.length == nonJavaResourcesCounter) { + // resize + System.arraycopy(nonJavaResources, 0, (nonJavaResources = new IResource[nonJavaResourcesCounter * 2]), 0, nonJavaResourcesCounter); + } + nonJavaResources[nonJavaResourcesCounter++] = member; + + } + if (nonJavaResources.length != nonJavaResourcesCounter) { + System.arraycopy(nonJavaResources, 0, (nonJavaResources = new IResource[nonJavaResourcesCounter]), 0, nonJavaResourcesCounter); + } + return nonJavaResources; + } catch (CoreException e) { + throw new JavaModelException(e); + } +} +/** + * Compute the non-package resources of this package fragment root. + * + * @exception JavaModelException The resource associated with this package fragment root does not exist + */ +private Object[] computeNonJavaResources(IJavaProject project, IResource underlyingResource, PackageFragmentRoot handle) { + Object[] nonJavaResources = NO_NON_JAVA_RESOURCES; + try { + // the underlying resource may be a folder or a project (in the case that the project folder + // is actually the package fragment root) + if (underlyingResource.getType() == IResource.FOLDER || underlyingResource.getType() == IResource.PROJECT) { + nonJavaResources = + computeFolderNonJavaResources( + (JavaProject)project, + (IContainer) underlyingResource, + handle.fullExclusionPatternChars()); + } + } catch (JavaModelException e) { + } + return nonJavaResources; +} +/** + * Returns an array of non-java resources contained in the receiver. + */ +synchronized Object[] getNonJavaResources(IJavaProject project, IResource underlyingResource, PackageFragmentRoot handle) { + Object[] nonJavaResources = fNonJavaResources; + if (nonJavaResources == null) { + nonJavaResources = this.computeNonJavaResources(project, underlyingResource, handle); + fNonJavaResources = nonJavaResources; + } + return nonJavaResources; +} +/** + * Returns the kind of this root. + */ +public int getRootKind() { + return fRootKind; +} +/** + * Retuns the SourceMapper for this root, or null + * if this root does not have attached source. + */ +//protected synchronized SourceMapper getSourceMapper() { +// return this.sourceMapper; +//} +private static boolean isClasspathEntry(IPath path, IClasspathEntry[] resolvedClasspath) { + for (int i = 0, length = resolvedClasspath.length; i < length; i++) { + IClasspathEntry entry = resolvedClasspath[i]; + if (entry.getPath().equals(path)) { + return true; + } + } + return false; +} +/** + * Set the fNonJavaResources to res value + */ +synchronized void setNonJavaResources(Object[] resources) { + fNonJavaResources = resources; +} +/** + * Sets the kind of this root. + */ +protected void setRootKind(int newRootKind) { + fRootKind = newRootKind; +} +/** + * Sets the SourceMapper for this root. + */ +//protected synchronized void setSourceMapper(SourceMapper mapper) { +// this.sourceMapper= mapper; +//} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/ReconcileWorkingCopyOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/ReconcileWorkingCopyOperation.java new file mode 100644 index 0000000..9df9bea --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/ReconcileWorkingCopyOperation.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelStatus; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; +import net.sourceforge.phpdt.core.IProblemRequestor; +import net.sourceforge.phpdt.core.JavaModelException; + +/** + * Reconcile a working copy and signal the changes through a delta. + */ +public class ReconcileWorkingCopyOperation extends JavaModelOperation { + + boolean forceProblemDetection; + + public ReconcileWorkingCopyOperation(IJavaElement workingCopy, boolean forceProblemDetection) { + super(new IJavaElement[] {workingCopy}); + this.forceProblemDetection = forceProblemDetection; + } + /** + * @exception JavaModelException if setting the source + * of the original compilation unit fails + */ + protected void executeOperation() throws JavaModelException { + if (fMonitor != null){ + if (fMonitor.isCanceled()) return; + fMonitor.beginTask(Util.bind("element.reconciling"), 10); //$NON-NLS-1$ + } + + WorkingCopy workingCopy = getWorkingCopy(); + boolean wasConsistent = workingCopy.isConsistent(); + JavaElementDeltaBuilder deltaBuilder = null; + + try { + // create the delta builder (this remembers the current content of the cu) + if (!wasConsistent){ + deltaBuilder = new JavaElementDeltaBuilder(workingCopy); + + // update the element infos with the content of the working copy + workingCopy.makeConsistent(fMonitor); + deltaBuilder.buildDeltas(); + + } + + if (fMonitor != null) fMonitor.worked(2); + + // force problem detection? - if structure was consistent + if (forceProblemDetection && wasConsistent){ + if (fMonitor != null && fMonitor.isCanceled()) return; + + IProblemRequestor problemRequestor = workingCopy.problemRequestor; + if (problemRequestor != null && problemRequestor.isActive()){ + problemRequestor.beginReporting(); + CompilationUnitProblemFinder.process(workingCopy, problemRequestor, fMonitor); + problemRequestor.endReporting(); + } + } + + // register the deltas + if (deltaBuilder != null){ + if ((deltaBuilder.delta != null) && (deltaBuilder.delta.getAffectedChildren().length > 0)) { + addReconcileDelta(workingCopy, deltaBuilder.delta); + } + } + } finally { + if (fMonitor != null) fMonitor.done(); + } + } + /** + * Returns the working copy this operation is working on. + */ + protected WorkingCopy getWorkingCopy() { + return (WorkingCopy)getElementToProcess(); + } + /** + * @see JavaModelOperation#isReadOnly + */ + public boolean isReadOnly() { + return true; + } + protected IJavaModelStatus verify() { + IJavaModelStatus status = super.verify(); + if (!status.isOK()) { + return status; + } + WorkingCopy workingCopy = getWorkingCopy(); + if (workingCopy.useCount == 0) { + return new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, workingCopy); //was destroyed + } + return status; + } + + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/RenameElementsOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/RenameElementsOperation.java new file mode 100644 index 0000000..5d3fc42 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/RenameElementsOperation.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelStatus; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; +import net.sourceforge.phpdt.core.ISourceReference; +import net.sourceforge.phpdt.core.JavaModelException; + +/** + * This operation renames elements. + * + *

        Notes:

          + *
        • Resource rename is not supported - this operation only renames + * elements contained in compilation units. + *
        • When a main type is renamed, its compilation unit and constructors are renamed. + *
        • Constructors cannot be renamed. + *
        + */ +public class RenameElementsOperation extends MoveElementsOperation { +/** + * When executed, this operation will rename the specified elements with the given names in the + * corresponding destinations. + */ +public RenameElementsOperation(IJavaElement[] elements, IJavaElement[] destinations, String[] newNames, boolean force) { + //a rename is a move to the same parent with a new name specified + //these elements are from different parents + super(elements, destinations, force); + setRenamings(newNames); +} +/** + * @see MultiOperation + */ +protected String getMainTaskName() { + return Util.bind("operation.renameElementProgress"); //$NON-NLS-1$ +} +/** + * @see CopyElementsOperation#isRename() + */ +protected boolean isRename() { + return true; +} +/** + * @see MultiOperation + */ +protected IJavaModelStatus verify() { + IJavaModelStatus status = super.verify(); + if (! status.isOK()) + return status; + if (fRenamingsList == null || fRenamingsList.length == 0) + return new JavaModelStatus(IJavaModelStatusConstants.NULL_NAME); + return JavaModelStatus.VERIFIED_OK; +} +/** + * @see MultiOperation + */ +protected void verify(IJavaElement element) throws JavaModelException { + int elementType = element.getElementType(); + + if (element == null || !element.exists()) + error(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, element); + + if (element.isReadOnly()) + error(IJavaModelStatusConstants.READ_ONLY, element); + + if (!(element instanceof ISourceReference)) + error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element); + + if (elementType < IJavaElement.TYPE || elementType == IJavaElement.INITIALIZER) + error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element); + + verifyRenaming(element); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/RenameResourceElementsOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/RenameResourceElementsOperation.java new file mode 100644 index 0000000..a24f922 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/RenameResourceElementsOperation.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; +import net.sourceforge.phpdt.core.JavaModelException; + +/** + * This operation renames resources (Package fragments and compilation units). + * + *

        Notes:

          + *
        • When a compilation unit is renamed, its main type and the constructors of the + * main type are renamed. + *
        + */ +public class RenameResourceElementsOperation extends MoveResourceElementsOperation { +/** + * When executed, this operation will rename the specified elements with the given names in the + * corresponding destinations. + */ +public RenameResourceElementsOperation(IJavaElement[] elements, IJavaElement[] destinations, String[] newNames, boolean force) { + //a rename is a move to the same parent with a new name specified + //these elements are from different parents + super(elements, destinations, force); + setRenamings(newNames); +} +/** + * @see MultiOperation + */ +protected String getMainTaskName() { + return Util.bind("operation.renameResourceProgress"); //$NON-NLS-1$ +} +/** + * @see CopyResourceElementsOperation#isRename() + */ +protected boolean isRename() { + return true; +} +/** + * @see MultiOperation + */ +protected void verify(IJavaElement element) throws JavaModelException { + super.verify(element); + + int elementType = element.getElementType(); + + if (!(elementType == IJavaElement.COMPILATION_UNIT || elementType == IJavaElement.PACKAGE_FRAGMENT)) { + error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element); + } + if (elementType == IJavaElement.COMPILATION_UNIT) { + if (((ICompilationUnit) element).isWorkingCopy()) { + error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element); + } + } + verifyRenaming(element); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/SearchableEnvironment.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/SearchableEnvironment.java new file mode 100644 index 0000000..6bc4edc --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/SearchableEnvironment.java @@ -0,0 +1,302 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.core.search.IJavaSearchConstants; +import net.sourceforge.phpdt.core.search.ITypeNameRequestor; +import net.sourceforge.phpdt.internal.codeassist.ISearchRequestor; +import net.sourceforge.phpdt.internal.codeassist.ISearchableNameEnvironment; +import net.sourceforge.phpdt.internal.compiler.env.IConstants; +import net.sourceforge.phpdt.internal.compiler.env.ISourceType; +import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer; + +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * This class provides a SearchableBuilderEnvironment for code assist which + * uses the Java model as a search tool. + */ +public class SearchableEnvironment implements ISearchableNameEnvironment, IJavaSearchConstants { + protected NameLookup nameLookup; + protected ICompilationUnit unitToSkip; + + protected IJavaProject project; + // protected IJavaSearchScope searchScope; + + /** + * Creates a SearchableEnvironment on the given project + */ + public SearchableEnvironment(IJavaProject project) throws JavaModelException { + this.project = project; + this.nameLookup = (NameLookup) ((JavaProject) project).getNameLookup(); + + // Create search scope with visible entry on the project's classpath + // this.searchScope = SearchEngine.createJavaSearchScope(this.project.getAllPackageFragmentRoots()); + } + + /** + * Returns the given type in the the given package if it exists, + * otherwise null. + */ + protected NameEnvironmentAnswer find(String typeName, String packageName) { + if (packageName == null) + packageName = IPackageFragment.DEFAULT_PACKAGE_NAME; + + IType type = this.nameLookup.findType(typeName, packageName, false, NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES); + if (type != null) { + // if (type instanceof BinaryType) { + // try { + // return new NameEnvironmentAnswer( + // (IBinaryType) ((BinaryType) type).getElementInfo()); + // } catch (JavaModelException npe) { + // return null; + // } + // } else { //SourceType + try { + // retrieve the requested type + SourceTypeElementInfo sourceType = (SourceTypeElementInfo) ((SourceType) type).getElementInfo(); + ISourceType topLevelType = sourceType; + while (topLevelType.getEnclosingType() != null) { + topLevelType = topLevelType.getEnclosingType(); + } + // find all siblings (other types declared in same unit, since may be used for name resolution) + IType[] types = sourceType.getHandle().getCompilationUnit().getTypes(); + ISourceType[] sourceTypes = new ISourceType[types.length]; + + // in the resulting collection, ensure the requested type is the first one + sourceTypes[0] = sourceType; + for (int i = 0, index = 1; i < types.length; i++) { + ISourceType otherType = (ISourceType) ((JavaElement) types[i]).getElementInfo(); + if (!otherType.equals(topLevelType)) + sourceTypes[index++] = otherType; + } + return new NameEnvironmentAnswer(sourceTypes); + } catch (JavaModelException npe) { + return null; + } + // } + } + return null; + } + + /** + * @see ISearchableNameEnvironment#findPackages(char[], ISearchRequestor) + */ + public void findPackages(char[] prefix, ISearchRequestor requestor) { + // this.nameLookup.seekPackageFragments( + // new String(prefix), + // true, + // new SearchableEnvironmentRequestor(requestor)); + } + + /** + * @see INameEnvironment#findType(char[][]) + */ + public NameEnvironmentAnswer findType(char[][] compoundTypeName) { + if (compoundTypeName == null) + return null; + + int length = compoundTypeName.length; + if (length <= 1) { + if (length == 0) + return null; + return find(new String(compoundTypeName[0]), null); + } + + int lengthM1 = length - 1; + char[][] packageName = new char[lengthM1][]; + System.arraycopy(compoundTypeName, 0, packageName, 0, lengthM1); + + return find(new String(compoundTypeName[lengthM1]), CharOperation.toString(packageName)); + } + + /** + * @see INameEnvironment#findType(char[], char[][]) + */ + public NameEnvironmentAnswer findType(char[] name, char[][] packageName) { + if (name == null) + return null; + + return find(new String(name), packageName == null || packageName.length == 0 ? null : CharOperation.toString(packageName)); + } + + /** + * @see ISearchableNameEnvironment#findTypes(char[], ISearchRequestor) + */ + public void findTypes(char[] prefix, final ISearchRequestor storage) { + + /* + if (true){ + findTypes(new String(prefix), storage, NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES); + return; + } + */ + // try { + final String excludePath; + if (this.unitToSkip != null) { + if (!(this.unitToSkip instanceof IJavaElement)) { + // revert to model investigation + findTypes(new String(prefix), storage, NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES); + return; + } + excludePath = ((IJavaElement) this.unitToSkip).getPath().toString(); + } else { + excludePath = null; + } + int lastDotIndex = CharOperation.lastIndexOf('.', prefix); + char[] qualification, simpleName; + if (lastDotIndex < 0) { + qualification = null; + simpleName = CharOperation.toLowerCase(prefix); + } else { + qualification = CharOperation.subarray(prefix, 0, lastDotIndex); + simpleName = CharOperation.toLowerCase(CharOperation.subarray(prefix, lastDotIndex + 1, prefix.length)); + } + + IProgressMonitor progressMonitor = new IProgressMonitor() { + boolean isCanceled = false; + public void beginTask(String name, int totalWork) { + } + public void done() { + } + public void internalWorked(double work) { + } + public boolean isCanceled() { + return isCanceled; + } + public void setCanceled(boolean value) { + isCanceled = value; + } + public void setTaskName(String name) { + } + public void subTask(String name) { + } + public void worked(int work) { + } + }; + ITypeNameRequestor nameRequestor = new ITypeNameRequestor() { + public void acceptClass(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) { + if (excludePath != null && excludePath.equals(path)) + return; + if (enclosingTypeNames != null && enclosingTypeNames.length > 0) + return; // accept only top level types + storage.acceptClass(packageName, simpleTypeName, IConstants.AccPublic); + } + public void acceptInterface(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) { + if (excludePath != null && excludePath.equals(path)) + return; + if (enclosingTypeNames != null && enclosingTypeNames.length > 0) + return; // accept only top level types + storage.acceptInterface(packageName, simpleTypeName, IConstants.AccPublic); + } + }; + // try { + // new SearchEngine().searchAllTypeNames( + // this.project.getProject().getWorkspace(), + // qualification, + // simpleName, + // PREFIX_MATCH, + // CASE_INSENSITIVE, + // IJavaSearchConstants.TYPE, + // this.searchScope, + // nameRequestor, + // CANCEL_IF_NOT_READY_TO_SEARCH, + // progressMonitor); + // } catch (OperationCanceledException e) { + // findTypes( + // new String(prefix), + // storage, + // NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES); + // } + // } catch (JavaModelException e) { + // findTypes( + // new String(prefix), + // storage, + // NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES); + // } + } + + /** + * Returns all types whose name starts with the given (qualified) prefix. + * + * If the prefix is unqualified, all types whose simple name matches + * the prefix are returned. + */ + private void findTypes(String prefix, ISearchRequestor storage, int type) { + SearchableEnvironmentRequestor requestor = new SearchableEnvironmentRequestor(storage, this.unitToSkip); + int index = prefix.lastIndexOf('.'); + if (index == -1) { + this.nameLookup.seekTypes(prefix, null, true, type, requestor); + } else { + String packageName = prefix.substring(0, index); + JavaElementRequestor elementRequestor = new JavaElementRequestor(); + this.nameLookup.seekPackageFragments(packageName, false, elementRequestor); + IPackageFragment[] fragments = elementRequestor.getPackageFragments(); + if (fragments != null) { + String className = prefix.substring(index + 1); + for (int i = 0, length = fragments.length; i < length; i++) + if (fragments[i] != null) + this.nameLookup.seekTypes(className, fragments[i], true, type, requestor); + } + } + } + + /** + * @see INameEnvironment#isPackage(char[][], char[]) + */ + public boolean isPackage(char[][] parentPackageName, char[] subPackageName) { + if (subPackageName == null || CharOperation.contains('.', subPackageName)) + return false; + if (parentPackageName == null || parentPackageName.length == 0) + return isTopLevelPackage(subPackageName); + for (int i = 0, length = parentPackageName.length; i < length; i++) + if (parentPackageName[i] == null || CharOperation.contains('.', parentPackageName[i])) + return false; + + String packageName = new String(CharOperation.concatWith(parentPackageName, subPackageName, '.')); + return this.nameLookup.findPackageFragments(packageName, false) != null; + } + + public boolean isTopLevelPackage(char[] packageName) { + return packageName != null + && !CharOperation.contains('.', packageName) + && this.nameLookup.findPackageFragments(new String(packageName), false) != null; + } + + /** + * Returns a printable string for the array. + */ + protected String toStringChar(char[] name) { + return "[" //$NON-NLS-1$ + + new String(name) + "]"; //$NON-NLS-1$ + } + + /** + * Returns a printable string for the array. + */ + protected String toStringCharChar(char[][] names) { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < names.length; i++) { + result.append(toStringChar(names[i])); + } + return result.toString(); + } + + public void cleanup() { + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/SearchableEnvironmentRequestor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/SearchableEnvironmentRequestor.java new file mode 100644 index 0000000..caf3e0f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/SearchableEnvironmentRequestor.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.codeassist.ISearchRequestor; + +/** + * Implements IJavaElementRequestor, wrappering and forwarding + * results onto a org.eclipse.jdt.internal.codeassist.api.ISearchRequestor. + */ +class SearchableEnvironmentRequestor extends JavaElementRequestor implements IJavaElementRequestor { + /** + * The ISearchRequestor this JavaElementRequestor wraps + * and forwards results to. + */ + protected ISearchRequestor fRequestor; + /** + * The ICompilationUNit this JavaElementRequestor will not + * accept types within. + */ + protected ICompilationUnit fUnitToSkip; +/** + * Constructs a SearchableEnvironmentRequestor that wraps the + * given SearchRequestor. + */ +public SearchableEnvironmentRequestor(ISearchRequestor requestor) { + fRequestor = requestor; + fUnitToSkip= null; +} +/** + * Constructs a SearchableEnvironmentRequestor that wraps the + * given SearchRequestor. The requestor will not accept types in + * the unitToSkip. + */ +public SearchableEnvironmentRequestor(ISearchRequestor requestor, ICompilationUnit unitToSkip) { + fRequestor = requestor; + fUnitToSkip= unitToSkip; +} +/** + * Do nothing, a SearchRequestor does not accept initializers + * so there is no need to forward this results. + * + * @see IJavaElementRequestor + */ +//public void acceptInitializer(IInitializer initializer) { +// +//} +/** + * @see IJavaElementRequestor + */ +public void acceptPackageFragment(IPackageFragment packageFragment) { + fRequestor.acceptPackage(packageFragment.getElementName().toCharArray()); +} +/** + * @see IJavaElementRequestor + */ +public void acceptType(IType type) { + try { + if (fUnitToSkip != null && fUnitToSkip.equals(type.getCompilationUnit())){ + return; + } + if (type.isClass()) { + fRequestor.acceptClass(type.getPackageFragment().getElementName().toCharArray(), type.getElementName().toCharArray(), type.getFlags()); + } else { + fRequestor.acceptInterface(type.getPackageFragment().getElementName().toCharArray(), type.getElementName().toCharArray(), type.getFlags()); + } + } catch (JavaModelException npe) { + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/SetClasspathOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/SetClasspathOperation.java new file mode 100644 index 0000000..513ad3d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/SetClasspathOperation.java @@ -0,0 +1,837 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; + +import net.sourceforge.phpdt.core.IClasspathEntry; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaElementDelta; +import net.sourceforge.phpdt.core.IJavaModel; +import net.sourceforge.phpdt.core.IJavaModelStatus; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.compiler.util.ObjectVector; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * This operation sets an IJavaProject's classpath. + * + * @see IJavaProject + */ +public class SetClasspathOperation extends JavaModelOperation { + + IClasspathEntry[] oldResolvedPath, newResolvedPath; + IClasspathEntry[] newRawPath; + boolean canChangeResource; + boolean needCycleCheck; + boolean needValidation; + boolean needSave; + IPath newOutputLocation; + + public static final IClasspathEntry[] ReuseClasspath = new IClasspathEntry[0]; + public static final IClasspathEntry[] UpdateClasspath = new IClasspathEntry[0]; + // if reusing output location, then also reuse clean flag + public static final IPath ReuseOutputLocation = new Path("Reuse Existing Output Location"); //$NON-NLS-1$ + + /** + * When executed, this operation sets the classpath of the given project. + */ + public SetClasspathOperation( + IJavaProject project, + IClasspathEntry[] oldResolvedPath, + IClasspathEntry[] newRawPath, + IPath newOutputLocation, + boolean canChangeResource, + boolean needValidation, + boolean needSave) { + + super(new IJavaElement[] { project }); + this.oldResolvedPath = oldResolvedPath; + this.newRawPath = newRawPath; + this.newOutputLocation = newOutputLocation; + this.canChangeResource = canChangeResource; + this.needValidation = needValidation; + this.needSave = needSave; + } + + /** + * Adds deltas for the given roots, with the specified change flag, + * and closes the root. Helper method for #setClasspath + */ + protected void addClasspathDeltas( + IPackageFragmentRoot[] roots, + int flag, + JavaElementDelta delta) { + + for (int i = 0; i < roots.length; i++) { + IPackageFragmentRoot root = roots[i]; + delta.changed(root, flag); + if ((flag & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0 + || (flag & IJavaElementDelta.F_SOURCEATTACHED) != 0 + || (flag & IJavaElementDelta.F_SOURCEDETACHED) != 0){ + try { + root.close(); + } catch (JavaModelException e) { + } + // force detach source on jar package fragment roots (source will be lazily computed when needed) + ((PackageFragmentRoot) root).setSourceAttachmentProperty(null);// loose info - will be recomputed + } + } + } + + + + /** + * Returns the index of the item in the list if the given list contains the specified entry. If the list does + * not contain the entry, -1 is returned. + * A helper method for #setClasspath + */ + protected int classpathContains( + IClasspathEntry[] list, + IClasspathEntry entry) { + + IPath[] exclusionPatterns = entry.getExclusionPatterns(); + nextEntry: for (int i = 0; i < list.length; i++) { + IClasspathEntry other = list[i]; + if (other.getContentKind() == entry.getContentKind() + && other.getEntryKind() == entry.getEntryKind() + && other.isExported() == entry.isExported() + && other.getPath().equals(entry.getPath())) { + // check custom outputs + IPath entryOutput = entry.getOutputLocation(); + IPath otherOutput = other.getOutputLocation(); + if (entryOutput == null) { + if (otherOutput != null) + continue; + } else { + if (!entryOutput.equals(otherOutput)) + continue; + } + + // check exclusion patterns + IPath[] otherExcludes = other.getExclusionPatterns(); + if (exclusionPatterns != otherExcludes) { + int excludeLength = exclusionPatterns.length; + if (otherExcludes.length != excludeLength) + continue; + for (int j = 0; j < excludeLength; j++) { + // compare toStrings instead of IPaths + // since IPath.equals is specified to ignore trailing separators + if (!exclusionPatterns[j].toString().equals(otherExcludes[j].toString())) + continue nextEntry; + } + } + return i; + } + } + return -1; + } + + /** + * Recursively adds all subfolders of folder to the given collection. + */ + protected void collectAllSubfolders(IFolder folder, ArrayList collection) throws JavaModelException { + try { + IResource[] members= folder.members(); + for (int i = 0, max = members.length; i < max; i++) { + IResource r= members[i]; + if (r.getType() == IResource.FOLDER) { + collection.add(r); + collectAllSubfolders((IFolder)r, collection); + } + } + } catch (CoreException e) { + throw new JavaModelException(e); + } + } + + /** + * Returns a collection of package fragments that have been added/removed + * as the result of changing the output location to/from the given + * location. The collection is empty if no package fragments are + * affected. + */ +// protected ArrayList determineAffectedPackageFragments(IPath location) throws JavaModelException { +// ArrayList fragments = new ArrayList(); +// JavaProject project =getProject(); +// +// // see if this will cause any package fragments to be affected +// IWorkspace workspace = ResourcesPlugin.getWorkspace(); +// IResource resource = null; +// if (location != null) { +// resource = workspace.getRoot().findMember(location); +// } +// if (resource != null && resource.getType() == IResource.FOLDER) { +// IFolder folder = (IFolder) resource; +// // only changes if it actually existed +// IClasspathEntry[] classpath = project.getExpandedClasspath(true); +// for (int i = 0; i < classpath.length; i++) { +// IClasspathEntry entry = classpath[i]; +// IPath path = classpath[i].getPath(); +// if (entry.getEntryKind() != IClasspathEntry.CPE_PROJECT && path.isPrefixOf(location) && !path.equals(location)) { +// IPackageFragmentRoot[] roots = project.computePackageFragmentRoots(classpath[i]); +// IPackageFragmentRoot root = roots[0]; +// // now the output location becomes a package fragment - along with any subfolders +// ArrayList folders = new ArrayList(); +// folders.add(folder); +// collectAllSubfolders(folder, folders); +// Iterator elements = folders.iterator(); +// int segments = path.segmentCount(); +// while (elements.hasNext()) { +// IFolder f = (IFolder) elements.next(); +// IPath relativePath = f.getFullPath().removeFirstSegments(segments); +// String name = relativePath.toOSString(); +// name = name.replace(File.pathSeparatorChar, '.'); +// if (name.endsWith(".")) { //$NON-NLS-1$ +// name = name.substring(0, name.length() - 1); +// } +// IPackageFragment pkg = root.getPackageFragment(name); +// fragments.add(pkg); +// } +// } +// } +// } +// return fragments; +// } + + /** + * Sets the classpath of the pre-specified project. + */ + protected void executeOperation() throws JavaModelException { + // project reference updated - may throw an exception if unable to write .project file + updateProjectReferencesIfNecessary(); + + // classpath file updated - may throw an exception if unable to write .classpath file + saveClasspathIfNecessary(); + + // perform classpath and output location updates, if exception occurs in classpath update, + // make sure the output location is updated before surfacing the exception (in case the output + // location update also throws an exception, give priority to the classpath update one). + JavaModelException originalException = null; + + try { + JavaProject project = getProject(); + if (this.newRawPath == UpdateClasspath) this.newRawPath = project.getRawClasspath(); + if (this.newRawPath != ReuseClasspath){ + updateClasspath(); +// project.updatePackageFragmentRoots(); + JavaModelManager.getJavaModelManager().deltaProcessor.addForRefresh(project); + } + + } catch(JavaModelException e){ + originalException = e; + throw e; + + } finally { // if traversed by an exception we still need to update the output location when necessary + + try { + if (this.newOutputLocation != ReuseOutputLocation) updateOutputLocation(); + + } catch(JavaModelException e){ + if (originalException != null) throw originalException; + throw e; + } + } + done(); + } + + /** + * Generates the delta of removed/added/reordered roots. + * Use three deltas in case the same root is removed/added/reordered (for + * instance, if it is changed from K_SOURCE to K_BINARY or vice versa) + */ +// protected void generateClasspathChangeDeltas( +// IClasspathEntry[] oldResolvedPath, +// IClasspathEntry[] newResolvedPath, +// final JavaProject project) { +// +// JavaModelManager manager = JavaModelManager.getJavaModelManager(); +// boolean needToUpdateDependents = false; +// JavaElementDelta delta = new JavaElementDelta(getJavaModel()); +// boolean hasDelta = false; +// int oldLength = oldResolvedPath.length; +// int newLength = newResolvedPath.length; +// +// final IndexManager indexManager = manager.getIndexManager(); +// Map oldRoots = null; +// IPackageFragmentRoot[] roots = null; +// if (project.isOpen()) { +// try { +// roots = project.getPackageFragmentRoots(); +// } catch (JavaModelException e) { +// } +// } else { +// Map allRemovedRoots ; +// if ((allRemovedRoots = manager.deltaProcessor.removedRoots) != null) { +// roots = (IPackageFragmentRoot[]) allRemovedRoots.get(project); +// } +// } +// if (roots != null) { +// oldRoots = new HashMap(); +// for (int i = 0; i < roots.length; i++) { +// IPackageFragmentRoot root = roots[i]; +// oldRoots.put(root.getPath(), root); +// } +// } +// for (int i = 0; i < oldLength; i++) { +// +// int index = classpathContains(newResolvedPath, oldResolvedPath[i]); +// if (index == -1) { +// // do not notify remote project changes +// if (oldResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){ +// needToUpdateDependents = true; +// this.needCycleCheck = true; +// continue; +// } +// +// IPackageFragmentRoot[] pkgFragmentRoots = null; +// if (oldRoots != null) { +// IPackageFragmentRoot oldRoot = (IPackageFragmentRoot) oldRoots.get(oldResolvedPath[i].getPath()); +// if (oldRoot != null) { // use old root if any (could be none if entry wasn't bound) +// pkgFragmentRoots = new IPackageFragmentRoot[] { oldRoot }; +// } +// } +// if (pkgFragmentRoots == null) { +// try { +// ObjectVector accumulatedRoots = new ObjectVector(); +// HashSet rootIDs = new HashSet(5); +// rootIDs.add(project.rootID()); +// project.computePackageFragmentRoots( +// oldResolvedPath[i], +// accumulatedRoots, +// rootIDs, +// true, // inside original project +// false, // don't check existency +// false); // don't retrieve exported roots +// pkgFragmentRoots = new IPackageFragmentRoot[accumulatedRoots.size()]; +// accumulatedRoots.copyInto(pkgFragmentRoots); +// } catch (JavaModelException e) { +// pkgFragmentRoots = new IPackageFragmentRoot[] {}; +// } +// } +// addClasspathDeltas(pkgFragmentRoots, IJavaElementDelta.F_REMOVED_FROM_CLASSPATH, delta); +// +// int changeKind = oldResolvedPath[i].getEntryKind(); +// needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE) || oldResolvedPath[i].isExported(); +// +// // Remove the .java files from the index for a source folder +// // For a lib folder or a .jar file, remove the corresponding index if not shared. +// if (indexManager != null) { +// IClasspathEntry oldEntry = oldResolvedPath[i]; +// final IPath path = oldEntry.getPath(); +// switch (changeKind) { +// case IClasspathEntry.CPE_SOURCE: +// final char[][] exclusionPatterns = ((ClasspathEntry)oldEntry).fullExclusionPatternChars(); +// postAction(new IPostAction() { +// public String getID() { +// return path.toString(); +// } +// public void run() throws JavaModelException { +// indexManager.removeSourceFolderFromIndex(project, path, exclusionPatterns); +// } +// }, +// REMOVEALL_APPEND); +// break; +// case IClasspathEntry.CPE_LIBRARY: +// final DeltaProcessor deltaProcessor = manager.deltaProcessor; +// postAction(new IPostAction() { +// public String getID() { +// return path.toString(); +// } +// public void run() throws JavaModelException { +// if (deltaProcessor.otherRoots.get(path) == null) { // if root was not shared +// indexManager.discardJobs(path.toString()); +// indexManager.removeIndex(path); +// // TODO: we could just remove the in-memory index and have the indexing check for timestamps +// } +// } +// }, +// REMOVEALL_APPEND); +// break; +// } +// } +// hasDelta = true; +// +// } else { +// // do not notify remote project changes +// if (oldResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){ +// this.needCycleCheck |= (oldResolvedPath[i].isExported() != newResolvedPath[index].isExported()); +// continue; +// } +// needToUpdateDependents |= (oldResolvedPath[i].isExported() != newResolvedPath[index].isExported()); +// if (index != i) { //reordering of the classpath +// addClasspathDeltas( +// project.computePackageFragmentRoots(oldResolvedPath[i]), +// IJavaElementDelta.F_REORDER, +// delta); +// int changeKind = oldResolvedPath[i].getEntryKind(); +// needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE); +// +// hasDelta = true; +// } +// +// // check source attachment +// IPath newSourcePath = newResolvedPath[index].getSourceAttachmentPath(); +// int sourceAttachmentFlags = +// this.getSourceAttachmentDeltaFlag( +// oldResolvedPath[i].getSourceAttachmentPath(), +// newSourcePath, +// null/*not a source root path*/); +// int sourceAttachmentRootFlags = +// this.getSourceAttachmentDeltaFlag( +// oldResolvedPath[i].getSourceAttachmentRootPath(), +// newResolvedPath[index].getSourceAttachmentRootPath(), +// newSourcePath/*in case both root paths are null*/); +// int flags = sourceAttachmentFlags | sourceAttachmentRootFlags; +// if (flags != 0) { +// addClasspathDeltas( +// project.computePackageFragmentRoots(oldResolvedPath[i]), +// flags, +// delta); +// hasDelta = true; +// } +// } +// } +// +// for (int i = 0; i < newLength; i++) { +// +// int index = classpathContains(oldResolvedPath, newResolvedPath[i]); +// if (index == -1) { +// // do not notify remote project changes +// if (newResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){ +// needToUpdateDependents = true; +// this.needCycleCheck = true; +// continue; +// } +// addClasspathDeltas( +// project.computePackageFragmentRoots(newResolvedPath[i]), +// IJavaElementDelta.F_ADDED_TO_CLASSPATH, +// delta); +// int changeKind = newResolvedPath[i].getEntryKind(); +// +// // Request indexing +// if (indexManager != null) { +// switch (changeKind) { +// case IClasspathEntry.CPE_LIBRARY: +// boolean pathHasChanged = true; +// final IPath newPath = newResolvedPath[i].getPath(); +// for (int j = 0; j < oldLength; j++) { +// IClasspathEntry oldEntry = oldResolvedPath[j]; +// if (oldEntry.getPath().equals(newPath)) { +// pathHasChanged = false; +// break; +// } +// } +// if (pathHasChanged) { +// postAction(new IPostAction() { +// public String getID() { +// return newPath.toString(); +// } +// public void run() throws JavaModelException { +// indexManager.indexLibrary(newPath, project.getProject()); +// } +// }, +// REMOVEALL_APPEND); +// } +// break; +// case IClasspathEntry.CPE_SOURCE: +// IClasspathEntry entry = newResolvedPath[i]; +// final IPath path = entry.getPath(); +// final char[][] exclusionPatterns = ((ClasspathEntry)entry).fullExclusionPatternChars(); +// postAction(new IPostAction() { +// public String getID() { +// return path.toString(); +// } +// public void run() throws JavaModelException { +// indexManager.indexSourceFolder(project, path, exclusionPatterns); +// } +// }, +// APPEND); // append so that a removeSourceFolder action is not removed +// break; +// } +// } +// +// needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE) || newResolvedPath[i].isExported(); +// hasDelta = true; +// +// } // classpath reordering has already been generated in previous loop +// } +// +// if (hasDelta) { +// this.addDelta(delta); +// } +// if (needToUpdateDependents){ +// updateAffectedProjects(project.getProject().getFullPath()); +// } +// } + + protected JavaProject getProject() { + return ((JavaProject) getElementsToProcess()[0]); + } + + /* + * Returns the source attachment flag for the delta between the 2 give source paths. + * Returns either F_SOURCEATTACHED, F_SOURCEDETACHED, F_SOURCEATTACHED | F_SOURCEDETACHED + * or 0 if there is no difference. + */ + private int getSourceAttachmentDeltaFlag(IPath oldPath, IPath newPath, IPath sourcePath) { + if (oldPath == null) { + if (newPath != null) { + return IJavaElementDelta.F_SOURCEATTACHED; + } else { + if (sourcePath != null) { + // if source path is specified and no root path, it needs to be recomputed dynamically + return IJavaElementDelta.F_SOURCEATTACHED | IJavaElementDelta.F_SOURCEDETACHED; + } else { + return 0; + } + } + } else if (newPath == null) { + return IJavaElementDelta.F_SOURCEDETACHED; + } else if (!oldPath.equals(newPath)) { + return IJavaElementDelta.F_SOURCEATTACHED | IJavaElementDelta.F_SOURCEDETACHED; + } else { + return 0; + } + } + + /** + * Returns true if this operation performs no resource modifications, + * otherwise false. Subclasses must override. + */ + public boolean isReadOnly() { + return !this.canChangeResource; + } + + protected void saveClasspathIfNecessary() throws JavaModelException { + + if (!this.canChangeResource || !this.needSave) return; + + IClasspathEntry[] classpathForSave; + JavaProject project = getProject(); + if (this.newRawPath == ReuseClasspath || this.newRawPath == UpdateClasspath){ + classpathForSave = project.getRawClasspath(); + } else { + classpathForSave = this.newRawPath; + } + IPath outputLocationForSave; + if (this.newOutputLocation == ReuseOutputLocation){ + outputLocationForSave = project.getOutputLocation(); + } else { + outputLocationForSave = this.newOutputLocation; + } + // if read-only .classpath, then the classpath setting will never been performed completely + if (project.saveClasspath(classpathForSave, outputLocationForSave)) { + this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); + } + } + + public String toString(){ + StringBuffer buffer = new StringBuffer(20); + buffer.append("SetClasspathOperation\n"); //$NON-NLS-1$ + buffer.append(" - classpath : "); //$NON-NLS-1$ + if (this.newRawPath == ReuseClasspath){ + buffer.append(""); //$NON-NLS-1$ + } else { + buffer.append("{"); //$NON-NLS-1$ + for (int i = 0; i < this.newRawPath.length; i++) { + if (i > 0) buffer.append(","); //$NON-NLS-1$ + IClasspathEntry element = this.newRawPath[i]; + buffer.append(" ").append(element.toString()); //$NON-NLS-1$ + } + } + buffer.append("\n - output location : "); //$NON-NLS-1$ + if (this.newOutputLocation == ReuseOutputLocation){ + buffer.append(""); //$NON-NLS-1$ + } else { + buffer.append(this.newOutputLocation.toString()); //$NON-NLS-1$ + } + return buffer.toString(); + } + + private void updateClasspath() throws JavaModelException { + + JavaProject project = ((JavaProject) getElementsToProcess()[0]); + + beginTask(Util.bind("classpath.settingProgress", project.getElementName()), 2); //$NON-NLS-1$ + + // SIDE-EFFECT: from thereon, the classpath got modified + project.setRawClasspath0(this.newRawPath); + + // resolve new path (asking for marker creation if problems) + if (this.newResolvedPath == null) { + this.newResolvedPath = project.getResolvedClasspath(true, this.canChangeResource); + } + +// if (this.oldResolvedPath != null) { +// generateClasspathChangeDeltas( +// this.oldResolvedPath, +// this.newResolvedPath, +// project); +// } else { + this.needCycleCheck = true; + updateAffectedProjects(project.getProject().getFullPath()); +// } + + updateCycleMarkersIfNecessary(newResolvedPath); + } + + /** + * Update projects which are affected by this classpath change: + * those which refers to the current project as source + */ + protected void updateAffectedProjects(IPath prerequisiteProjectPath) { + + try { + IJavaModel model = JavaModelManager.getJavaModelManager().getJavaModel(); + IJavaProject originatingProject = getProject(); + IJavaProject[] projects = model.getJavaProjects(); + for (int i = 0, projectCount = projects.length; i < projectCount; i++) { + try { + JavaProject project = (JavaProject) projects[i]; + if (project.equals(originatingProject)) continue; // skip itself + + // consider ALL dependents (even indirect ones), since they may need to + // flush their respective namelookup caches (all pkg fragment roots). + + IClasspathEntry[] classpath = project.getExpandedClasspath(true); + for (int j = 0, entryCount = classpath.length; j < entryCount; j++) { + IClasspathEntry entry = classpath[j]; + if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT + && entry.getPath().equals(prerequisiteProjectPath)) { + project.setRawClasspath( + UpdateClasspath, + SetClasspathOperation.ReuseOutputLocation, + this.fMonitor, + this.canChangeResource, + project.getResolvedClasspath(true), + false, // updating only - no validation + false); // updating only - no need to save + break; + } + } + } catch (JavaModelException e) { + } + } + } catch (JavaModelException e) { + } + + } + + /** + * Update cycle markers + */ + protected void updateCycleMarkersIfNecessary(IClasspathEntry[] newResolvedPath) { + + if (!this.needCycleCheck) return; + if (!this.canChangeResource) return; + + try { + JavaProject project = getProject(); + if (!project.hasCycleMarker() && !project.hasClasspathCycle(project.getResolvedClasspath(true))){ + return; + } + + postAction( + new IPostAction() { + public String getID() { + return "updateCycleMarkers"; //$NON-NLS-1$ + } + public void run() throws JavaModelException { + JavaProject.updateAllCycleMarkers(); + } + }, + REMOVEALL_APPEND); + } catch(JavaModelException e){ + } + } + + /** + * Sets the output location of the pre-specified project. + * + *

        This can cause changes in package fragments, in case either the + * old or new output location folder are considered as a package fragment. + */ + protected void updateOutputLocation() throws JavaModelException { + + JavaProject project= ((JavaProject) getElementsToProcess()[0]); + + beginTask(Util.bind("classpath.settingOutputLocationProgress", project.getElementName()), 2); //$NON-NLS-1$ + + IPath oldLocation= project.getOutputLocation(); + + // see if this will cause any package fragments to be added + boolean deltaToFire= false; + JavaElementDelta delta = newJavaElementDelta(); +// ArrayList added= determineAffectedPackageFragments(oldLocation); +// Iterator iter = added.iterator(); +// while (iter.hasNext()){ +// IPackageFragment frag= (IPackageFragment)iter.next(); +// ((IPackageFragmentRoot)frag.getParent()).close(); +// if (!Util.isExcluded(frag)) { +// delta.added(frag); +// deltaToFire = true; +// } +// } + + // see if this will cause any package fragments to be removed +// ArrayList removed= determineAffectedPackageFragments(this.newOutputLocation); +// iter = removed.iterator(); +// while (iter.hasNext()){ +// IPackageFragment frag= (IPackageFragment)iter.next(); +// ((IPackageFragmentRoot)frag.getParent()).close(); +// if (!Util.isExcluded(frag)) { +// delta.removed(frag); +// deltaToFire = true; +// } +// } + + JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject()); + synchronized (perProjectInfo) { + perProjectInfo.outputLocation = this.newOutputLocation; + } + + if (deltaToFire) { + addDelta(delta); + } + worked(1); + } + + /** + * Update projects references so that the build order is consistent with the classpath + */ + protected void updateProjectReferencesIfNecessary() throws JavaModelException { + + if (!this.canChangeResource) return; + if (this.newRawPath == ReuseClasspath || this.newRawPath == UpdateClasspath) return; + + JavaProject jproject = getProject(); + String[] oldRequired = jproject.projectPrerequisites(this.oldResolvedPath); + + if (this.newResolvedPath == null) { + this.newResolvedPath = jproject.getResolvedClasspath(this.newRawPath, null, true, this.needValidation, null /*no reverse map*/); + } + String[] newRequired = jproject.projectPrerequisites(this.newResolvedPath); + + try { + IProject project = jproject.getProject(); + IProjectDescription description = project.getDescription(); + + IProject[] projectReferences = description.getReferencedProjects(); + + HashSet oldReferences = new HashSet(projectReferences.length); + for (int i = 0; i < projectReferences.length; i++){ + String projectName = projectReferences[i].getName(); + oldReferences.add(projectName); + } + HashSet newReferences = (HashSet)oldReferences.clone(); + + for (int i = 0; i < oldRequired.length; i++){ + String projectName = oldRequired[i]; + newReferences.remove(projectName); + } + for (int i = 0; i < newRequired.length; i++){ + String projectName = newRequired[i]; + newReferences.add(projectName); + } + + Iterator iter; + int newSize = newReferences.size(); + + checkIdentity: { + if (oldReferences.size() == newSize){ + iter = newReferences.iterator(); + while (iter.hasNext()){ + if (!oldReferences.contains(iter.next())){ + break checkIdentity; + } + } + return; + } + } + String[] requiredProjectNames = new String[newSize]; + int index = 0; + iter = newReferences.iterator(); + while (iter.hasNext()){ + requiredProjectNames[index++] = (String)iter.next(); + } + Util.sort(requiredProjectNames); // ensure that if changed, the order is consistent + + IProject[] requiredProjectArray = new IProject[newSize]; + IWorkspaceRoot wksRoot = project.getWorkspace().getRoot(); + for (int i = 0; i < newSize; i++){ + requiredProjectArray[i] = wksRoot.getProject(requiredProjectNames[i]); + } + + description.setReferencedProjects(requiredProjectArray); + project.setDescription(description, this.fMonitor); + + } catch(CoreException e){ + throw new JavaModelException(e); + } + } + + public IJavaModelStatus verify() { + + IJavaModelStatus status = super.verify(); + if (!status.isOK()) { + return status; + } + + if (needValidation) { + IJavaProject project = (IJavaProject) getElementToProcess(); + // retrieve classpath + IClasspathEntry[] entries = this.newRawPath; + if (entries == ReuseClasspath){ + try { + entries = project.getRawClasspath(); + } catch (JavaModelException e) { + return e.getJavaModelStatus(); + } + } + // retrieve output location + IPath outputLocation = this.newOutputLocation; + if (outputLocation == ReuseOutputLocation){ + try { + outputLocation = project.getOutputLocation(); + } catch (JavaModelException e) { + return e.getJavaModelStatus(); + } + } + + // perform validation +// return JavaConventions.validateClasspath( +// project, +// entries, +// outputLocation); + } + + return JavaModelStatus.VERIFIED_OK; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/SourceField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/SourceField.java new file mode 100644 index 0000000..14094cd --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/SourceField.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.IField; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.Signature; +import net.sourceforge.phpdt.core.jdom.IDOMNode; + +/** + * @see IField + */ + +/* package */ class SourceField extends Member implements IField { + +/** + * Constructs a handle to the field with the given name in the specified type. + */ +protected SourceField(IType parent, String name) { + super(FIELD, parent, name); +} +/** + * @see JavaElement#equalsDOMNode + */ +protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException { + return (node.getNodeType() == IDOMNode.FIELD) && super.equalsDOMNode(node); +} +/** + * @see IField + */ +public Object getConstant() throws JavaModelException { + SourceFieldElementInfo info = (SourceFieldElementInfo) getElementInfo(); + return info.initializationSource; +} +/** + * @see JavaElement#getHandleMemento() + */ +protected char getHandleMementoDelimiter() { + return JavaElement.JEM_FIELD; +} +/** + * @see IField + */ +public String getTypeSignature() throws JavaModelException { + SourceFieldElementInfo info = (SourceFieldElementInfo) getElementInfo(); + return info.getTypeSignature(); +} +/** + * @private Debugging purposes + */ +protected void toStringInfo(int tab, StringBuffer buffer, Object info) { + buffer.append(this.tabString(tab)); + if (info == null) { + buffer.append(getElementName()); + buffer.append(" (not open)"); //$NON-NLS-1$ + } else if (info == NO_INFO) { + buffer.append(getElementName()); + } else { + try { + buffer.append(Signature.toString(this.getTypeSignature())); + buffer.append(" "); //$NON-NLS-1$ + buffer.append(this.getElementName()); + } catch (JavaModelException e) { + buffer.append("null indicates no + * parameters. + */ + protected String[] fParameterTypes; + + /** + * An empty list of Strings + */ + protected static final String[] fgEmptyList= new String[] {}; +protected SourceMethod(IType parent, String name, String[] parameterTypes) { + super(METHOD, parent, name); + Assert.isTrue(name.indexOf('.') == -1); + if (parameterTypes == null) { + fParameterTypes= fgEmptyList; + } else { + fParameterTypes= parameterTypes; + } +} +protected SourceMethod(ICompilationUnit parent, String name, String[] parameterTypes) { + super(METHOD, parent, name); + Assert.isTrue(name.indexOf('.') == -1); + if (parameterTypes == null) { + fParameterTypes= fgEmptyList; + } else { + fParameterTypes= parameterTypes; + } +} +public boolean equals(Object o) { + return super.equals(o) && Util.equalArraysOrNull(fParameterTypes, ((SourceMethod)o).fParameterTypes); +} +/** + * @see JavaElement#equalsDOMNode + */ +protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException { + if (node.getNodeType() == IDOMNode.METHOD) { + IDOMMethod m = (IDOMMethod)node; + if (isConstructor()) { + return + (m.isConstructor() || m.getName().equals(this.getElementName()) /* case of a constructor that is being renamed */) + && signatureEquals(m); + } else { + return super.equalsDOMNode(node) && signatureEquals(m); + } + } else { + return false; + } + +} +/** + * @see IMethod + */ +public String[] getExceptionTypes() throws JavaModelException { + SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo(); + char[][] exs= info.getExceptionTypeNames(); + return CompilationUnitStructureRequestor.convertTypeNamesToSigs(exs); +} +/** + * @see JavaElement#getHandleMemento() + */ +public String getHandleMemento() { + StringBuffer buff = new StringBuffer(((JavaElement) getParent()).getHandleMemento()); + buff.append(getHandleMementoDelimiter()); + buff.append(getElementName()); + for (int i = 0; i < fParameterTypes.length; i++) { + buff.append(getHandleMementoDelimiter()); + buff.append(fParameterTypes[i]); + } + return buff.toString(); +} +/** + * @see JavaElement#getHandleMemento() + */ +protected char getHandleMementoDelimiter() { + return JavaElement.JEM_METHOD; +} +/** + * @see IMethod + */ +public int getNumberOfParameters() { + return fParameterTypes == null ? 0 : fParameterTypes.length; +} +/** + * @see IMethod + */ +public String[] getParameterNames() throws JavaModelException { + SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo(); + char[][] names= info.getArgumentNames(); + if (names == null || names.length == 0) { + return fgEmptyList; + } + String[] strings= new String[names.length]; + for (int i= 0; i < names.length; i++) { + strings[i]= new String(names[i]); + } + return strings; +} +/** + * @see IMethod + */ +public String[] getParameterTypes() { + return fParameterTypes; +} +/** + * @see IMethod + */ +public String getReturnType() throws JavaModelException { + SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo(); + return Signature.createTypeSignature(info.getReturnTypeName(), false); +} +/** + * @see IMethod + */ +public String getSignature() throws JavaModelException { + SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo(); + return info.getSignature(); +} +/** + * @see IMethod + */ +public boolean isConstructor() throws JavaModelException { + SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo(); + return info.isConstructor(); +} +/** + * @see IMethod#isMainMethod() + */ +public boolean isMainMethod() throws JavaModelException { + return this.isMainMethod(this); +} + +/** + * @see IMethod#isSimilar(IMethod) + */ +public boolean isSimilar(IMethod method) { + return + this.areSimilarMethods( + this.getElementName(), this.getParameterTypes(), + method.getElementName(), method.getParameterTypes(), + null); +} + +/** + */ +public String readableName() { + + StringBuffer buffer = new StringBuffer(super.readableName()); + buffer.append('('); + String[] parameterTypes = this.getParameterTypes(); + int length; + if (parameterTypes != null && (length = parameterTypes.length) > 0) { + for (int i = 0; i < length; i++) { + buffer.append(Signature.toString(parameterTypes[i])); + if (i < length - 1) { + buffer.append(", "); //$NON-NLS-1$ + } + } + } + buffer.append(')'); + return buffer.toString(); +} +/** + * Returns true if the signature of this SourceMethod matches that of the given + * IDOMMethod, otherwise false. + */ +protected boolean signatureEquals(IDOMMethod method) throws JavaModelException { + String[] otherTypes= method.getParameterTypes(); + String[] types= getParameterTypes(); + boolean ok= true; + + // ensure the number of parameters match + if (otherTypes == null || otherTypes.length == 0) { + ok= (types == null || types.length == 0); + } else if (types != null) { + ok= (otherTypes.length == types.length); + } else { + return false; + } + + // ensure the parameter type signatures match + if (ok) { + if (types != null) { + int i; + for (i= 0; i < types.length; i++) { + String otherType= Signature.createTypeSignature(otherTypes[i].toCharArray(), false); + if (!types[i].equals(otherType)) { + ok= false; + break; + } + } + } + } + + return ok; +} +/** + * @private Debugging purposes + */ +protected void toStringInfo(int tab, StringBuffer buffer, Object info) { + buffer.append(this.tabString(tab)); + if (info == null) { + buffer.append(getElementName()); + buffer.append(" (not open)"); //$NON-NLS-1$ + } else if (info == NO_INFO) { + buffer.append(getElementName()); + } else { + try { + if (Flags.isStatic(this.getFlags())) { + buffer.append("static "); //$NON-NLS-1$ + } + if (!this.isConstructor()) { + buffer.append(Signature.toString(this.getReturnType())); + buffer.append(' '); + } + buffer.append(this.getElementName()); + buffer.append('('); + String[] parameterTypes = this.getParameterTypes(); + int length; + if (parameterTypes != null && (length = parameterTypes.length) > 0) { + for (int i = 0; i < length; i++) { + buffer.append(Signature.toString(parameterTypes[i])); + if (i < length - 1) { + buffer.append(", "); //$NON-NLS-1$ + } + } + } + buffer.append(')'); + } catch (JavaModelException e) { + buffer.append(" -1 && insertion < source.length()) { +// String encoding = project.getOption(JavaCore.CORE_ENCODING, true); +// +// char[] prefix = CharOperation.concat(source.substring(0, insertion).toCharArray(), new char[]{'{'}); +// char[] suffix = CharOperation.concat(new char[]{'}'}, source.substring(insertion).toCharArray()); +// char[] fakeSource = CharOperation.concat(prefix, snippet, suffix); +// +// BasicCompilationUnit cu = +// new BasicCompilationUnit( +// fakeSource, +// null, +// getElementName(), +// encoding); +// +// engine.complete(cu, prefix.length + position, prefix.length); +// } else { +// engine.complete(this, snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic); +// } +//} +/** + * @see IType + */ +//public IField createField(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException { +// CreateFieldOperation op = new CreateFieldOperation(this, contents, force); +// if (sibling != null) { +// op.createBefore(sibling); +// } +// runOperation(op, monitor); +// return (IField) op.getResultElements()[0]; +//} +/** + * @see IType + */ +//public IInitializer createInitializer(String contents, IJavaElement sibling, IProgressMonitor monitor) throws JavaModelException { +// CreateInitializerOperation op = new CreateInitializerOperation(this, contents); +// if (sibling != null) { +// op.createBefore(sibling); +// } +// runOperation(op, monitor); +// return (IInitializer) op.getResultElements()[0]; +//} +/** + * @see IType + */ +//public IMethod createMethod(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException { +// CreateMethodOperation op = new CreateMethodOperation(this, contents, force); +// if (sibling != null) { +// op.createBefore(sibling); +// } +// runOperation(op, monitor); +// return (IMethod) op.getResultElements()[0]; +//} +/** + * @see IType + */ +//public IType createType(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException { +// CreateTypeOperation op = new CreateTypeOperation(this, contents, force); +// if (sibling != null) { +// op.createBefore(sibling); +// } +// runOperation(op, monitor); +// return (IType) op.getResultElements()[0]; +//} +/** + * @see JavaElement#equalsDOMNode + */ +protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException { + return (node.getNodeType() == IDOMNode.TYPE) && super.equalsDOMNode(node); +} +/* + * @see IType + */ +public IMethod[] findMethods(IMethod method) { + try { + return this.findMethods(method, this.getMethods()); + } catch (JavaModelException e) { + // if type doesn't exist, no matching method can exist + return null; + } +} +/** + * @see IMember + */ +public IType getDeclaringType() { + IJavaElement parent = getParent(); + while (parent != null) { + if (parent.getElementType() == IJavaElement.TYPE) { + return (IType) parent; + } else + if (parent instanceof IMember) { + parent = parent.getParent(); + } else { + return null; + } + } + return null; +} +/** + * @see IType#getField + */ +public IField getField(String name) { + return new SourceField(this, name); +} +/** + * @see IType + */ +public IField[] getFields() throws JavaModelException { + ArrayList list = getChildrenOfType(FIELD); + IField[] array= new IField[list.size()]; + list.toArray(array); + return array; +} +/** + * @see IType#getFullyQualifiedName + */ +public String getFullyQualifiedName() { + return this.getFullyQualifiedName('$'); +} +/** + * @see IType#getFullyQualifiedName(char) + */ +public String getFullyQualifiedName(char enclosingTypeSeparator) { + String packageName = getPackageFragment().getElementName(); + if (packageName.equals(IPackageFragment.DEFAULT_PACKAGE_NAME)) { + return getTypeQualifiedName(enclosingTypeSeparator); + } + return packageName + '.' + getTypeQualifiedName(enclosingTypeSeparator); +} + +/** + * @see IType + */ +//public IInitializer getInitializer(int occurrenceCount) { +// return new Initializer(this, occurrenceCount); +//} +/** + * @see IType + */ +//public IInitializer[] getInitializers() throws JavaModelException { +// ArrayList list = getChildrenOfType(INITIALIZER); +// IInitializer[] array= new IInitializer[list.size()]; +// list.toArray(array); +// return array; +//} +/** + * @see IType#getMethod + */ +public IMethod getMethod(String name, String[] parameterTypeSignatures) { + return new SourceMethod(this, name, parameterTypeSignatures); +} +/** + * @see IType + */ +public IMethod[] getMethods() throws JavaModelException { + ArrayList list = getChildrenOfType(METHOD); + IMethod[] array= new IMethod[list.size()]; + list.toArray(array); + return array; +} +/** + * @see IType + */ +public IPackageFragment getPackageFragment() { + IJavaElement parent = fParent; + while (parent != null) { + if (parent.getElementType() == IJavaElement.PACKAGE_FRAGMENT) { + return (IPackageFragment) parent; + } + else { + parent = parent.getParent(); + } + } + Assert.isTrue(false); // should not happen + return null; +} +/** + * @see IType + */ +public String getSuperclassName() throws JavaModelException { + SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo(); + char[] superclassName= info.getSuperclassName(); + if (superclassName == null) { + return null; + } + return new String(superclassName); +} +/** + * @see IType + */ +public String[] getSuperInterfaceNames() throws JavaModelException { + SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo(); + char[][] names= info.getInterfaceNames(); + if (names == null) { + return fgEmptyList; + } + String[] strings= new String[names.length]; + for (int i= 0; i < names.length; i++) { + strings[i]= new String(names[i]); + } + return strings; +} +/** + * @see IType + */ +public IType getType(String name) { + return new SourceType(this, name); +} +/** + * @see IType#getTypeQualifiedName + */ +public String getTypeQualifiedName() { + return this.getTypeQualifiedName('$'); +} +/** + * @see IType#getTypeQualifiedName(char) + */ +public String getTypeQualifiedName(char enclosingTypeSeparator) { + if (fParent.getElementType() == IJavaElement.COMPILATION_UNIT) { + return fName; + } else { + return ((IType) fParent).getTypeQualifiedName(enclosingTypeSeparator) + enclosingTypeSeparator + fName; + } +} + +/** + * @see IType + */ +public IType[] getTypes() throws JavaModelException { + ArrayList list= getChildrenOfType(TYPE); + IType[] array= new IType[list.size()]; + list.toArray(array); + return array; +} +/** + * @see IParent + */ +public boolean hasChildren() throws JavaModelException { + return getChildren().length > 0; +} +/** + * @see IType#isAnonymous() + */ +public boolean isAnonymous() throws JavaModelException { + return false; // cannot create source handle onto anonymous types +} +/** + * @see IType + */ +public boolean isClass() throws JavaModelException { + return !isInterface(); +} +/** + * @see IType + */ +public boolean isInterface() throws JavaModelException { + SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo(); + return info.isInterface(); +} +/** + * @see IType#isLocal() + */ +public boolean isLocal() throws JavaModelException { + return false; // cannot create source handle onto local types +} +/** + * @see IType#isMember() + */ +public boolean isMember() throws JavaModelException { + return getDeclaringType() != null; +} +/** + * @see IType + */ +//public ITypeHierarchy loadTypeHierachy(InputStream input, IProgressMonitor monitor) throws JavaModelException { +// return TypeHierarchy.load(this, input); +//} +/** + * @see IType + */ +//public ITypeHierarchy newSupertypeHierarchy(IProgressMonitor monitor) throws JavaModelException { +// return this.newSupertypeHierarchy(null, monitor); +//} +/** + * @see IType#newSupertypeHierarchy(IWorkingCopy[], IProgressMonitor) + */ +//public ITypeHierarchy newSupertypeHierarchy( +// IWorkingCopy[] workingCopies, +// IProgressMonitor monitor) +// throws JavaModelException { +// +// CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), false); +// runOperation(op, monitor); +// return op.getResult(); +//} + +/** + * @see IType + */ +//public ITypeHierarchy newTypeHierarchy(IProgressMonitor monitor) throws JavaModelException { +// return this.newTypeHierarchy((IWorkingCopy[])null, monitor); +//} +/** + * @see IType#newTypeHierarchy(IWorkingCopy[], IProgressMonitor) + */ +//public ITypeHierarchy newTypeHierarchy( +// IWorkingCopy[] workingCopies, +// IProgressMonitor monitor) +// throws JavaModelException { +// +// CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), true); +// runOperation(op, monitor); +// return op.getResult(); +//} + +/** + * @see IType + */ +//public ITypeHierarchy newTypeHierarchy(IJavaProject project, IProgressMonitor monitor) throws JavaModelException { +// if (project == null) { +// throw new IllegalArgumentException(Util.bind("hierarchy.nullProject")); //$NON-NLS-1$ +// } +// +// CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation( +// this, +// (IWorkingCopy[])null, // no working copies +// project, +// true); +// runOperation(op, monitor); +// return op.getResult(); +//} +/** + * See ISourceType.resolveType(...) + */ + +// public String[][] resolveType(String typeName) throws JavaModelException { +// ISourceType info = (ISourceType) this.getElementInfo(); +// ISearchableNameEnvironment environment = ((JavaProject)getJavaProject()).getSearchableNameEnvironment(); +// +// class TypeResolveRequestor implements ISelectionRequestor { +// String[][] answers = null; +// void acceptType(String[] answer){ +// if (answers == null) { +// answers = new String[][]{ answer }; +// } else { +// // grow +// int length = answers.length; +// System.arraycopy(answers, 0, answers = new String[length+1][], 0, length); +// answers[length] = answer; +// } +// } +// public void acceptClass(char[] packageName, char[] className, boolean needQualification) { +// acceptType(new String[] { new String(packageName), new String(className) }); +// } +// +// public void acceptInterface(char[] packageName, char[] interfaceName, boolean needQualification) { +// acceptType(new String[] { new String(packageName), new String(interfaceName) }); +// } +// +// public void acceptError(IProblem error) {} +// public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name) {} +// public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, boolean isConstructor) {} +// public void acceptPackage(char[] packageName){} +// +// } +// TypeResolveRequestor requestor = new TypeResolveRequestor(); +// SelectionEngine engine = +// new SelectionEngine(environment, requestor, this.getJavaProject().getOptions(true)); +// +// IType[] topLevelTypes = this.getCompilationUnit().getTypes(); +// int length = topLevelTypes.length; +// ISourceType[] topLevelInfos = new ISourceType[length]; +// for (int i = 0; i < length; i++) { +// topLevelInfos[i] = (ISourceType)((SourceType)topLevelTypes[i]).getElementInfo(); +// } +// +// engine.selectType(info, typeName.toCharArray(), topLevelInfos, false); +// return requestor.answers; +//} +/** + * @private Debugging purposes + */ +protected void toStringInfo(int tab, StringBuffer buffer, Object info) { + buffer.append(this.tabString(tab)); + if (info == null) { + buffer.append(this.getElementName()); + buffer.append(" (not open)"); //$NON-NLS-1$ + } else if (info == NO_INFO) { + buffer.append(getElementName()); + } else { + try { + if (this.isInterface()) { + buffer.append("interface "); //$NON-NLS-1$ + } else { + buffer.append("class "); //$NON-NLS-1$ + } + buffer.append(this.getElementName()); + } catch (JavaModelException e) { + buffer.append("null if this type is a top level type. + */ +public ISourceType getEnclosingType() { + IJavaElement parent= fHandle.getParent(); + if (parent != null && parent.getElementType() == IJavaElement.TYPE) { + try { + return (ISourceType)((JavaElement)parent).getElementInfo(); + } catch (JavaModelException e) { + return null; + } + } else { + return null; + } +} +/** + * @see ISourceType + */ +public char[] getEnclosingTypeName() { + return fEnclosingTypeName; +} +/** + * @see ISourceType + */ +public ISourceField[] getFields() { + int length = fChildren.length; + if (length == 0) return NO_FIELDS; + ISourceField[] fields = new ISourceField[length]; + int fieldIndex = 0; + for (int i = 0; i < length; i++) { + IJavaElement child = fChildren[i]; + if (child instanceof SourceField) { + try { + ISourceField field = (ISourceField)((SourceField)child).getElementInfo(); + fields[fieldIndex++] = field; + } catch (JavaModelException e) { + } + } + } + if (fieldIndex == 0) return NO_FIELDS; + System.arraycopy(fields, 0, fields = new ISourceField[fieldIndex], 0, fieldIndex); + return fields; +} +/** + * @see ISourceType + */ +public char[] getFileName() { + return fSourceFileName; +} +/** + * Returns the handle for this type info + */ +public IType getHandle() { + return fHandle; +} +/** + * @see ISourceType + */ +public char[][] getImports() { + return fImports; +} +/** + * @see ISourceType + */ +public char[][] getInterfaceNames() { + return fSuperInterfaceNames; +} +/** + * @see ISourceType + */ +public ISourceType[] getMemberTypes() { + int length = fChildren.length; + if (length == 0) return NO_TYPES; + ISourceType[] memberTypes = new ISourceType[length]; + int typeIndex = 0; + for (int i = 0; i < length; i++) { + IJavaElement child = fChildren[i]; + if (child instanceof SourceType) { + try { + ISourceType type = (ISourceType)((SourceType)child).getElementInfo(); + memberTypes[typeIndex++] = type; + } catch (JavaModelException e) { + } + } + } + if (typeIndex == 0) return NO_TYPES; + System.arraycopy(memberTypes, 0, memberTypes = new ISourceType[typeIndex], 0, typeIndex); + return memberTypes; +} +/** + * @see ISourceType + */ +public ISourceMethod[] getMethods() { + int length = fChildren.length; + if (length == 0) return NO_METHODS; + ISourceMethod[] methods = new ISourceMethod[length]; + int methodIndex = 0; + for (int i = 0; i < length; i++) { + IJavaElement child = fChildren[i]; + if (child instanceof SourceMethod) { + try { + ISourceMethod method = (ISourceMethod)((SourceMethod)child).getElementInfo(); + methods[methodIndex++] = method; + } catch (JavaModelException e) { + } + } + } + if (methodIndex == 0) return NO_METHODS; + System.arraycopy(methods, 0, methods = new ISourceMethod[methodIndex], 0, methodIndex); + return methods; +} +/** + * @see ISourceType + */ +public char[] getPackageName() { + return fPackageName; +} +/** + * @see ISourceType + */ +public char[] getQualifiedName() { + return fQualifiedName; +} +/** + * @see ISourceType + */ +public char[] getSuperclassName() { + return fSuperclassName; +} +/** + * @see ISourceType + */ +public boolean isBinaryType() { + return false; +} +/** + * @see ISourceType + */ +public boolean isClass() { + return (this.flags & IConstants.AccInterface) == 0; +} +/** + * @see ISourceType + */ +public boolean isInterface() { + return (this.flags & IConstants.AccInterface) != 0; +} +/** + * Sets the (unqualified) name of the type that encloses this type. + */ +protected void setEnclosingTypeName(char[] enclosingTypeName) { + fEnclosingTypeName = enclosingTypeName; +} +/** + * Sets the handle for this type info + */ +protected void setHandle(IType handle) { + fHandle= handle; +} +/** + * Sets the name of the package this type is declared in. + */ +protected void setPackageName(char[] name) { + fPackageName= name; +} +/** + * Sets this type's qualified name. + */ +protected void setQualifiedName(char[] name) { + fQualifiedName= name; +} +/** + * Sets the name of the source file this type is declared in. + */ +protected void setSourceFileName(char[] name) { + fSourceFileName= name; +} +/** + * Sets the (unqualified) name of this type's superclass + */ +protected void setSuperclassName(char[] superclassName) { + fSuperclassName = superclassName; +} +/** + * Sets the (unqualified) names of the interfaces this type implements or extends + */ +protected void setSuperInterfaceNames(char[][] superInterfaceNames) { + fSuperInterfaceNames = superInterfaceNames; +} +public String toString() { + return "Info for " + fHandle.toString(); //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Util.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Util.java index 93c2697..825cd1a 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Util.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Util.java @@ -10,18 +10,28 @@ *******************************************************************************/ package net.sourceforge.phpdt.internal.core; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; import java.util.StringTokenizer; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; +import net.sourceforge.phpdt.core.IPackageFragment; import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.Signature; import net.sourceforge.phpdt.core.compiler.CharOperation; import net.sourceforge.phpdt.internal.core.util.CharArrayBuffer; import net.sourceforge.phpdt.internal.corext.Assert; +import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil; import net.sourceforge.phpeclipse.PHPCore; +import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; @@ -65,16 +75,16 @@ public class Util { /* Bundle containing messages */ protected static ResourceBundle bundle; - private final static String bundleName = "org.eclipse.jdt.internal.core.messages"; //$NON-NLS-1$ + private final static String bundleName = "net.sourceforge.phpdt.internal.core.messages"; //$NON-NLS-1$ - public final static char[] SUFFIX_class = ".class".toCharArray(); //$NON-NLS-1$ - public final static char[] SUFFIX_CLASS = ".CLASS".toCharArray(); //$NON-NLS-1$ - public final static char[] SUFFIX_java = ".java".toCharArray(); //$NON-NLS-1$ - public final static char[] SUFFIX_JAVA = ".JAVA".toCharArray(); //$NON-NLS-1$ - public final static char[] SUFFIX_jar = ".jar".toCharArray(); //$NON-NLS-1$ - public final static char[] SUFFIX_JAR = ".JAR".toCharArray(); //$NON-NLS-1$ - public final static char[] SUFFIX_zip = ".zip".toCharArray(); //$NON-NLS-1$ - public final static char[] SUFFIX_ZIP = ".ZIP".toCharArray(); //$NON-NLS-1$ +// public final static char[] SUFFIX_class = ".class".toCharArray(); //$NON-NLS-1$ +// public final static char[] SUFFIX_CLASS = ".CLASS".toCharArray(); //$NON-NLS-1$ +// public final static char[] SUFFIX_java = ".java".toCharArray(); //$NON-NLS-1$ +// public final static char[] SUFFIX_JAVA = ".JAVA".toCharArray(); //$NON-NLS-1$ +// public final static char[] SUFFIX_jar = ".jar".toCharArray(); //$NON-NLS-1$ +// public final static char[] SUFFIX_JAR = ".JAR".toCharArray(); //$NON-NLS-1$ +// public final static char[] SUFFIX_zip = ".zip".toCharArray(); //$NON-NLS-1$ +// public final static char[] SUFFIX_ZIP = ".ZIP".toCharArray(); //$NON-NLS-1$ static { String ver = System.getProperty("java.version"); //$NON-NLS-1$ @@ -583,104 +593,106 @@ public class Util { return count; } -// /** -// * Returns the given file's contents as a byte array. -// */ -// public static byte[] getResourceContentsAsByteArray(IFile file) throws JavaModelException { -// InputStream stream= null; -// try { -// stream = new BufferedInputStream(file.getContents(true)); -// } catch (CoreException e) { -// throw new JavaModelException(e); -// } -// try { -// return org.eclipse.jdt.internal.compiler.util.Util.getInputStreamAsByteArray(stream, -1); -// } catch (IOException e) { -// throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); -// } finally { -// try { -// stream.close(); -// } catch (IOException e) { -// } -// } -// } -// -// /** -// * Returns the given file's contents as a character array. -// */ -// public static char[] getResourceContentsAsCharArray(IFile file) throws JavaModelException { -// String encoding = JavaCore.create(file.getProject()).getOption(JavaCore.CORE_ENCODING, true); -// return getResourceContentsAsCharArray(file, encoding); -// } -// -// public static char[] getResourceContentsAsCharArray(IFile file, String encoding) throws JavaModelException { -// InputStream stream= null; -// try { -// stream = new BufferedInputStream(file.getContents(true)); -// } catch (CoreException e) { -// throw new JavaModelException(e, IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST); -// } -// try { -// return org.eclipse.jdt.internal.compiler.util.Util.getInputStreamAsCharArray(stream, -1, encoding); -// } catch (IOException e) { -// throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); -// } finally { -// try { -// stream.close(); -// } catch (IOException e) { -// } -// } -// } -// -// /** -// * Returns a trimmed version the simples names returned by Signature. -// */ -// public static String[] getTrimmedSimpleNames(String name) { -// String[] result = Signature.getSimpleNames(name); -// if (result == null) return null; -// for (int i = 0, length = result.length; i < length; i++) { -// result[i] = result[i].trim(); -// } -// return result; -// } + /** + * Returns the given file's contents as a byte array. + */ + public static byte[] getResourceContentsAsByteArray(IFile file) throws JavaModelException { + InputStream stream= null; + try { + stream = new BufferedInputStream(file.getContents(true)); + } catch (CoreException e) { + throw new JavaModelException(e); + } + try { + return net.sourceforge.phpdt.internal.compiler.util.Util.getInputStreamAsByteArray(stream, -1); + } catch (IOException e) { + throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); + } finally { + try { + stream.close(); + } catch (IOException e) { + } + } + } /** - * Returns true iff str.toLowerCase().endsWith(".class") - * implementation is not creating extra strings. + * Returns the given file's contents as a character array. */ - public final static boolean isClassFileName(String name) { - int nameLength = name == null ? 0 : name.length(); - int suffixLength = SUFFIX_CLASS.length; - if (nameLength < suffixLength) return false; + public static char[] getResourceContentsAsCharArray(IFile file) throws JavaModelException { + String encoding = PHPCore.create(file.getProject()).getOption(PHPCore.CORE_ENCODING, true); + return getResourceContentsAsCharArray(file, encoding); + } - for (int i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) { - char c = name.charAt(offset + i); - if (c != SUFFIX_class[i] && c != SUFFIX_CLASS[i]) return false; + public static char[] getResourceContentsAsCharArray(IFile file, String encoding) throws JavaModelException { + InputStream stream= null; + try { + stream = new BufferedInputStream(file.getContents(true)); + } catch (CoreException e) { + throw new JavaModelException(e, IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST); + } + try { + return net.sourceforge.phpdt.internal.compiler.util.Util.getInputStreamAsCharArray(stream, -1, encoding); + } catch (IOException e) { + throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); + } finally { + try { + stream.close(); + } catch (IOException e) { + } } - return true; } + /** + * Returns a trimmed version the simples names returned by Signature. + */ + public static String[] getTrimmedSimpleNames(String name) { + String[] result = Signature.getSimpleNames(name); + if (result == null) return null; + for (int i = 0, length = result.length; i < length; i++) { + result[i] = result[i].trim(); + } + return result; + } + + /** + * Returns true iff str.toLowerCase().endsWith(".class") + * implementation is not creating extra strings. + */ +// public final static boolean isClassFileName(String name) { +// int nameLength = name == null ? 0 : name.length(); +// int suffixLength = SUFFIX_CLASS.length; +// if (nameLength < suffixLength) return false; +// +// for (int i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) { +// char c = name.charAt(offset + i); +// if (c != SUFFIX_class[i] && c != SUFFIX_CLASS[i]) return false; +// } +// return true; +// } + /* * Returns whether the given java element is exluded from its root's classpath. */ -// public static final boolean isExcluded(IJavaElement element) { -// int elementType = element.getElementType(); -// switch (elementType) { + public static final boolean isExcluded(IJavaElement element) { + int elementType = element.getElementType(); + PackageFragmentRoot root = null; + IResource resource = null; + switch (elementType) { // case IJavaElement.PACKAGE_FRAGMENT: // PackageFragmentRoot root = (PackageFragmentRoot)element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); // IResource resource = element.getResource(); // return resource != null && Util.isExcluded(resource, root.fullExclusionPatternChars()); -// case IJavaElement.COMPILATION_UNIT: -// root = (PackageFragmentRoot)element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); -// resource = element.getResource(); -// if (resource != null && Util.isExcluded(resource, root.fullExclusionPatternChars())) -// return true; -// return isExcluded(element.getParent()); -// default: -// IJavaElement cu = element.getAncestor(IJavaElement.COMPILATION_UNIT); -// return cu != null && isExcluded(cu); -// } -// } + case IJavaElement.COMPILATION_UNIT: + root = (PackageFragmentRoot)element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); + resource = element.getResource(); + if (resource != null && Util.isExcluded(resource, root.fullExclusionPatternChars())) + return true; + return isExcluded(element.getParent()); + default: + IJavaElement cu = element.getAncestor(IJavaElement.COMPILATION_UNIT); + return cu != null && isExcluded(cu); + } + } /* * Returns whether the given resource path matches one of the exclusion * patterns. @@ -713,23 +725,23 @@ public class Util { * Returns true iff str.toLowerCase().endsWith(".jar" or ".zip") * implementation is not creating extra strings. */ - public final static boolean isArchiveFileName(String name) { - int nameLength = name == null ? 0 : name.length(); - int suffixLength = SUFFIX_JAR.length; - if (nameLength < suffixLength) return false; - - int i, offset; - for ( i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) { - char c = name.charAt(offset + i); - if (c != SUFFIX_jar[i] && c != SUFFIX_JAR[i]) break; - } - if (i == suffixLength) return true; - for ( i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) { - char c = name.charAt(offset + i); - if (c != SUFFIX_zip[i] && c != SUFFIX_ZIP[i]) return false; - } - return true; - } +// public final static boolean isArchiveFileName(String name) { +// int nameLength = name == null ? 0 : name.length(); +// int suffixLength = SUFFIX_JAR.length; +// if (nameLength < suffixLength) return false; +// +// int i, offset; +// for ( i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) { +// char c = name.charAt(offset + i); +// if (c != SUFFIX_jar[i] && c != SUFFIX_JAR[i]) break; +// } +// if (i == suffixLength) return true; +// for ( i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) { +// char c = name.charAt(offset + i); +// if (c != SUFFIX_zip[i] && c != SUFFIX_ZIP[i]) return false; +// } +// return true; +// } /** * Validate the given compilation unit name. @@ -745,9 +757,10 @@ public class Util { * the given name is valid as a compilation unit name, otherwise a status * object indicating what is wrong with the name */ -// public static boolean isValidCompilationUnitName(String name) { + public static boolean isValidCompilationUnitName(String name) { + return PHPFileUtil.isPHPFileName(name); // return JavaConventions.validateCompilationUnitName(name).getSeverity() != IStatus.ERROR; -// } + } /** * Validate the given .class file name. @@ -772,15 +785,16 @@ public class Util { * implementation is not creating extra strings. */ public final static boolean isJavaFileName(String name) { - int nameLength = name == null ? 0 : name.length(); - int suffixLength = SUFFIX_JAVA.length; - if (nameLength < suffixLength) return false; - - for (int i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) { - char c = name.charAt(offset + i); - if (c != SUFFIX_java[i] && c != SUFFIX_JAVA[i]) return false; - } - return true; + return PHPFileUtil.isPHPFileName(name); +// int nameLength = name == null ? 0 : name.length(); +// int suffixLength = SUFFIX_JAVA.length; +// if (nameLength < suffixLength) return false; +// +// for (int i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) { +// char c = name.charAt(offset + i); +// if (c != SUFFIX_java[i] && c != SUFFIX_JAVA[i]) return false; +// } +// return true; } /** @@ -818,9 +832,10 @@ public class Util { * Returns true if the given folder name is valid for a package, * false if it is not. */ -// public static boolean isValidFolderNameForPackage(String folderName) { + public static boolean isValidFolderNameForPackage(String folderName) { // return JavaConventions.validateIdentifier(folderName).getSeverity() != IStatus.ERROR; -// } + return true; + } /* * Add a log entry @@ -1006,20 +1021,20 @@ public class Util { * Converts the given relative path into a package name. * Returns null if the path is not a valid package name. */ -// public static String packageName(IPath pkgPath) { -// StringBuffer pkgName = new StringBuffer(IPackageFragment.DEFAULT_PACKAGE_NAME); -// for (int j = 0, max = pkgPath.segmentCount(); j < max; j++) { -// String segment = pkgPath.segment(j); -// if (!isValidFolderNameForPackage(segment)) { -// return null; -// } -// pkgName.append(segment); -// if (j < pkgPath.segmentCount() - 1) { -// pkgName.append("." ); //$NON-NLS-1$ -// } -// } -// return pkgName.toString(); -// } + public static String packageName(IPath pkgPath) { + StringBuffer pkgName = new StringBuffer(IPackageFragment.DEFAULT_PACKAGE_NAME); + for (int j = 0, max = pkgPath.segmentCount(); j < max; j++) { + String segment = pkgPath.segment(j); + if (!isValidFolderNameForPackage(segment)) { + return null; + } + pkgName.append(segment); + if (j < pkgPath.segmentCount() - 1) { + pkgName.append("." ); //$NON-NLS-1$ + } + } + return pkgName.toString(); + } /** * Sort the comparable objects in the given collection. diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/WorkingCopy.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/WorkingCopy.java new file mode 100644 index 0000000..416eb26 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/WorkingCopy.java @@ -0,0 +1,515 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.io.ByteArrayInputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; + +import net.sourceforge.phpdt.core.IBuffer; +import net.sourceforge.phpdt.core.IBufferFactory; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IMethod; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IProblemRequestor; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpeclipse.PHPCore; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + + + +/** + * Implementation of a working copy compilation unit. A working + * copy maintains the timestamp of the resource it was created + * from. + */ + +public class WorkingCopy extends CompilationUnit { + + /** + * If set, this is the factory that will be used to create the buffer. + */ + protected IBufferFactory bufferFactory; + + /** + * If set, this is the problem requestor which will be used to notify problems + * detected during reconciling. + */ + protected IProblemRequestor problemRequestor; + + /** + * A counter of the number of time clients have asked for this + * working copy. It is set to 1, if the working + * copy is not managed. When destroyed, this counter is + * set to 0. Once destroyed, this working copy cannot be opened + * and non-handle info can not be accessed. This is + * never true if this compilation unit is not a working + * copy. + */ + protected int useCount = 1; + +/** + */ +protected WorkingCopy(IPackageFragment parent, String name, IBufferFactory bufferFactory) { + this(parent, name, bufferFactory, null); +} +/** + */ +protected WorkingCopy(IPackageFragment parent, String name, IBufferFactory bufferFactory, IProblemRequestor problemRequestor) { + super(parent, name); + this.bufferFactory = + bufferFactory == null ? + this.getBufferManager().getDefaultBufferFactory() : + bufferFactory; + this.problemRequestor = problemRequestor; +} +/** + * @see IWorkingCopy + */ +public void commit(boolean force, IProgressMonitor monitor) throws JavaModelException { + ICompilationUnit original = (ICompilationUnit)this.getOriginalElement(); + if (original.exists()) { + CommitWorkingCopyOperation op= new CommitWorkingCopyOperation(this, force); + runOperation(op, monitor); + } else { + String encoding = this.getJavaProject().getOption(PHPCore.CORE_ENCODING, true); + String contents = this.getSource(); + if (contents == null) return; + try { + byte[] bytes = encoding == null + ? contents.getBytes() + : contents.getBytes(encoding); + ByteArrayInputStream stream = new ByteArrayInputStream(bytes); + IFile originalRes = (IFile)original.getResource(); + if (originalRes.exists()) { + originalRes.setContents( + stream, + force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY, + null); + } else { + originalRes.create( + stream, + force, + monitor); + } + } catch (CoreException e) { + throw new JavaModelException(e); + } catch (UnsupportedEncodingException e) { + throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); + } + } +} +/** + * Returns a new element info for this element. + */ +protected OpenableElementInfo createElementInfo() { + return new WorkingCopyElementInfo(); +} +/** + * @see IWorkingCopy + */ +public void destroy() { + if (--this.useCount > 0) { + if (SHARED_WC_VERBOSE) { + System.out.println("Decrementing use count of shared working copy " + this.toStringWithAncestors());//$NON-NLS-1$ + } + return; + } + try { + DestroyWorkingCopyOperation op = new DestroyWorkingCopyOperation(this); + runOperation(op, null); + } catch (JavaModelException e) { + // do nothing + } +} + +public boolean exists() { + // working copy always exists in the model until it is detroyed + return this.useCount != 0; +} + + +/** + * Answers custom buffer factory + */ +public IBufferFactory getBufferFactory(){ + + return this.bufferFactory; +} + +/** + * Working copies must be identical to be equal. + * + * @see Object#equals + */ +public boolean equals(Object o) { + return this == o; +} + + /** + * Returns the info for this handle. + * If this element is not already open, it and all of its parents are opened. + * Does not return null. + * NOTE: BinaryType infos are NJOT rooted under JavaElementInfo. + * @exception JavaModelException if the element is not present or not accessible + */ +// public Object getElementInfo() throws JavaModelException { +// +// JavaModelManager manager = JavaModelManager.getJavaModelManager(); +// boolean shouldPerformProblemDetection = false; +// synchronized(manager){ +// Object info = manager.getInfo(this); +// if (info == null) { +// shouldPerformProblemDetection = true; +// } +// } +// Object info = super.getElementInfo(); // will populate if necessary +// +// // perform problem detection outside the JavaModelManager lock +// if (this.problemRequestor != null && shouldPerformProblemDetection && this.problemRequestor.isActive()){ +// this.problemRequestor.beginReporting(); +// CompilationUnitProblemFinder.process(this, this.problemRequestor, null); +// this.problemRequestor.endReporting(); +// } +// return info; +// } +/** + * @see IWorkingCopy + */ +public IJavaElement getOriginal(IJavaElement workingCopyElement) { + //not a element contained in a compilation unit + int javaElementType = workingCopyElement.getElementType(); + if (javaElementType < COMPILATION_UNIT || javaElementType == CLASS_FILE) { + return null; + } +// if (workingCopyElement instanceof BinaryMember) { +// return null; +// } + IJavaElement parent = workingCopyElement.getParent(); + ArrayList hierarchy = new ArrayList(4); + + while (parent.getElementType() > COMPILATION_UNIT) { + hierarchy.add(parent); + parent = parent.getParent(); + } + if (parent.getElementType() == COMPILATION_UNIT) { + hierarchy.add(((ICompilationUnit)parent).getOriginalElement()); + } + + ICompilationUnit cu = (ICompilationUnit) getOriginalElement(); + if (javaElementType == COMPILATION_UNIT) { + parent = workingCopyElement; + } + if (((ICompilationUnit) parent).isWorkingCopy() && !((ICompilationUnit) parent).getOriginalElement().equals(cu)) { + return null; + } + IType type=null; + switch (javaElementType) { +// case PACKAGE_DECLARATION : +// return cu.getPackageDeclaration(workingCopyElement.getElementName()); +// case IMPORT_CONTAINER : +// return cu.getImportContainer(); +// case IMPORT_DECLARATION : +// return cu.getImport(workingCopyElement.getElementName()); +// case TYPE : +// if (hierarchy.size() == 1) { +// return cu.getType(workingCopyElement.getElementName()); +// } else { +// //inner type +// return getOriginalType(hierarchy).getType(workingCopyElement.getElementName()); +// } + case METHOD : + + if (hierarchy.size() == 2) { + String typeName = ((IJavaElement) hierarchy.get(0)).getElementName(); + type = cu.getType(typeName); +// } else { +// //inner type +// type = getOriginalType(hierarchy); + } + return type.getMethod(workingCopyElement.getElementName(), ((IMethod) workingCopyElement).getParameterTypes()); + case FIELD : + if (hierarchy.size() == 2) { + String typeName = ((IJavaElement) hierarchy.get(0)).getElementName(); + type = cu.getType(typeName); +// } else { +// //inner type +// type = getOriginalType(hierarchy); + } + return type.getField(workingCopyElement.getElementName()); +// case INITIALIZER : +// if (hierarchy.size() == 2) { +// String typeName = ((IJavaElement) hierarchy.get(0)).getElementName(); +// type = cu.getType(typeName); +// } else { +// //inner type +// type = getOriginalType(hierarchy); +// } +// return type.getInitializer(((Initializer) workingCopyElement).getOccurrenceCount()); + case COMPILATION_UNIT : + return cu; + default : + return null; + } +} +/** + * @see IWorkingCopy + */ +public IJavaElement getOriginalElement() { + return new CompilationUnit((IPackageFragment)getParent(), getElementName()); +} +//protected IType getOriginalType(ArrayList hierarchy) { +// int size = hierarchy.size() - 1; +// ICompilationUnit typeCU = (ICompilationUnit) hierarchy.get(size); +// String typeName = ((IJavaElement) hierarchy.get(size - 1)).getElementName(); +// IType type = typeCU.getType(typeName); +// size= size - 2; +// while (size > -1) { +// typeName = ((IJavaElement) hierarchy.get(size)).getElementName(); +// type = ((IType) type).getType(typeName); +// size--; +// } +// return type; +//} + +/* + * @see IJavaElement + */ +public IResource getResource() { + return null; +} + +/** + * @see IWorkingCopy + */ +public IJavaElement getSharedWorkingCopy(IProgressMonitor monitor, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException { + return this; +} +/** + * Returns null - a working copy does not have an underlying resource. + * + * @see IJavaElement + */ +public IResource getUnderlyingResource() throws JavaModelException { + return null; +} +/** + * @see IWorkingCopy + */ +public IJavaElement getWorkingCopy() throws JavaModelException { + return this; +} +/** + * @see IWorkingCopy + */ +public IJavaElement getWorkingCopy(IProgressMonitor monitor, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException { + return this; +} +/** + * @see IWorkingCopy + */ +public boolean isBasedOn(IResource resource) { + if (resource.getType() != IResource.FILE) { + return false; + } + if (this.useCount == 0) { + return false; + } + try { + // if resource got deleted, then #getModificationStamp() will answer IResource.NULL_STAMP, which is always different from the cached + // timestamp + return ((CompilationUnitElementInfo) getElementInfo()).fTimestamp == ((IFile) resource).getModificationStamp(); + } catch (JavaModelException e) { + return false; + } +} +/** + * @see IWorkingCopy + */ +public boolean isWorkingCopy() { + return true; +} + +/** + * @see IOpenable#makeConsistent(IProgressMonitor) + */ +//public void makeConsistent(IProgressMonitor monitor) throws JavaModelException { +// if (!isConsistent()) { // TODO: this code isn't synchronized with regular opening of a working copy (should use getElementInfo) +// super.makeConsistent(monitor); +// +// if (monitor != null && monitor.isCanceled()) return; +// if (this.problemRequestor != null && this.problemRequestor.isActive()){ +// this.problemRequestor.beginReporting(); +// CompilationUnitProblemFinder.process(this, this.problemRequestor, monitor); +// this.problemRequestor.endReporting(); +// } +// } +//} + +/** + * @see IOpenable + * @see IWorkingCopy + * + * @exception JavaModelException attempting to open a read only element for something other than navigation + * or if this is a working copy being opened after it has been destroyed. + */ +public void open(IProgressMonitor monitor) throws JavaModelException { + if (this.useCount == 0) { // was destroyed + throw newNotPresentException(); + } else { + super.open(monitor); + + if (monitor != null && monitor.isCanceled()) return; + if (this.problemRequestor != null && this.problemRequestor.isActive()){ + this.problemRequestor.beginReporting(); + CompilationUnitProblemFinder.process(this, this.problemRequestor, monitor); + this.problemRequestor.endReporting(); + } + } +} +/** + * @see Openable + */ +//protected IBuffer openBuffer(IProgressMonitor pm) throws JavaModelException { +// +// if (this.useCount == 0) throw newNotPresentException(); // was destroyed +// +// // create buffer - working copies may use custom buffer factory +// IBuffer buffer = getBufferFactory().createBuffer(this); +// if (buffer == null) return null; +// +// // set the buffer source if needed +// if (buffer.getCharacters() == null) { +// ICompilationUnit original = (ICompilationUnit)this.getOriginalElement(); +// if (original.isOpen()) { +// buffer.setContents(original.getSource()); +// } else { +// IFile file = (IFile)original.getResource(); +// if (file == null || !file.exists()) { +// // initialize buffer with empty contents +// buffer.setContents(CharOperation.NO_CHAR); +// } else { +// buffer.setContents(Util.getResourceContentsAsCharArray(file)); +// } +// } +// } +// +// // add buffer to buffer cache +// this.getBufferManager().addBuffer(buffer); +// +// // listen to buffer changes +// buffer.addBufferChangedListener(this); +// +// return buffer; +//} +/* + * @see Openable#openParent(IProgressMonitor) + */ +protected void openParent(IProgressMonitor pm) throws JavaModelException { +// if (FIX_BUG25184) { +// try { +// super.openParent(pm); +// } catch(JavaModelException e){ +// // allow parent to not exist for working copies defined outside classpath +// if (!e.isDoesNotExist()){ +// throw e; +// } +// } +// } else { + super.openParent(pm); +// } +} + +/** + * @see IWorkingCopy + */ +public IMarker[] reconcile() throws JavaModelException { + reconcile(false, null); + return null; +} + +/** + * @see IWorkingCopy + */ +public void reconcile(boolean forceProblemDetection, IProgressMonitor monitor) throws JavaModelException { + ReconcileWorkingCopyOperation op = new ReconcileWorkingCopyOperation(this, forceProblemDetection); + runOperation(op, monitor); +} + +/** + * @see IWorkingCopy + */ +public void restore() throws JavaModelException { + + if (this.useCount == 0) throw newNotPresentException(); //was destroyed + + CompilationUnit original = (CompilationUnit) getOriginalElement(); + IBuffer buffer = this.getBuffer(); + if (buffer == null) return; + buffer.setContents(original.getContents()); + updateTimeStamp(original); + makeConsistent(null); +} +/* + * @see JavaElement#rootedAt(IJavaProject) + */ +public IJavaElement rootedAt(IJavaProject project) { + return + new WorkingCopy( + (IPackageFragment)((JavaElement)fParent).rootedAt(project), + fName, + this.bufferFactory); + +} +/** + * @see IOpenable + */ +public void save(IProgressMonitor pm, boolean force) throws JavaModelException { + if (isReadOnly()) { + throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this)); + } + // no need to save the buffer for a working copy (this is a noop) + //IBuffer buf = getBuffer(); + //if (buf != null) { // some Openables (like a JavaProject) don't have a buffer + // buf.save(pm, force); + this.reconcile(); // not simply makeConsistent, also computes fine-grain deltas + // in case the working copy is being reconciled already (if not it would miss + // one iteration of deltas). + //} +} + +/** + * @private Debugging purposes + */ +protected void toStringInfo(int tab, StringBuffer buffer, Object info) { + buffer.append(this.tabString(tab)); + buffer.append("[Working copy] "); //$NON-NLS-1$ + super.toStringInfo(0, buffer, info); +} +protected void updateTimeStamp(CompilationUnit original) throws JavaModelException { + long timeStamp = + ((IFile) original.getResource()).getModificationStamp(); + if (timeStamp == IResource.NULL_STAMP) { + throw new JavaModelException( + new JavaModelStatus(IJavaModelStatusConstants.INVALID_RESOURCE)); + } + ((CompilationUnitElementInfo) getElementInfo()).fTimestamp = timeStamp; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/WorkingCopyElementInfo.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/WorkingCopyElementInfo.java new file mode 100644 index 0000000..9f91608 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/WorkingCopyElementInfo.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import net.sourceforge.phpdt.core.compiler.IProblem; + + +public class WorkingCopyElementInfo extends CompilationUnitElementInfo { + IProblem[] problems; +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/AbortIncrementalBuildException.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/AbortIncrementalBuildException.java new file mode 100644 index 0000000..5b6a28e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/AbortIncrementalBuildException.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +/** + * Exception thrown when an incremental builder cannot find a .class file. + * Its possible the type can no longer be found because it was renamed inside its existing + * source file. + */ +public class AbortIncrementalBuildException extends RuntimeException { + +protected String qualifiedTypeName; + +public AbortIncrementalBuildException(String qualifiedTypeName) { + this.qualifiedTypeName = qualifiedTypeName; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/AbstractImageBuilder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/AbstractImageBuilder.java new file mode 100644 index 0000000..6b40b16 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/AbstractImageBuilder.java @@ -0,0 +1,463 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import java.util.ArrayList; +import java.util.Locale; + +import net.sourceforge.phpdt.core.IJavaModelMarker; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.Compiler; +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.DefaultErrorHandlingPolicies; +import net.sourceforge.phpdt.internal.compiler.ICompilerRequestor; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; +import net.sourceforge.phpdt.internal.core.Util; +import net.sourceforge.phpeclipse.PHPCore; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +/** + * The abstract superclass of Java builders. + * Provides the building and compilation mechanism + * in common with the batch and incremental builders. + */ +public abstract class AbstractImageBuilder implements ICompilerRequestor { + +protected PHPBuilder javaBuilder; +protected State newState; + +// local copies +protected NameEnvironment nameEnvironment; +protected ClasspathMultiDirectory[] sourceLocations; +protected BuildNotifier notifier; + +protected String encoding; +protected Compiler compiler; +protected WorkQueue workQueue; +protected ArrayList problemSourceFiles; +protected boolean compiledAllAtOnce; + +private boolean inCompiler; + +public static int MAX_AT_ONCE = 1000; + +protected AbstractImageBuilder(PHPBuilder javaBuilder) { + this.javaBuilder = javaBuilder; + this.newState = new State(javaBuilder); + + // local copies + this.nameEnvironment = javaBuilder.nameEnvironment; + this.sourceLocations = this.nameEnvironment.sourceLocations; + this.notifier = javaBuilder.notifier; + + this.encoding = javaBuilder.javaProject.getOption(PHPCore.CORE_ENCODING, true); + this.compiler = newCompiler(); + this.workQueue = new WorkQueue(); + this.problemSourceFiles = new ArrayList(3); +} + +public void acceptResult(CompilationResult result) { + // In Batch mode, we write out the class files, hold onto the dependency info + // & additional types and report problems. + + // In Incremental mode, when writing out a class file we need to compare it + // against the previous file, remembering if structural changes occured. + // Before reporting the new problems, we need to update the problem count & + // remove the old problems. Plus delete additional class files that no longer exist. + + SourceFile compilationUnit = (SourceFile) result.getCompilationUnit(); // go directly back to the sourceFile + if (!workQueue.isCompiled(compilationUnit)) { + try { + workQueue.finished(compilationUnit); + updateProblemsFor(compilationUnit, result); // record compilation problems before potentially adding duplicate errors + updateTasksFor(compilationUnit, result); // record tasks + + String typeLocator = compilationUnit.typeLocator(); +// ClassFile[] classFiles = result.getClassFiles(); +// int length = classFiles.length; +// ArrayList duplicateTypeNames = null; +// ArrayList definedTypeNames = new ArrayList(length); +// for (int i = 0; i < length; i++) { +// ClassFile classFile = classFiles[i]; +// char[][] compoundName = classFile.getCompoundName(); +// char[] typeName = compoundName[compoundName.length - 1]; +// boolean isNestedType = CharOperation.contains('$', typeName); +// +// // Look for a possible collision, if one exists, report an error but do not write the class file +// if (isNestedType) { +// String qualifiedTypeName = new String(classFile.outerMostEnclosingClassFile().fileName()); +// if (newState.isDuplicateLocator(qualifiedTypeName, typeLocator)) +// continue; +// } else { +// String qualifiedTypeName = new String(classFile.fileName()); // the qualified type name "p1/p2/A" +// if (newState.isDuplicateLocator(qualifiedTypeName, typeLocator)) { +// if (duplicateTypeNames == null) +// duplicateTypeNames = new ArrayList(); +// duplicateTypeNames.add(compoundName); +// createErrorFor(compilationUnit.resource, Util.bind("build.duplicateClassFile", new String(typeName))); //$NON-NLS-1$ +// continue; +// } +// newState.recordLocatorForType(qualifiedTypeName, typeLocator); +// } +// definedTypeNames.add(writeClassFile(classFile, compilationUnit.sourceLocation.binaryFolder, !isNestedType)); +// } + +// finishedWith(typeLocator, result, compilationUnit.getMainTypeName(), definedTypeNames, duplicateTypeNames); + notifier.compiled(compilationUnit); + } catch (CoreException e) { + Util.log(e, "JavaBuilder handling CoreException"); //$NON-NLS-1$ + createErrorFor(compilationUnit.resource, Util.bind("build.inconsistentClassFile")); //$NON-NLS-1$ + } + } +} + +protected void cleanUp() { + this.nameEnvironment.cleanup(); + + this.javaBuilder = null; + this.nameEnvironment = null; + this.sourceLocations = null; + this.notifier = null; + this.compiler = null; + this.workQueue = null; + this.problemSourceFiles = null; +} + +/* Compile the given elements, adding more elements to the work queue +* if they are affected by the changes. +*/ +protected void compile(SourceFile[] units) { + int toDo = units.length; + if (this.compiledAllAtOnce = toDo <= MAX_AT_ONCE) { + // do them all now + if (PHPBuilder.DEBUG) + for (int i = 0; i < toDo; i++) + System.out.println("About to compile " + units[i].typeLocator()); //$NON-NLS-1$ + compile(units, null); + } else { + int i = 0; + boolean compilingFirstGroup = true; + while (i < toDo) { + int doNow = toDo < MAX_AT_ONCE ? toDo : MAX_AT_ONCE; + int index = 0; + SourceFile[] toCompile = new SourceFile[doNow]; + while (i < toDo && index < doNow) { + // Although it needed compiling when this method was called, it may have + // already been compiled when it was referenced by another unit. + SourceFile unit = units[i++]; + if (compilingFirstGroup || workQueue.isWaiting(unit)) { + if (PHPBuilder.DEBUG) + System.out.println("About to compile " + unit.typeLocator()); //$NON-NLS-1$ + toCompile[index++] = unit; + } + } + if (index < doNow) + System.arraycopy(toCompile, 0, toCompile = new SourceFile[index], 0, index); + SourceFile[] additionalUnits = new SourceFile[toDo - i]; + System.arraycopy(units, i, additionalUnits, 0, additionalUnits.length); + compilingFirstGroup = false; + compile(toCompile, additionalUnits); + } + } +} + +void compile(SourceFile[] units, SourceFile[] additionalUnits) { + if (units.length == 0) return; + notifier.aboutToCompile(units[0]); // just to change the message + + // extend additionalFilenames with all hierarchical problem types found during this entire build + if (!problemSourceFiles.isEmpty()) { + int toAdd = problemSourceFiles.size(); + int length = additionalUnits == null ? 0 : additionalUnits.length; + if (length == 0) + additionalUnits = new SourceFile[toAdd]; + else + System.arraycopy(additionalUnits, 0, additionalUnits = new SourceFile[length + toAdd], 0, length); + for (int i = 0; i < toAdd; i++) + additionalUnits[length + i] = (SourceFile) problemSourceFiles.get(i); + } + String[] initialTypeNames = new String[units.length]; + for (int i = 0, l = units.length; i < l; i++) + initialTypeNames[i] = units[i].initialTypeName; + nameEnvironment.setNames(initialTypeNames, additionalUnits); + notifier.checkCancel(); + try { + inCompiler = true; + compiler.compile(units); + } catch (AbortCompilation ignored) { + // ignore the AbortCompilcation coming from BuildNotifier.checkCancelWithinCompiler() + // the Compiler failed after the user has chose to cancel... likely due to an OutOfMemory error + } finally { + inCompiler = false; + } + // Check for cancel immediately after a compile, because the compiler may + // have been cancelled but without propagating the correct exception + notifier.checkCancel(); +} + +protected void createErrorFor(IResource resource, String message) { + try { + IMarker marker = resource.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); + int severity = IMarker.SEVERITY_ERROR; + if (message.equals(Util.bind("build.duplicateResource"))) //$NON-NLS-1$ + if (PHPCore.WARNING.equals(javaBuilder.javaProject.getOption(PHPCore.CORE_JAVA_BUILD_DUPLICATE_RESOURCE, true))) + severity = IMarker.SEVERITY_WARNING; + marker.setAttributes( + new String[] {IMarker.MESSAGE, IMarker.SEVERITY, IMarker.CHAR_START, IMarker.CHAR_END}, + new Object[] {message, new Integer(severity), new Integer(0), new Integer(1)}); + } catch (CoreException e) { + throw internalException(e); + } +} + +//protected void finishedWith(String sourceLocator, CompilationResult result, char[] mainTypeName) throws CoreException {//, ArrayList definedTypeNames, ArrayList duplicateTypeNames) throws CoreException { +// if (duplicateTypeNames == null) { +// newState.record(sourceLocator, result.qualifiedReferences, result.simpleNameReferences, mainTypeName, definedTypeNames); +// return; +// } +// +// char[][][] qualifiedRefs = result.qualifiedReferences; +// char[][] simpleRefs = result.simpleNameReferences; +// // for each duplicate type p1.p2.A, add the type name A (package was already added) +// next : for (int i = 0, l = duplicateTypeNames.size(); i < l; i++) { +// char[][] compoundName = (char[][]) duplicateTypeNames.get(i); +// char[] typeName = compoundName[compoundName.length - 1]; +// int sLength = simpleRefs.length; +// for (int j = 0; j < sLength; j++) +// if (CharOperation.equals(simpleRefs[j], typeName)) +// continue next; +// System.arraycopy(simpleRefs, 0, simpleRefs = new char[sLength + 1][], 0, sLength); +// simpleRefs[sLength] = typeName; +// } +// newState.record(sourceLocator, qualifiedRefs, simpleRefs, mainTypeName, definedTypeNames); +//} + +protected IContainer createFolder(IPath packagePath, IContainer outputFolder) throws CoreException { + if (packagePath.isEmpty()) return outputFolder; + IFolder folder = outputFolder.getFolder(packagePath); + if (!folder.exists()) { + createFolder(packagePath.removeLastSegments(1), outputFolder); + folder.create(true, true, null); + folder.setDerived(true); + } + return folder; +} + +protected RuntimeException internalException(CoreException t) { + ImageBuilderInternalException imageBuilderException = new ImageBuilderInternalException(t); + if (inCompiler) + return new AbortCompilation(true, imageBuilderException); + return imageBuilderException; +} + +protected Compiler newCompiler() { + // called once when the builder is initialized... can override if needed + return new Compiler( + nameEnvironment, + DefaultErrorHandlingPolicies.proceedWithAllProblems(), +// javaBuilder.javaProject.getOptions(true), + this, + ProblemFactory.getProblemFactory(Locale.getDefault())); +} + +protected boolean isExcludedFromProject(IPath childPath) throws JavaModelException { + // answer whether the folder should be ignored when walking the project as a source folder + if (childPath.segmentCount() > 2) return false; // is a subfolder of a package + + for (int j = 0, k = sourceLocations.length; j < k; j++) { + if (childPath.equals(sourceLocations[j].binaryFolder.getFullPath())) return true; + if (childPath.equals(sourceLocations[j].sourceFolder.getFullPath())) return true; + } + // skip default output folder which may not be used by any source folder + return childPath.equals(javaBuilder.javaProject.getOutputLocation()); +} + +/** + * Creates a marker from each problem and adds it to the resource. + * The marker is as follows: + * - its type is T_PROBLEM + * - its plugin ID is the JavaBuilder's plugin ID + * - its message is the problem's message + * - its priority reflects the severity of the problem + * - its range is the problem's range + * - it has an extra attribute "ID" which holds the problem's id + */ +protected void storeProblemsFor(SourceFile sourceFile, IProblem[] problems) throws CoreException { + if (sourceFile == null || problems == null || problems.length == 0) return; + +// String missingClassFile = null; + IResource resource = sourceFile.resource; + for (int i = 0, l = problems.length; i < l; i++) { + IProblem problem = problems[i]; + int id = problem.getID(); + switch (id) { + case IProblem.IsClassPathCorrect : +// PHPBuilder.removeProblemsAndTasksFor(javaBuilder.currentProject); // make this the only problem for this project +// String[] args = problem.getArguments(); +// missingClassFile = args[0]; + break; + case IProblem.SuperclassMustBeAClass : + case IProblem.SuperInterfaceMustBeAnInterface : + case IProblem.HierarchyCircularitySelfReference : + case IProblem.HierarchyCircularity : + case IProblem.HierarchyHasProblems : + case IProblem.SuperclassNotFound : + case IProblem.SuperclassNotVisible : + case IProblem.SuperclassAmbiguous : + case IProblem.SuperclassInternalNameProvided : + case IProblem.SuperclassInheritedNameHidesEnclosingName : + case IProblem.InterfaceNotFound : + case IProblem.InterfaceNotVisible : + case IProblem.InterfaceAmbiguous : + case IProblem.InterfaceInternalNameProvided : + case IProblem.InterfaceInheritedNameHidesEnclosingName : + // ensure that this file is always retrieved from source for the rest of the build + if (!problemSourceFiles.contains(sourceFile)) + problemSourceFiles.add(sourceFile); + break; + } + + if (id != IProblem.Task) { + IMarker marker = resource.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); + marker.setAttributes( + new String[] { + IMarker.MESSAGE, + IMarker.SEVERITY, + IJavaModelMarker.ID, + IMarker.CHAR_START, + IMarker.CHAR_END, + IMarker.LINE_NUMBER, + IJavaModelMarker.ARGUMENTS}, + new Object[] { + problem.getMessage(), + new Integer(problem.isError() ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING), + new Integer(id), + new Integer(problem.getSourceStart()), + new Integer(problem.getSourceEnd() + 1), + new Integer(problem.getSourceLineNumber()), + Util.getProblemArgumentsForMarker(problem.getArguments()) + }); + } + +/* Do NOT want to populate the Java Model just to find the matching Java element. + * Also cannot query compilation units located in folders with invalid package + * names such as 'a/b.c.d/e'. + + // compute a user-friendly location + IJavaElement element = JavaCore.create(resource); + if (element instanceof org.eclipse.jdt.core.ICompilationUnit) { // try to find a finer grain element + org.eclipse.jdt.core.ICompilationUnit unit = (org.eclipse.jdt.core.ICompilationUnit) element; + IJavaElement fragment = unit.getElementAt(problem.getSourceStart()); + if (fragment != null) element = fragment; + } + String location = null; + if (element instanceof JavaElement) + location = ((JavaElement) element).readableName(); + if (location != null) + marker.setAttribute(IMarker.LOCATION, location); +*/ + +// if (missingClassFile != null) +// throw new MissingClassFileException(missingClassFile); + } +} + +protected void storeTasksFor(SourceFile sourceFile, IProblem[] tasks) throws CoreException { + if (sourceFile == null || tasks == null || tasks.length == 0) return; + + IResource resource = sourceFile.resource; + for (int i = 0, l = tasks.length; i < l; i++) { + IProblem task = tasks[i]; + if (task.getID() == IProblem.Task) { + IMarker marker = resource.createMarker(IJavaModelMarker.TASK_MARKER); + int priority = IMarker.PRIORITY_NORMAL; + String compilerPriority = task.getArguments()[2]; + if (PHPCore.COMPILER_TASK_PRIORITY_HIGH.equals(compilerPriority)) + priority = IMarker.PRIORITY_HIGH; + else if (PHPCore.COMPILER_TASK_PRIORITY_LOW.equals(compilerPriority)) + priority = IMarker.PRIORITY_LOW; + marker.setAttributes( + new String[] { + IMarker.MESSAGE, + IMarker.PRIORITY, + IMarker.DONE, + IMarker.CHAR_START, + IMarker.CHAR_END, + IMarker.LINE_NUMBER, + IMarker.USER_EDITABLE, + }, + new Object[] { + task.getMessage(), + new Integer(priority), + new Boolean(false), + new Integer(task.getSourceStart()), + new Integer(task.getSourceEnd() + 1), + new Integer(task.getSourceLineNumber()), + new Boolean(false), + }); + } + } +} + +protected void updateProblemsFor(SourceFile sourceFile, CompilationResult result) throws CoreException { + IProblem[] problems = result.getProblems(); + if (problems == null || problems.length == 0) return; + + notifier.updateProblemCounts(problems); + storeProblemsFor(sourceFile, problems); +} + +protected void updateTasksFor(SourceFile sourceFile, CompilationResult result) throws CoreException { + IProblem[] tasks = result.getTasks(); + if (tasks == null || tasks.length == 0) return; + + storeTasksFor(sourceFile, tasks); +} + +//protected char[] writeClassFile(ClassFile classFile, IContainer outputFolder, boolean isSecondaryType) throws CoreException { +// String fileName = new String(classFile.fileName()); // the qualified type name "p1/p2/A" +// IPath filePath = new Path(fileName); +// IContainer container = outputFolder; +// if (filePath.segmentCount() > 1) { +// container = createFolder(filePath.removeLastSegments(1), outputFolder); +// filePath = new Path(filePath.lastSegment()); +// } +// +// IFile file = container.getFile(filePath.addFileExtension(JavaBuilder.CLASS_EXTENSION)); +// writeClassFileBytes(classFile.getBytes(), file, fileName, isSecondaryType); +// // answer the name of the class file as in Y or Y$M +// return filePath.lastSegment().toCharArray(); +//} +// +//protected void writeClassFileBytes(byte[] bytes, IFile file, String qualifiedFileName, boolean isSecondaryType) throws CoreException { +// if (file.exists()) { +// // Deal with shared output folders... last one wins... no collision cases detected +// if (JavaBuilder.DEBUG) +// System.out.println("Writing changed class file " + file.getName());//$NON-NLS-1$ +// file.setContents(new ByteArrayInputStream(bytes), true, false, null); +// if (!file.isDerived()) +// file.setDerived(true); +// } else { +// // Default implementation just writes out the bytes for the new class file... +// if (JavaBuilder.DEBUG) +// System.out.println("Writing new class file " + file.getName());//$NON-NLS-1$ +// file.create(new ByteArrayInputStream(bytes), IResource.FORCE, null); +// file.setDerived(true); +// } +//} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/AdditionalTypeCollection.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/AdditionalTypeCollection.java new file mode 100644 index 0000000..1979871 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/AdditionalTypeCollection.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +public class AdditionalTypeCollection extends ReferenceCollection { + +char[][] definedTypeNames; + +protected AdditionalTypeCollection(char[][] definedTypeNames, char[][][] qualifiedReferences, char[][] simpleNameReferences) { + super(qualifiedReferences, simpleNameReferences); + this.definedTypeNames = definedTypeNames; // do not bother interning member type names (ie. 'A$M') +} +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/BatchImageBuilder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/BatchImageBuilder.java new file mode 100644 index 0000000..579de3c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/BatchImageBuilder.java @@ -0,0 +1,248 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import java.util.ArrayList; + +import net.sourceforge.phpdt.internal.core.JavaModelManager; +import net.sourceforge.phpdt.internal.core.Util; +import net.sourceforge.phpeclipse.PHPCore; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceProxy; +import org.eclipse.core.resources.IResourceProxyVisitor; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +public class BatchImageBuilder extends AbstractImageBuilder { + +protected BatchImageBuilder(PHPBuilder javaBuilder) { + super(javaBuilder); + this.nameEnvironment.isIncrementalBuild = false; +} + +public void build() { + if (PHPBuilder.DEBUG) + System.out.println("FULL build"); //$NON-NLS-1$ + + try { +// notifier.subTask(Util.bind("build.cleaningOutput")); //$NON-NLS-1$ +// JavaModelManager.getJavaModelManager().deltaProcessor.addForRefresh(javaBuilder.javaProject); +// PHPBuilder.removeProblemsAndTasksFor(javaBuilder.currentProject); +// cleanOutputFolders(); + notifier.updateProgressDelta(0.1f); + + notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$ + ArrayList sourceFiles = new ArrayList(33); + addAllSourceFiles(sourceFiles); + notifier.updateProgressDelta(0.15f); + + if (sourceFiles.size() > 0) { + SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()]; + sourceFiles.toArray(allSourceFiles); + + notifier.setProgressPerCompilationUnit(0.75f / allSourceFiles.length); + workQueue.addAll(allSourceFiles); + compile(allSourceFiles); + } + + if (javaBuilder.javaProject.hasCycleMarker()) + javaBuilder.mustPropagateStructuralChanges(); + } catch (CoreException e) { + throw internalException(e); + } finally { + cleanUp(); + } +} + +protected void addAllSourceFiles(final ArrayList sourceFiles) throws CoreException { + for (int i = 0, l = sourceLocations.length; i < l; i++) { + final ClasspathMultiDirectory sourceLocation = sourceLocations[i]; + final char[][] exclusionPatterns = sourceLocation.exclusionPatterns; + final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject); + sourceLocation.sourceFolder.accept( + new IResourceProxyVisitor() { + public boolean visit(IResourceProxy proxy) throws CoreException { + IResource resource = null; + if (exclusionPatterns != null) { + resource = proxy.requestResource(); + if (Util.isExcluded(resource, exclusionPatterns)) return false; + } + switch(proxy.getType()) { + case IResource.FILE : + if (Util.isJavaFileName(proxy.getName())) { + if (resource == null) + resource = proxy.requestResource(); + sourceFiles.add(new SourceFile((IFile) resource, sourceLocation, encoding)); + } + return false; + case IResource.FOLDER : + if (isAlsoProject && isExcludedFromProject(proxy.requestFullPath())) return false; + } + return true; + } + }, + IResource.NONE + ); + notifier.checkCancel(); + } +} + +protected void cleanOutputFolders() throws CoreException { + boolean deleteAll = PHPCore.CLEAN.equals( + javaBuilder.javaProject.getOption(PHPCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, true)); + if (deleteAll) { + ArrayList visited = new ArrayList(sourceLocations.length); + for (int i = 0, l = sourceLocations.length; i < l; i++) { + notifier.subTask(Util.bind("build.cleaningOutput")); //$NON-NLS-1$ + ClasspathMultiDirectory sourceLocation = sourceLocations[i]; + if (sourceLocation.hasIndependentOutputFolder) { + IContainer outputFolder = sourceLocation.binaryFolder; + if (!visited.contains(outputFolder)) { + visited.add(outputFolder); + IResource[] members = outputFolder.members(); + for (int j = 0, m = members.length; j < m; j++) + members[j].delete(IResource.FORCE, null); + } + notifier.checkCancel(); + copyExtraResourcesBack(sourceLocation, deleteAll); + } else { + boolean isOutputFolder = sourceLocation.sourceFolder.equals(sourceLocation.binaryFolder); + final char[][] exclusionPatterns = + isOutputFolder + ? sourceLocation.exclusionPatterns + : null; // ignore exclusionPatterns if output folder == another source folder... not this one + sourceLocation.binaryFolder.accept( + new IResourceProxyVisitor() { + public boolean visit(IResourceProxy proxy) throws CoreException { + IResource resource = null; + if (exclusionPatterns != null) { + resource = proxy.requestResource(); + if (Util.isExcluded(resource, exclusionPatterns)) return false; + } + if (proxy.getType() == IResource.FILE) { +// if (Util.isClassFileName(proxy.getName())) { +// if (resource == null) +// resource = proxy.requestResource(); +// resource.delete(IResource.FORCE, null); +// } + return false; + } + notifier.checkCancel(); + return true; + } + }, + IResource.NONE + ); + if (!isOutputFolder) { + notifier.checkCancel(); + copyPackages(sourceLocation); + } + } + notifier.checkCancel(); + } + } else { + for (int i = 0, l = sourceLocations.length; i < l; i++) { + ClasspathMultiDirectory sourceLocation = sourceLocations[i]; + if (sourceLocation.hasIndependentOutputFolder) + copyExtraResourcesBack(sourceLocation, deleteAll); + else if (!sourceLocation.sourceFolder.equals(sourceLocation.binaryFolder)) + copyPackages(sourceLocation); // output folder is different from source folder + notifier.checkCancel(); + } + } +} + +protected void copyExtraResourcesBack(ClasspathMultiDirectory sourceLocation, final boolean deletedAll) throws CoreException { + // When, if ever, does a builder need to copy resources files (not .java or .class) into the output folder? + // If we wipe the output folder at the beginning of the build then all 'extra' resources must be copied to the output folder. + + notifier.subTask(Util.bind("build.copyingResources")); //$NON-NLS-1$ + final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount(); + final char[][] exclusionPatterns = sourceLocation.exclusionPatterns; + final IContainer outputFolder = sourceLocation.binaryFolder; + final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject); + sourceLocation.sourceFolder.accept( + new IResourceProxyVisitor() { + public boolean visit(IResourceProxy proxy) throws CoreException { + IResource resource = null; + switch(proxy.getType()) { + case IResource.FILE : + if (Util.isJavaFileName(proxy.getName())) return false;// || Util.isClassFileName(proxy.getName())) return false; + + resource = proxy.requestResource(); + if (javaBuilder.filterExtraResource(resource)) return false; + if (exclusionPatterns != null && Util.isExcluded(resource, exclusionPatterns)) + return false; + + IPath partialPath = resource.getFullPath().removeFirstSegments(segmentCount); + IResource copiedResource = outputFolder.getFile(partialPath); + if (copiedResource.exists()) { + if (deletedAll) { + createErrorFor(resource, Util.bind("build.duplicateResource")); //$NON-NLS-1$ + return false; + } + copiedResource.delete(IResource.FORCE, null); // last one wins + } + resource.copy(copiedResource.getFullPath(), IResource.FORCE, null); + copiedResource.setDerived(true); + return false; + case IResource.FOLDER : + resource = proxy.requestResource(); + if (javaBuilder.filterExtraResource(resource)) return false; + if (exclusionPatterns != null && Util.isExcluded(resource, exclusionPatterns)) + return false; + + IPath folderPath = resource.getFullPath(); + if (isAlsoProject && isExcludedFromProject(folderPath)) return false; // the sourceFolder == project + createFolder(folderPath.removeFirstSegments(segmentCount), outputFolder); + } + return true; + } + }, + IResource.NONE + ); +} + +protected void copyPackages(ClasspathMultiDirectory sourceLocation) throws CoreException { + final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount(); + final char[][] exclusionPatterns = sourceLocation.exclusionPatterns; + final IContainer outputFolder = sourceLocation.binaryFolder; + final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject); + sourceLocation.sourceFolder.accept( + new IResourceProxyVisitor() { + public boolean visit(IResourceProxy proxy) throws CoreException { + switch(proxy.getType()) { + case IResource.FILE : + return false; + case IResource.FOLDER : + IResource resource = proxy.requestResource(); + if (javaBuilder.filterExtraResource(resource)) return false; + if (exclusionPatterns != null && Util.isExcluded(resource, exclusionPatterns)) + return false; + + IPath folderPath = resource.getFullPath(); + if (isAlsoProject && isExcludedFromProject(folderPath)) return false; // the sourceFolder == project + createFolder(folderPath.removeFirstSegments(segmentCount), outputFolder); + } + return true; + } + }, + IResource.NONE + ); +} + +public String toString() { + return "batch image builder for:\n\tnew state: " + newState; //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/BuildNotifier.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/BuildNotifier.java new file mode 100644 index 0000000..032cf26 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/BuildNotifier.java @@ -0,0 +1,278 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; +import net.sourceforge.phpdt.internal.compiler.util.Util; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; + +public class BuildNotifier { + +protected IProgressMonitor monitor; +protected boolean cancelling; +protected float percentComplete; +protected float progressPerCompilationUnit; +protected int newErrorCount; +protected int fixedErrorCount; +protected int newWarningCount; +protected int fixedWarningCount; +protected int workDone; +protected int totalWork; +protected String previousSubtask; + +public static int NewErrorCount = 0; +public static int FixedErrorCount = 0; +public static int NewWarningCount = 0; +public static int FixedWarningCount = 0; + +public static void resetProblemCounters() { + NewErrorCount = 0; + FixedErrorCount = 0; + NewWarningCount = 0; + FixedWarningCount = 0; +} + +public BuildNotifier(IProgressMonitor monitor, IProject project) { + this.monitor = monitor; + this.cancelling = false; + this.newErrorCount = NewErrorCount; + this.fixedErrorCount = FixedErrorCount; + this.newWarningCount = NewWarningCount; + this.fixedWarningCount = FixedWarningCount; + this.workDone = 0; + this.totalWork = 1000000; +} + +/** + * Notification before a compile that a unit is about to be compiled. + */ +public void aboutToCompile(SourceFile unit) { + String message = Util.bind("build.compiling", unit.resource.getFullPath().removeLastSegments(1).makeRelative().toString()); //$NON-NLS-1$ + subTask(message); +} + +public void begin() { + if (monitor != null) + monitor.beginTask("", totalWork); //$NON-NLS-1$ + this.previousSubtask = null; +} + +/** + * Check whether the build has been canceled. + */ +public void checkCancel() { + if (monitor != null && monitor.isCanceled()) + throw new OperationCanceledException(); +} + +/** + * Check whether the build has been canceled. + * Must use this call instead of checkCancel() when within the compiler. + */ +public void checkCancelWithinCompiler() { + if (monitor != null && monitor.isCanceled() && !cancelling) { + // Once the compiler has been canceled, don't check again. + setCancelling(true); + // Only AbortCompilation can stop the compiler cleanly. + // We check cancelation again following the call to compile. + throw new AbortCompilation(true, null); + } +} + +/** + * Notification while within a compile that a unit has finished being compiled. + */ +public void compiled(SourceFile unit) { + String message = Util.bind("build.compiling", unit.resource.getFullPath().removeLastSegments(1).makeRelative().toString()); //$NON-NLS-1$ + subTask(message); + updateProgressDelta(progressPerCompilationUnit); + checkCancelWithinCompiler(); +} + +public void done() { + NewErrorCount = this.newErrorCount; + FixedErrorCount = this.fixedErrorCount; + NewWarningCount = this.newWarningCount; + FixedWarningCount = this.fixedWarningCount; + + updateProgress(1.0f); + subTask(Util.bind("build.done")); //$NON-NLS-1$ + if (monitor != null) + monitor.done(); + this.previousSubtask = null; +} + +/** + * Returns a string describing the problems. + */ +protected String problemsMessage() { + int numNew = newErrorCount + newWarningCount; + int numFixed = fixedErrorCount + fixedWarningCount; + if (numNew == 0 && numFixed == 0) return ""; //$NON-NLS-1$ + + boolean displayBoth = numNew > 0 && numFixed > 0; + StringBuffer buffer = new StringBuffer(); + buffer.append('('); + if (numNew > 0) { + // (Found x errors + y warnings) + buffer.append(Util.bind("build.foundHeader")); //$NON-NLS-1$ + buffer.append(' '); + if (displayBoth || newErrorCount > 0) { + if (newErrorCount == 1) + buffer.append(Util.bind("build.oneError")); //$NON-NLS-1$ + else + buffer.append(Util.bind("build.multipleErrors", String.valueOf(newErrorCount))); //$NON-NLS-1$ + if (displayBoth || newWarningCount > 0) + buffer.append(" + "); //$NON-NLS-1$ + } + if (displayBoth || newWarningCount > 0) { + if (newWarningCount == 1) + buffer.append(Util.bind("build.oneWarning")); //$NON-NLS-1$ + else + buffer.append(Util.bind("build.multipleWarnings", String.valueOf(newWarningCount))); //$NON-NLS-1$ + } + if (numFixed > 0) + buffer.append(", "); //$NON-NLS-1$ + } + if (numFixed > 0) { + // (Fixed x errors + y warnings) or (Found x errors + y warnings, Fixed x + y) + buffer.append(Util.bind("build.fixedHeader")); //$NON-NLS-1$ + buffer.append(' '); + if (displayBoth) { + buffer.append(String.valueOf(fixedErrorCount)); + buffer.append(" + "); //$NON-NLS-1$ + buffer.append(String.valueOf(fixedWarningCount)); + } else { + if (fixedErrorCount > 0) { + if (fixedErrorCount == 1) + buffer.append(Util.bind("build.oneError")); //$NON-NLS-1$ + else + buffer.append(Util.bind("build.multipleErrors", String.valueOf(fixedErrorCount))); //$NON-NLS-1$ + if (fixedWarningCount > 0) + buffer.append(" + "); //$NON-NLS-1$ + } + if (fixedWarningCount > 0) { + if (fixedWarningCount == 1) + buffer.append(Util.bind("build.oneWarning")); //$NON-NLS-1$ + else + buffer.append(Util.bind("build.multipleWarnings", String.valueOf(fixedWarningCount))); //$NON-NLS-1$ + } + } + } + buffer.append(')'); + return buffer.toString(); +} + +/** + * Sets the cancelling flag, which indicates we are in the middle + * of being cancelled. Certain places (those callable indirectly from the compiler) + * should not check cancel again while this is true, to avoid OperationCanceledException + * being thrown at an inopportune time. + */ +public void setCancelling(boolean cancelling) { + this.cancelling = cancelling; +} + +/** + * Sets the amount of progress to report for compiling each compilation unit. + */ +public void setProgressPerCompilationUnit(float progress) { + this.progressPerCompilationUnit = progress; +} + +public void subTask(String message) { + String pm = problemsMessage(); + String msg = pm.length() == 0 ? message : pm + " " + message; //$NON-NLS-1$ + + if (msg.equals(this.previousSubtask)) return; // avoid refreshing with same one + //if (JavaBuilder.DEBUG) System.out.println(msg); + if (monitor != null) + monitor.subTask(msg); + + this.previousSubtask = msg; +} + +protected void updateProblemCounts(IProblem[] newProblems) { + for (int i = 0, l = newProblems.length; i < l; i++) + if (newProblems[i].isError()) newErrorCount++; else newWarningCount++; +} + +/** + * Update the problem counts from one compilation result given the old and new problems, + * either of which may be null. + */ +protected void updateProblemCounts(IMarker[] oldProblems, IProblem[] newProblems) { + if (newProblems != null) { + next : for (int i = 0, l = newProblems.length; i < l; i++) { + IProblem newProblem = newProblems[i]; + if (newProblem.getID() == IProblem.Task) continue; // skip task + boolean isError = newProblem.isError(); + String message = newProblem.getMessage(); + + if (oldProblems != null) { + for (int j = 0, m = oldProblems.length; j < m; j++) { + IMarker pb = oldProblems[j]; + if (pb == null) continue; // already matched up with a new problem + boolean wasError = IMarker.SEVERITY_ERROR + == pb.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); + if (isError == wasError && message.equals(pb.getAttribute(IMarker.MESSAGE, ""))) { //$NON-NLS-1$ + oldProblems[j] = null; + continue next; + } + } + } + if (isError) newErrorCount++; else newWarningCount++; + } + } + if (oldProblems != null) { + next : for (int i = 0, l = oldProblems.length; i < l; i++) { + IMarker oldProblem = oldProblems[i]; + if (oldProblem == null) continue next; // already matched up with a new problem + boolean wasError = IMarker.SEVERITY_ERROR + == oldProblem.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); + String message = oldProblem.getAttribute(IMarker.MESSAGE, ""); //$NON-NLS-1$ + + if (newProblems != null) { + for (int j = 0, m = newProblems.length; j < m; j++) { + IProblem pb = newProblems[j]; + if (pb.getID() == IProblem.Task) continue; // skip task + if (wasError == pb.isError() && message.equals(pb.getMessage())) + continue next; + } + } + if (wasError) fixedErrorCount++; else fixedWarningCount++; + } + } +} + +public void updateProgress(float percentComplete) { + if (percentComplete > this.percentComplete) { + this.percentComplete = Math.min(percentComplete, 1.0f); + int work = Math.round(this.percentComplete * this.totalWork); + if (work > this.workDone) { + if (monitor != null) + monitor.worked(work - this.workDone); + //if (JavaBuilder.DEBUG) + //System.out.println(java.text.NumberFormat.getPercentInstance().format(this.percentComplete)); + this.workDone = work; + } + } +} + +public void updateProgressDelta(float percentWorked) { + updateProgress(percentComplete + percentWorked); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ClasspathDirectory.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ClasspathDirectory.java new file mode 100644 index 0000000..86f7d35 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ClasspathDirectory.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer; +import net.sourceforge.phpdt.internal.core.Util; +import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +class ClasspathDirectory extends ClasspathLocation { + +IContainer binaryFolder; // includes .class files for a single directory +boolean isOutputFolder; +String binaryLocation; +SimpleLookupTable directoryCache; +String[] missingPackageHolder = new String[1]; + +ClasspathDirectory(IContainer binaryFolder, boolean isOutputFolder) { + this.binaryFolder = binaryFolder; + this.isOutputFolder = isOutputFolder; + IPath location = binaryFolder.getLocation(); + this.binaryLocation = location != null ? location.addTrailingSeparator().toString() : ""; //$NON-NLS-1$ + + this.directoryCache = new SimpleLookupTable(5); +} + +public void cleanup() { + this.directoryCache = null; +} + +String[] directoryList(String qualifiedPackageName) { + String[] dirList = (String[]) directoryCache.get(qualifiedPackageName); + if (dirList == missingPackageHolder) return null; // package exists in another classpath directory or jar + if (dirList != null) return dirList; + + try { + IResource container = binaryFolder.findMember(qualifiedPackageName); // this is a case-sensitive check + if (container instanceof IContainer) { + IResource[] members = ((IContainer) container).members(); + dirList = new String[members.length]; + int index = 0; + for (int i = 0, l = members.length; i < l; i++) { + IResource m = members[i]; +// if (m.getType() == IResource.FILE && Util.isClassFileName(m.getName())) +// // add exclusion pattern check here if we want to hide .class files +// dirList[index++] = m.getName(); + } + if (index < dirList.length) + System.arraycopy(dirList, 0, dirList = new String[index], 0, index); + directoryCache.put(qualifiedPackageName, dirList); + return dirList; + } + } catch(CoreException ignored) { + } + directoryCache.put(qualifiedPackageName, missingPackageHolder); + return null; +} + +boolean doesFileExist(String fileName, String qualifiedPackageName, String qualifiedFullName) { + 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 boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ClasspathDirectory)) return false; + + return binaryFolder.equals(((ClasspathDirectory) o).binaryFolder); +} + +public NameEnvironmentAnswer findClass(String binaryFileName, String qualifiedPackageName, String qualifiedBinaryFileName) { + if (!doesFileExist(binaryFileName, qualifiedPackageName, qualifiedBinaryFileName)) return null; // most common case + +// try { +// ClassFileReader reader = ClassFileReader.read(binaryLocation + qualifiedBinaryFileName); +// if (reader != null) return new NameEnvironmentAnswer(reader); +// } catch (Exception e) {} // treat as if class file is missing + return null; +} + +public IPath getProjectRelativePath() { + return binaryFolder.getProjectRelativePath(); +} + +public boolean isOutputFolder() { + return isOutputFolder; +} + +public boolean isPackage(String qualifiedPackageName) { + return directoryList(qualifiedPackageName) != null; +} + +public void reset() { + this.directoryCache = new SimpleLookupTable(5); +} + +public String toString() { + return "Binary classpath directory " + binaryFolder.getFullPath().toString(); //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ClasspathLocation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ClasspathLocation.java new file mode 100644 index 0000000..c9bbdad --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ClasspathLocation.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.IPath; + +public abstract class ClasspathLocation { + +static ClasspathLocation forSourceFolder(IContainer sourceFolder, IContainer outputFolder, char[][] exclusionPatterns) { + return new ClasspathMultiDirectory(sourceFolder, outputFolder, exclusionPatterns); +} + +public static ClasspathLocation forBinaryFolder(IContainer binaryFolder, boolean isOutputFolder) { + return new ClasspathDirectory(binaryFolder, isOutputFolder); +} + +//static ClasspathLocation forLibrary(String libraryPathname) { +// return new ClasspathJar(libraryPathname); +//} + +//static ClasspathLocation forLibrary(IFile library) { +// return new ClasspathJar(library); +//} + +public abstract NameEnvironmentAnswer findClass(String binaryFileName, String qualifiedPackageName, String qualifiedBinaryFileName); + +public abstract IPath getProjectRelativePath(); + +public boolean isOutputFolder() { + return false; +} + +public abstract boolean isPackage(String qualifiedPackageName); + +// free anything which is not required when the state is saved +public void cleanup() { +} +// reset any internal caches before another compile loop starts +public void reset() { +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ClasspathMultiDirectory.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ClasspathMultiDirectory.java new file mode 100644 index 0000000..077fa45 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ClasspathMultiDirectory.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import net.sourceforge.phpdt.core.compiler.CharOperation; + +import org.eclipse.core.resources.IContainer; + +class ClasspathMultiDirectory extends ClasspathDirectory { + +IContainer sourceFolder; +char[][] exclusionPatterns; // used by builders when walking source folders +boolean hasIndependentOutputFolder; // if output folder is not equal to any of the source folders + +ClasspathMultiDirectory(IContainer sourceFolder, IContainer binaryFolder, char[][] exclusionPatterns) { + super(binaryFolder, true); + + this.sourceFolder = sourceFolder; + this.exclusionPatterns = exclusionPatterns; + this.hasIndependentOutputFolder = false; + + // handle the case when a state rebuilds a source folder + if (this.exclusionPatterns != null && this.exclusionPatterns.length == 0) + this.exclusionPatterns = null; +} + +public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ClasspathMultiDirectory)) return false; + + ClasspathMultiDirectory md = (ClasspathMultiDirectory) o; + return sourceFolder.equals(md.sourceFolder) && binaryFolder.equals(md.binaryFolder) + && CharOperation.equals(exclusionPatterns, md.exclusionPatterns); +} + +public String toString() { + return "Source classpath directory " + sourceFolder.getFullPath().toString() + //$NON-NLS-1$ + " with binary directory " + binaryFolder.getFullPath().toString(); //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ImageBuilderInternalException.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ImageBuilderInternalException.java new file mode 100644 index 0000000..8de3250 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ImageBuilderInternalException.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import org.eclipse.core.runtime.CoreException; + +/** + * Exception thrown when there is an internal error in the image builder. + * May wrapper another exception. + */ +public class ImageBuilderInternalException extends RuntimeException { + +protected CoreException coreException; + +public ImageBuilderInternalException(CoreException e) { + this.coreException = e; +} + +public CoreException getThrowable() { + return coreException; +} + +public void printStackTrace() { + if (coreException != null) { + System.err.println(this); + System.err.println("Stack trace of embedded core exception:"); //$NON-NLS-1$ + coreException.printStackTrace(); + } else { + super.printStackTrace(); + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/IncrementalImageBuilder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/IncrementalImageBuilder.java new file mode 100644 index 0000000..694bcd9 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/IncrementalImageBuilder.java @@ -0,0 +1,649 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import java.util.ArrayList; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.core.Util; +import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +/** + * The incremental image builder + */ +public class IncrementalImageBuilder extends AbstractImageBuilder { + +protected ArrayList sourceFiles; +protected ArrayList previousSourceFiles; +protected ArrayList qualifiedStrings; +protected ArrayList simpleStrings; +protected SimpleLookupTable secondaryTypesToRemove; +protected boolean hasStructuralChanges; +protected int compileLoop; + +public static int MaxCompileLoop = 5; // perform a full build if it takes more than ? incremental compile loops + +protected IncrementalImageBuilder(PHPBuilder javaBuilder) { + super(javaBuilder); + this.nameEnvironment.isIncrementalBuild = true; + this.newState.copyFrom(javaBuilder.lastState); + + this.sourceFiles = new ArrayList(33); + this.previousSourceFiles = null; + this.qualifiedStrings = new ArrayList(33); + this.simpleStrings = new ArrayList(33); + this.hasStructuralChanges = false; + this.compileLoop = 0; +} + +public boolean build(SimpleLookupTable deltas) { + // initialize builder + // walk this project's deltas, find changed source files + // walk prereq projects' deltas, find changed class files & add affected source files + // use the build state # to skip the deltas for certain prereq projects + // ignore changed zip/jar files since they caused a full build + // compile the source files & acceptResult() + // compare the produced class files against the existing ones on disk + // recompile all dependent source files of any type with structural changes or new/removed secondary type + // keep a loop counter to abort & perform a full build + + if (PHPBuilder.DEBUG) + System.out.println("INCREMENTAL build"); //$NON-NLS-1$ + + try { + resetCollections(); + + notifier.subTask(Util.bind("build.analyzingDeltas")); //$NON-NLS-1$ + IResourceDelta sourceDelta = (IResourceDelta) deltas.get(javaBuilder.currentProject); + if (sourceDelta != null) + if (!findSourceFiles(sourceDelta)) return false; + notifier.updateProgressDelta(0.10f); + + Object[] keyTable = deltas.keyTable; + Object[] valueTable = deltas.valueTable; + for (int i = 0, l = valueTable.length; i < l; i++) { + IResourceDelta delta = (IResourceDelta) valueTable[i]; + if (delta != null) { +// ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) javaBuilder.binaryLocationsPerProject.get(keyTable[i]); +// if (classFoldersAndJars != null) +// if (!findAffectedSourceFiles(delta, classFoldersAndJars)) return false; + } + } + notifier.updateProgressDelta(0.10f); + + notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$ + addAffectedSourceFiles(); + notifier.updateProgressDelta(0.05f); + + this.compileLoop = 0; + float increment = 0.40f; + while (sourceFiles.size() > 0) { // added to in acceptResult + if (++this.compileLoop > MaxCompileLoop) { + if (PHPBuilder.DEBUG) + System.out.println("ABORTING incremental build... exceeded loop count"); //$NON-NLS-1$ + return false; + } + notifier.checkCancel(); + + SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()]; + sourceFiles.toArray(allSourceFiles); + resetCollections(); + + workQueue.addAll(allSourceFiles); + notifier.setProgressPerCompilationUnit(increment / allSourceFiles.length); + increment = increment / 2; + compile(allSourceFiles); + removeSecondaryTypes(); + addAffectedSourceFiles(); + } + if (this.hasStructuralChanges && javaBuilder.javaProject.hasCycleMarker()) + javaBuilder.mustPropagateStructuralChanges(); + } catch (AbortIncrementalBuildException e) { + // abort the incremental build and let the batch builder handle the problem + if (PHPBuilder.DEBUG) + System.out.println("ABORTING incremental build... cannot find " + e.qualifiedTypeName + //$NON-NLS-1$ + ". Could have been renamed inside its existing source file."); //$NON-NLS-1$ + return false; + } catch (CoreException e) { + throw internalException(e); + } finally { + cleanUp(); + } + return true; +} + +protected void addAffectedSourceFiles() { + if (qualifiedStrings.isEmpty() && simpleStrings.isEmpty()) return; + + // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are just 'X' + char[][][] qualifiedNames = ReferenceCollection.internQualifiedNames(qualifiedStrings); + // if a well known qualified name was found then we can skip over these + if (qualifiedNames.length < qualifiedStrings.size()) + qualifiedNames = null; + char[][] simpleNames = ReferenceCollection.internSimpleNames(simpleStrings); + // if a well known name was found then we can skip over these + if (simpleNames.length < simpleStrings.size()) + simpleNames = null; + + Object[] keyTable = newState.references.keyTable; + Object[] valueTable = newState.references.valueTable; + next : for (int i = 0, l = valueTable.length; i < l; i++) { + ReferenceCollection refs = (ReferenceCollection) valueTable[i]; + if (refs != null && refs.includes(qualifiedNames, simpleNames)) { + String typeLocator = (String) keyTable[i]; + IFile file = javaBuilder.currentProject.getFile(typeLocator); + if (file.exists()) { + ClasspathMultiDirectory md = sourceLocations[0]; + if (sourceLocations.length > 1) { + IPath sourceFileFullPath = file.getFullPath(); + for (int j = 0, m = sourceLocations.length; j < m; j++) { + if (sourceLocations[j].sourceFolder.getFullPath().isPrefixOf(sourceFileFullPath)) { + md = sourceLocations[j]; + if (md.exclusionPatterns == null || !Util.isExcluded(file, md.exclusionPatterns)) + break; + } + } + } + SourceFile sourceFile = new SourceFile(file, md, encoding); + if (sourceFiles.contains(sourceFile)) continue next; + if (compiledAllAtOnce && previousSourceFiles != null && previousSourceFiles.contains(sourceFile)) + continue next; // can skip previously compiled files since already saw hierarchy related problems + + if (PHPBuilder.DEBUG) + System.out.println(" adding affected source file " + typeLocator); //$NON-NLS-1$ + sourceFiles.add(sourceFile); + } + } + } +} + +protected void addDependentsOf(IPath path, boolean hasStructuralChanges) { + if (hasStructuralChanges) { + newState.tagAsStructurallyChanged(); + this.hasStructuralChanges = true; + } + // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are just 'X' + path = path.setDevice(null); + String packageName = path.removeLastSegments(1).toString(); + if (!qualifiedStrings.contains(packageName)) + qualifiedStrings.add(packageName); + String typeName = path.lastSegment(); + int memberIndex = typeName.indexOf('$'); + if (memberIndex > 0) + typeName = typeName.substring(0, memberIndex); + if (!simpleStrings.contains(typeName)) { + if (PHPBuilder.DEBUG) + System.out.println(" will look for dependents of " //$NON-NLS-1$ + + typeName + " in " + packageName); //$NON-NLS-1$ + simpleStrings.add(typeName); + } +} + +protected void cleanUp() { + super.cleanUp(); + + this.sourceFiles = null; + this.previousSourceFiles = null; + this.qualifiedStrings = null; + this.simpleStrings = null; + this.secondaryTypesToRemove = null; + this.hasStructuralChanges = false; + this.compileLoop = 0; +} + +//protected boolean findAffectedSourceFiles(IResourceDelta delta, ClasspathLocation[] classFoldersAndJars) { +// for (int i = 0, l = classFoldersAndJars.length; i < l; i++) { +// ClasspathLocation bLocation = classFoldersAndJars[i]; +// // either a .class file folder or a zip/jar file +// if (bLocation != null) { // skip unchanged output folder +// IPath p = bLocation.getProjectRelativePath(); +// if (p != null) { +// IResourceDelta binaryDelta = delta.findMember(p); +// if (binaryDelta != null) { +// if (bLocation instanceof ClasspathJar) { +// if (JavaBuilder.DEBUG) +// System.out.println("ABORTING incremental build... found delta to jar/zip file"); //$NON-NLS-1$ +// return false; // do full build since jar file was changed (added/removed were caught as classpath change) +// } +// if (binaryDelta.getKind() == IResourceDelta.ADDED || binaryDelta.getKind() == IResourceDelta.REMOVED) { +// if (JavaBuilder.DEBUG) +// System.out.println("ABORTING incremental build... found added/removed binary folder"); //$NON-NLS-1$ +// return false; // added/removed binary folder should not make it here (classpath change), but handle anyways +// } +// int segmentCount = binaryDelta.getFullPath().segmentCount(); +// IResourceDelta[] children = binaryDelta.getAffectedChildren(); // .class files from class folder +// for (int j = 0, m = children.length; j < m; j++) +// findAffectedSourceFiles(children[j], segmentCount); +// notifier.checkCancel(); +// } +// } +// } +// } +// return true; +//} + +protected void findAffectedSourceFiles(IResourceDelta binaryDelta, int segmentCount) { + // When a package becomes a type or vice versa, expect 2 deltas, + // one on the folder & one on the class file + IResource resource = binaryDelta.getResource(); + switch(resource.getType()) { + case IResource.FOLDER : + switch (binaryDelta.getKind()) { + case IResourceDelta.ADDED : + case IResourceDelta.REMOVED : + IPath packagePath = resource.getFullPath().removeFirstSegments(segmentCount); + String packageName = packagePath.toString(); + if (binaryDelta.getKind() == IResourceDelta.ADDED) { + // see if any known source file is from the same package... classpath already includes new package + if (!newState.isKnownPackage(packageName)) { + if (PHPBuilder.DEBUG) + System.out.println("Found added package " + packageName); //$NON-NLS-1$ + addDependentsOf(packagePath, false); + return; + } + if (PHPBuilder.DEBUG) + System.out.println("Skipped dependents of added package " + packageName); //$NON-NLS-1$ + } else { + // see if the package still exists on the classpath +// if (!nameEnvironment.isPackage(packageName)) { +// if (JavaBuilder.DEBUG) +// System.out.println("Found removed package " + packageName); //$NON-NLS-1$ +// addDependentsOf(packagePath, false); +// return; +// } + if (PHPBuilder.DEBUG) + System.out.println("Skipped dependents of removed package " + packageName); //$NON-NLS-1$ + } + // fall thru & traverse the sub-packages and .class files + case IResourceDelta.CHANGED : + IResourceDelta[] children = binaryDelta.getAffectedChildren(); + for (int i = 0, l = children.length; i < l; i++) + findAffectedSourceFiles(children[i], segmentCount); + } + return; + case IResource.FILE : +// if (Util.isClassFileName(resource.getName())) { +// IPath typePath = resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension(); +// switch (binaryDelta.getKind()) { +// case IResourceDelta.ADDED : +// case IResourceDelta.REMOVED : +// if (JavaBuilder.DEBUG) +// System.out.println("Found added/removed class file " + typePath); //$NON-NLS-1$ +// addDependentsOf(typePath, false); +// return; +// case IResourceDelta.CHANGED : +// if ((binaryDelta.getFlags() & IResourceDelta.CONTENT) == 0) +// return; // skip it since it really isn't changed +// if (JavaBuilder.DEBUG) +// System.out.println("Found changed class file " + typePath); //$NON-NLS-1$ +// addDependentsOf(typePath, false); +// } +// return; +// } + } +} + +protected boolean findSourceFiles(IResourceDelta delta) throws CoreException { + for (int i = 0, l = sourceLocations.length; i < l; i++) { + ClasspathMultiDirectory md = sourceLocations[i]; + if (md.sourceFolder.equals(javaBuilder.currentProject)) { + // skip nested source & output folders when the project is a source folder + int segmentCount = delta.getFullPath().segmentCount(); + IResourceDelta[] children = delta.getAffectedChildren(); + for (int j = 0, m = children.length; j < m; j++) + if (!isExcludedFromProject(children[j].getFullPath())) + findSourceFiles(children[j], md, segmentCount); + } else { + IResourceDelta sourceDelta = delta.findMember(md.sourceFolder.getProjectRelativePath()); + + if (sourceDelta != null) { + if (sourceDelta.getKind() == IResourceDelta.REMOVED) { + if (PHPBuilder.DEBUG) + System.out.println("ABORTING incremental build... found removed source folder"); //$NON-NLS-1$ + return false; // removed source folder should not make it here, but handle anyways (ADDED is supported) + } + int segmentCount = sourceDelta.getFullPath().segmentCount(); + IResourceDelta[] children = sourceDelta.getAffectedChildren(); + for (int j = 0, m = children.length; j < m; j++) + findSourceFiles(children[j], md, segmentCount); + } + } + notifier.checkCancel(); + } + return true; +} + +protected void findSourceFiles(IResourceDelta sourceDelta, ClasspathMultiDirectory md, int segmentCount) throws CoreException { + // When a package becomes a type or vice versa, expect 2 deltas, + // one on the folder & one on the source file + IResource resource = sourceDelta.getResource(); + if (md.exclusionPatterns != null && Util.isExcluded(resource, md.exclusionPatterns)) return; + switch(resource.getType()) { + case IResource.FOLDER : + switch (sourceDelta.getKind()) { + case IResourceDelta.ADDED : + IPath addedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount); + createFolder(addedPackagePath, md.binaryFolder); // ensure package exists in the output folder + // add dependents even when the package thinks it exists to be on the safe side + if (PHPBuilder.DEBUG) + System.out.println("Found added package " + addedPackagePath); //$NON-NLS-1$ + addDependentsOf(addedPackagePath, true); + // fall thru & collect all the source files + case IResourceDelta.CHANGED : + IResourceDelta[] children = sourceDelta.getAffectedChildren(); + for (int i = 0, l = children.length; i < l; i++) + findSourceFiles(children[i], md, segmentCount); + return; + case IResourceDelta.REMOVED : + IPath removedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount); + if (sourceLocations.length > 1) { + for (int i = 0, l = sourceLocations.length; i < l; i++) { + if (sourceLocations[i].sourceFolder.getFolder(removedPackagePath).exists()) { + // only a package fragment was removed, same as removing multiple source files + createFolder(removedPackagePath, md.binaryFolder); // ensure package exists in the output folder + IResourceDelta[] removedChildren = sourceDelta.getAffectedChildren(); + for (int j = 0, m = removedChildren.length; j < m; j++) + findSourceFiles(removedChildren[j], md, segmentCount); + return; + } + } + } + IFolder removedPackageFolder = md.binaryFolder.getFolder(removedPackagePath); + if (removedPackageFolder.exists()) + removedPackageFolder.delete(IResource.FORCE, null); + // add dependents even when the package thinks it does not exist to be on the safe side + if (PHPBuilder.DEBUG) + System.out.println("Found removed package " + removedPackagePath); //$NON-NLS-1$ + addDependentsOf(removedPackagePath, true); + newState.removePackage(sourceDelta); + } + return; + case IResource.FILE : + String resourceName = resource.getName(); + if (Util.isJavaFileName(resourceName)) { + IPath typePath = resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension(); + String typeLocator = resource.getProjectRelativePath().toString(); + switch (sourceDelta.getKind()) { + case IResourceDelta.ADDED : + if (PHPBuilder.DEBUG) + System.out.println("Compile this added source file " + typeLocator); //$NON-NLS-1$ + sourceFiles.add(new SourceFile((IFile) resource, md, encoding)); + String typeName = typePath.toString(); + if (!newState.isDuplicateLocator(typeName, typeLocator)) { // adding dependents results in 2 duplicate errors + if (PHPBuilder.DEBUG) + System.out.println("Found added source file " + typeName); //$NON-NLS-1$ + addDependentsOf(typePath, true); + } + return; + case IResourceDelta.REMOVED : + char[][] definedTypeNames = newState.getDefinedTypeNamesFor(typeLocator); + if (definedTypeNames == null) { // defined a single type matching typePath + removeClassFile(typePath, md.binaryFolder); + if ((sourceDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) { + // remove problems and tasks for a compilation unit that is being moved (to another package or renamed) + // if the target file is a compilation unit, the new cu will be recompiled + // if the target file is a non-java resource, then markers are removed + // see bug 2857 + IResource movedFile = javaBuilder.workspaceRoot.getFile(sourceDelta.getMovedToPath()); + PHPBuilder.removeProblemsAndTasksFor(movedFile); + } + } else { + if (PHPBuilder.DEBUG) + System.out.println("Found removed source file " + typePath.toString()); //$NON-NLS-1$ + addDependentsOf(typePath, true); // add dependents of the source file since it may be involved in a name collision + if (definedTypeNames.length > 0) { // skip it if it failed to successfully define a type + IPath packagePath = typePath.removeLastSegments(1); + for (int i = 0, l = definedTypeNames.length; i < l; i++) + removeClassFile(packagePath.append(new String(definedTypeNames[i])), md.binaryFolder); + } + } + newState.removeLocator(typeLocator); + return; + case IResourceDelta.CHANGED : + if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0) + return; // skip it since it really isn't changed + if (PHPBuilder.DEBUG) + System.out.println("Compile this changed source file " + typeLocator); //$NON-NLS-1$ + sourceFiles.add(new SourceFile((IFile) resource, md, encoding)); + } + return; +// } else if (Util.isClassFileName(resourceName)) { +// return; // skip class files + } else if (md.hasIndependentOutputFolder) { + if (javaBuilder.filterExtraResource(resource)) return; + + // copy all other resource deltas to the output folder + IPath resourcePath = resource.getFullPath().removeFirstSegments(segmentCount); + IResource outputFile = md.binaryFolder.getFile(resourcePath); + switch (sourceDelta.getKind()) { + case IResourceDelta.ADDED : + if (outputFile.exists()) { + if (PHPBuilder.DEBUG) + System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$ + outputFile.delete(IResource.FORCE, null); + } + if (PHPBuilder.DEBUG) + System.out.println("Copying added file " + resourcePath); //$NON-NLS-1$ + createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure package exists in the output folder + resource.copy(outputFile.getFullPath(), IResource.FORCE, null); + outputFile.setDerived(true); + return; + case IResourceDelta.REMOVED : + if (outputFile.exists()) { + if (PHPBuilder.DEBUG) + System.out.println("Deleting removed file " + resourcePath); //$NON-NLS-1$ + outputFile.delete(IResource.FORCE, null); + } + return; + case IResourceDelta.CHANGED : + if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0) + return; // skip it since it really isn't changed + if (outputFile.exists()) { + if (PHPBuilder.DEBUG) + System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$ + outputFile.delete(IResource.FORCE, null); + } + if (PHPBuilder.DEBUG) + System.out.println("Copying changed file " + resourcePath); //$NON-NLS-1$ + createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure package exists in the output folder + resource.copy(outputFile.getFullPath(), IResource.FORCE, null); + outputFile.setDerived(true); + } + return; + } + } +} + +protected void finishedWith(String sourceLocator, CompilationResult result, char[] mainTypeName, ArrayList definedTypeNames, ArrayList duplicateTypeNames) throws CoreException { + char[][] previousTypeNames = newState.getDefinedTypeNamesFor(sourceLocator); + if (previousTypeNames == null) + previousTypeNames = new char[][] {mainTypeName}; + IPath packagePath = null; + next : for (int i = 0, l = previousTypeNames.length; i < l; i++) { + char[] previous = previousTypeNames[i]; + for (int j = 0, m = definedTypeNames.size(); j < m; j++) + if (CharOperation.equals(previous, (char[]) definedTypeNames.get(j))) + continue next; + + SourceFile sourceFile = (SourceFile) result.getCompilationUnit(); + if (packagePath == null) { + int count = sourceFile.sourceLocation.sourceFolder.getFullPath().segmentCount(); + packagePath = sourceFile.resource.getFullPath().removeFirstSegments(count).removeLastSegments(1); + } + if (secondaryTypesToRemove == null) + this.secondaryTypesToRemove = new SimpleLookupTable(); + ArrayList types = (ArrayList) secondaryTypesToRemove.get(sourceFile.sourceLocation.binaryFolder); + if (types == null) + types = new ArrayList(definedTypeNames.size()); + types.add(packagePath.append(new String(previous))); + secondaryTypesToRemove.put(sourceFile.sourceLocation.binaryFolder, types); + } +// super.finishedWith(sourceLocator, result, mainTypeName, definedTypeNames, duplicateTypeNames); +} + +protected void removeClassFile(IPath typePath, IContainer outputFolder) throws CoreException { + if (typePath.lastSegment().indexOf('$') == -1) { // is not a nested type + newState.removeQualifiedTypeName(typePath.toString()); + // add dependents even when the type thinks it does not exist to be on the safe side + if (PHPBuilder.DEBUG) + System.out.println("Found removed type " + typePath); //$NON-NLS-1$ + addDependentsOf(typePath, true); // when member types are removed, their enclosing type is structurally changed + } + IFile classFile = outputFolder.getFile(typePath.addFileExtension(PHPBuilder.CLASS_EXTENSION)); + if (classFile.exists()) { + if (PHPBuilder.DEBUG) + System.out.println("Deleting class file of removed type " + typePath); //$NON-NLS-1$ + classFile.delete(IResource.FORCE, null); + } +} + +protected void removeSecondaryTypes() throws CoreException { + if (secondaryTypesToRemove != null) { // delayed deleting secondary types until the end of the compile loop + Object[] keyTable = secondaryTypesToRemove.keyTable; + Object[] valueTable = secondaryTypesToRemove.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) { + IContainer outputFolder = (IContainer) keyTable[i]; + if (outputFolder != null) { + ArrayList paths = (ArrayList) valueTable[i]; + for (int j = 0, m = paths.size(); j < m; j++) + removeClassFile((IPath) paths.get(j), outputFolder); + } + } + this.secondaryTypesToRemove = null; + if (previousSourceFiles != null && previousSourceFiles.size() > 1) + this.previousSourceFiles = null; // cannot optimize recompile case when a secondary type is deleted + } +} + +protected void resetCollections() { + previousSourceFiles = sourceFiles.isEmpty() ? null : (ArrayList) sourceFiles.clone(); + + sourceFiles.clear(); + qualifiedStrings.clear(); + simpleStrings.clear(); + workQueue.clear(); +} + +protected void updateProblemsFor(SourceFile sourceFile, CompilationResult result) throws CoreException { + IMarker[] markers = PHPBuilder.getProblemsFor(sourceFile.resource); + IProblem[] problems = result.getProblems(); + if (problems == null && markers.length == 0) return; + + notifier.updateProblemCounts(markers, problems); + PHPBuilder.removeProblemsFor(sourceFile.resource); + storeProblemsFor(sourceFile, problems); +} + +protected void updateTasksFor(SourceFile sourceFile, CompilationResult result) throws CoreException { + IMarker[] markers = PHPBuilder.getTasksFor(sourceFile.resource); + IProblem[] tasks = result.getTasks(); + if (tasks == null && markers.length == 0) return; + + PHPBuilder.removeTasksFor(sourceFile.resource); + storeTasksFor(sourceFile, tasks); +} + +//protected void writeClassFileBytes(byte[] bytes, IFile file, String qualifiedFileName, boolean isSecondaryType) throws CoreException { +// // Before writing out the class file, compare it to the previous file +// // If structural changes occured then add dependent source files +// if (file.exists()) { +// if (writeClassFileCheck(file, qualifiedFileName, bytes)) { +// if (JavaBuilder.DEBUG) +// System.out.println("Writing changed class file " + file.getName());//$NON-NLS-1$ +// file.setContents(new ByteArrayInputStream(bytes), true, false, null); +// if (!file.isDerived()) +// file.setDerived(true); +// } else if (JavaBuilder.DEBUG) { +// System.out.println("Skipped over unchanged class file " + file.getName());//$NON-NLS-1$ +// } +// } else { +// if (isSecondaryType) +// addDependentsOf(new Path(qualifiedFileName), true); // new secondary type +// if (JavaBuilder.DEBUG) +// System.out.println("Writing new class file " + file.getName());//$NON-NLS-1$ +// file.create(new ByteArrayInputStream(bytes), IResource.FORCE, null); +// file.setDerived(true); +// } +//} + +//protected boolean writeClassFileCheck(IFile file, String fileName, byte[] newBytes) throws CoreException { +// try { +// byte[] oldBytes = Util.getResourceContentsAsByteArray(file); +// if (this.compileLoop > 1) { // only optimize files which were recompiled during the dependent pass, see 33990 +// notEqual : if (newBytes.length == oldBytes.length) { +// for (int i = newBytes.length; --i >= 0;) +// if (newBytes[i] != oldBytes[i]) break notEqual; +// return false; // bytes are identical so skip them +// } +// } +// IPath location = file.getLocation(); +// if (location == null) return false; // unable to determine location of this class file +// ClassFileReader reader = new ClassFileReader(oldBytes, location.toString().toCharArray()); +// // ignore local types since they're only visible inside a single method +// if (!(reader.isLocal() || reader.isAnonymous()) && reader.hasStructuralChanges(newBytes)) { +// if (JavaBuilder.DEBUG) +// System.out.println("Type has structural changes " + fileName); //$NON-NLS-1$ +// addDependentsOf(new Path(fileName), true); +// } +// } catch (ClassFormatException e) { +// addDependentsOf(new Path(fileName), true); +// } +// return true; +//} + +public String toString() { + return "incremental image builder for:\n\tnew state: " + newState; //$NON-NLS-1$ +} + + +/* Debug helper + +static void dump(IResourceDelta delta) { + StringBuffer buffer = new StringBuffer(); + IPath path = delta.getFullPath(); + for (int i = path.segmentCount(); --i > 0;) + buffer.append(" "); + switch (delta.getKind()) { + case IResourceDelta.ADDED: + buffer.append('+'); + break; + case IResourceDelta.REMOVED: + buffer.append('-'); + break; + case IResourceDelta.CHANGED: + buffer.append('*'); + break; + case IResourceDelta.NO_CHANGE: + buffer.append('='); + break; + default: + buffer.append('?'); + break; + } + buffer.append(path); + System.out.println(buffer.toString()); + IResourceDelta[] children = delta.getAffectedChildren(); + for (int i = 0, l = children.length; i < l; i++) + dump(children[i]); +} +*/ +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/MissingClassFileException.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/MissingClassFileException.java new file mode 100644 index 0000000..4099502 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/MissingClassFileException.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +/** + * Exception thrown when the build should be aborted because a referenced + * class file cannot be found. + */ +public class MissingClassFileException extends RuntimeException { + +protected String missingClassFile; + +public MissingClassFileException(String missingClassFile) { + this.missingClassFile = missingClassFile; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/MissingSourceFileException.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/MissingSourceFileException.java new file mode 100644 index 0000000..4c5bf91 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/MissingSourceFileException.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +/** + * Exception thrown when the build should be aborted because a source file is missing/empty. + */ +public class MissingSourceFileException extends RuntimeException { + +protected String missingSourceFile; + +public MissingSourceFileException(String missingSourceFile) { + this.missingSourceFile = missingSourceFile; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/NameEnvironment.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/NameEnvironment.java new file mode 100644 index 0000000..9265c4c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/NameEnvironment.java @@ -0,0 +1,332 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import java.util.ArrayList; + +import net.sourceforge.phpdt.core.IClasspathEntry; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment; +import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; +import net.sourceforge.phpdt.internal.core.ClasspathEntry; +import net.sourceforge.phpdt.internal.core.JavaModel; +import net.sourceforge.phpdt.internal.core.JavaProject; +import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable; +import net.sourceforge.phpeclipse.PHPCore; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +public class NameEnvironment implements INameEnvironment { + + boolean isIncrementalBuild; + ClasspathMultiDirectory[] sourceLocations; + //ClasspathLocation[] binaryLocations; + + String[] initialTypeNames; // assumed that each name is of the form "a/b/ClassName" + SourceFile[] additionalUnits; + + NameEnvironment(IWorkspaceRoot root, JavaProject javaProject, SimpleLookupTable binaryLocationsPerProject) throws CoreException { + this.isIncrementalBuild = false; +// this.sourceLocations = new ClasspathMultiDirectory[0]; + computeClasspathLocations(root, javaProject, binaryLocationsPerProject); + setNames(null, null); + } + + public NameEnvironment(IJavaProject javaProject) { + this.isIncrementalBuild = false; + try { + computeClasspathLocations(javaProject.getProject().getWorkspace().getRoot(), (JavaProject) javaProject, null); + } catch(CoreException e) { +// this.sourceLocations = new ClasspathMultiDirectory[0]; + // this.binaryLocations = new ClasspathLocation[0]; + } + setNames(null, null); + } + + /* Some examples of resolved class path entries. + * Remember to search class path in the order that it was defined. + * + * 1a. typical project with no source folders: + * /Test[CPE_SOURCE][K_SOURCE] -> D:/eclipse.test/Test + * 1b. project with source folders: + * /Test/src1[CPE_SOURCE][K_SOURCE] -> D:/eclipse.test/Test/src1 + * /Test/src2[CPE_SOURCE][K_SOURCE] -> D:/eclipse.test/Test/src2 + * NOTE: These can be in any order & separated by prereq projects or libraries + * 1c. project external to workspace (only detectable using getLocation()): + * /Test/src[CPE_SOURCE][K_SOURCE] -> d:/eclipse.zzz/src + * Need to search source folder & output folder + * + * 2. zip files: + * D:/j9/lib/jclMax/classes.zip[CPE_LIBRARY][K_BINARY][sourcePath:d:/j9/lib/jclMax/source/source.zip] + * -> D:/j9/lib/jclMax/classes.zip + * ALWAYS want to take the library path as is + * + * 3a. prereq project (regardless of whether it has a source or output folder): + * /Test[CPE_PROJECT][K_SOURCE] -> D:/eclipse.test/Test + * ALWAYS want to append the output folder & ONLY search for .class files + */ + private void computeClasspathLocations( + IWorkspaceRoot root, + JavaProject javaProject, + SimpleLookupTable binaryLocationsPerProject) throws CoreException { + + /* Update incomplete classpath marker */ + IClasspathEntry[] classpathEntries = javaProject.getExpandedClasspath(true, true); + + /* Update cycle marker */ + IMarker cycleMarker = javaProject.getCycleMarker(); + if (cycleMarker != null) { + int severity = PHPCore.ERROR.equals(javaProject.getOption(PHPCore.CORE_CIRCULAR_CLASSPATH, true)) + ? IMarker.SEVERITY_ERROR + : IMarker.SEVERITY_WARNING; + if (severity != ((Integer) cycleMarker.getAttribute(IMarker.SEVERITY)).intValue()) + cycleMarker.setAttribute(IMarker.SEVERITY, severity); + } + + ArrayList sLocations = new ArrayList(classpathEntries.length); + ArrayList bLocations = new ArrayList(classpathEntries.length); + nextEntry : for (int i = 0, l = classpathEntries.length; i < l; i++) { + ClasspathEntry entry = (ClasspathEntry) classpathEntries[i]; + IPath path = entry.getPath(); + Object target = JavaModel.getTarget(root, path, true); + if (target == null) continue nextEntry; + + switch(entry.getEntryKind()) { + case IClasspathEntry.CPE_SOURCE : + if (!(target instanceof IContainer)) continue nextEntry; + IPath outputPath = entry.getOutputLocation() != null + ? entry.getOutputLocation() + : javaProject.getOutputLocation(); + IContainer outputFolder; + if (outputPath.segmentCount() == 1) { + outputFolder = javaProject.getProject(); + } else { + outputFolder = root.getFolder(outputPath); + if (!outputFolder.exists()) + createFolder(outputFolder); + } + sLocations.add( + ClasspathLocation.forSourceFolder((IContainer) target, outputFolder, entry.fullExclusionPatternChars())); + continue nextEntry; + + case IClasspathEntry.CPE_PROJECT : + if (!(target instanceof IProject)) continue nextEntry; + IProject prereqProject = (IProject) target; + if (!JavaProject.hasJavaNature(prereqProject)) continue nextEntry; // if project doesn't have java nature or is not accessible + + JavaProject prereqJavaProject = (JavaProject) PHPCore.create(prereqProject); + IClasspathEntry[] prereqClasspathEntries = prereqJavaProject.getRawClasspath(); + ArrayList seen = new ArrayList(); + nextPrereqEntry: for (int j = 0, m = prereqClasspathEntries.length; j < m; j++) { + IClasspathEntry prereqEntry = (IClasspathEntry) prereqClasspathEntries[j]; + if (prereqEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { + Object prereqTarget = JavaModel.getTarget(root, prereqEntry.getPath(), true); + if (!(prereqTarget instanceof IContainer)) continue nextPrereqEntry; + IPath prereqOutputPath = prereqEntry.getOutputLocation() != null + ? prereqEntry.getOutputLocation() + : prereqJavaProject.getOutputLocation(); + IContainer binaryFolder = prereqOutputPath.segmentCount() == 1 + ? (IContainer) prereqProject + : (IContainer) root.getFolder(prereqOutputPath); + if (binaryFolder.exists() && !seen.contains(binaryFolder)) { + seen.add(binaryFolder); + ClasspathLocation bLocation = ClasspathLocation.forBinaryFolder(binaryFolder, true); + bLocations.add(bLocation); + if (binaryLocationsPerProject != null) { // normal builder mode + ClasspathLocation[] existingLocations = (ClasspathLocation[]) binaryLocationsPerProject.get(prereqProject); + if (existingLocations == null) { + existingLocations = new ClasspathLocation[] {bLocation}; + } else { + int size = existingLocations.length; + System.arraycopy(existingLocations, 0, existingLocations = new ClasspathLocation[size + 1], 0, size); + existingLocations[size] = bLocation; + } + binaryLocationsPerProject.put(prereqProject, existingLocations); + } + } + } + } + continue nextEntry; + +// case IClasspathEntry.CPE_LIBRARY : +// if (target instanceof IResource) { +// IResource resource = (IResource) target; +// ClasspathLocation bLocation = null; +// if (resource instanceof IFile) { +// if (!(Util.isArchiveFileName(path.lastSegment()))) +// continue nextEntry; +// bLocation = ClasspathLocation.forLibrary((IFile) resource); +// } else if (resource instanceof IContainer) { +// bLocation = ClasspathLocation.forBinaryFolder((IContainer) target, false); // is library folder not output folder +// } +// bLocations.add(bLocation); +// if (binaryLocationsPerProject != null) { // normal builder mode +// IProject p = resource.getProject(); // can be the project being built +// ClasspathLocation[] existingLocations = (ClasspathLocation[]) binaryLocationsPerProject.get(p); +// if (existingLocations == null) { +// existingLocations = new ClasspathLocation[] {bLocation}; +// } else { +// int size = existingLocations.length; +// System.arraycopy(existingLocations, 0, existingLocations = new ClasspathLocation[size + 1], 0, size); +// existingLocations[size] = bLocation; +// } +// binaryLocationsPerProject.put(p, existingLocations); +// } +// } else if (target instanceof File) { +// if (!(Util.isArchiveFileName(path.lastSegment()))) +// continue nextEntry; +// bLocations.add(ClasspathLocation.forLibrary(path.toString())); +// } +// continue nextEntry; + } + } + + // now split the classpath locations... place the output folders ahead of the other .class file folders & jars + ArrayList outputFolders = new ArrayList(1); + this.sourceLocations = new ClasspathMultiDirectory[sLocations.size()]; + if (!sLocations.isEmpty()) { + sLocations.toArray(this.sourceLocations); + + // collect the output folders, skipping duplicates + next : for (int i = 0, l = sourceLocations.length; i < l; i++) { + ClasspathMultiDirectory md = sourceLocations[i]; + IPath outputPath = md.binaryFolder.getFullPath(); + for (int j = 0; j < i; j++) { // compare against previously walked source folders + if (outputPath.equals(sourceLocations[j].binaryFolder.getFullPath())) { + md.hasIndependentOutputFolder = sourceLocations[j].hasIndependentOutputFolder; + continue next; + } + } + outputFolders.add(md); + + // also tag each source folder whose output folder is an independent folder & is not also a source folder + for (int j = 0, m = sourceLocations.length; j < m; j++) + if (outputPath.equals(sourceLocations[j].sourceFolder.getFullPath())) + continue next; + md.hasIndependentOutputFolder = true; + } + } + +// combine the output folders with the binary folders & jars... place the output folders before other .class file folders & jars +// this.binaryLocations = new ClasspathLocation[outputFolders.size() + bLocations.size()]; +// int index = 0; +// for (int i = 0, l = outputFolders.size(); i < l; i++) +// this.binaryLocations[index++] = (ClasspathLocation) outputFolders.get(i); +// for (int i = 0, l = bLocations.size(); i < l; i++) +// this.binaryLocations[index++] = (ClasspathLocation) bLocations.get(i); + } + + public void cleanup() { + this.initialTypeNames = null; + this.additionalUnits = null; + for (int i = 0, l = sourceLocations.length; i < l; i++) + sourceLocations[i].cleanup(); + // for (int i = 0, l = binaryLocations.length; i < l; i++) + // binaryLocations[i].cleanup(); + } + + private void createFolder(IContainer folder) throws CoreException { + if (!folder.exists()) { + createFolder(folder.getParent()); + ((IFolder) folder).create(true, true, null); + } + } + + private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[] typeName) { + if (initialTypeNames != null) { + for (int i = 0, l = initialTypeNames.length; i < l; i++) { + if (qualifiedTypeName.equals(initialTypeNames[i])) { + if (isIncrementalBuild) + // catch the case that a type inside a source file has been renamed but other class files are looking for it + throw new AbortCompilation(true, new AbortIncrementalBuildException(qualifiedTypeName)); + return null; // looking for a file which we know was provided at the beginning of the compilation + } + } + } + + if (additionalUnits != null && sourceLocations.length > 0) { + // if an additional source file is waiting to be compiled, answer it BUT not if this is a secondary type search + // if we answer X.java & it no longer defines Y then the binary type looking for Y will think the class path is wrong + // let the recompile loop fix up dependents when the secondary type Y has been deleted from X.java + IPath qSourceFilePath = new Path(qualifiedTypeName + ".java"); //$NON-NLS-1$ + int qSegmentCount = qSourceFilePath.segmentCount(); + next : for (int i = 0, l = additionalUnits.length; i < l; i++) { + SourceFile additionalUnit = additionalUnits[i]; + IPath fullPath = additionalUnit.resource.getFullPath(); + int prefixCount = additionalUnit.sourceLocation.sourceFolder.getFullPath().segmentCount(); + if (qSegmentCount == fullPath.segmentCount() - prefixCount) { + for (int j = 0; j < qSegmentCount; j++) + if (!qSourceFilePath.segment(j).equals(fullPath.segment(j + prefixCount))) + continue next; + return new NameEnvironmentAnswer(additionalUnit); + } + } + } + + // String qBinaryFileName = qualifiedTypeName + ".class"; //$NON-NLS-1$ + // String binaryFileName = qBinaryFileName; + // String qPackageName = ""; //$NON-NLS-1$ + // if (qualifiedTypeName.length() > typeName.length) { + // int typeNameStart = qBinaryFileName.length() - typeName.length - 6; // size of ".class" + // qPackageName = qBinaryFileName.substring(0, typeNameStart - 1); + // binaryFileName = qBinaryFileName.substring(typeNameStart); + // } + // + // // NOTE: the output folders are added at the beginning of the binaryLocations + // for (int i = 0, l = binaryLocations.length; i < l; i++) { + // NameEnvironmentAnswer answer = binaryLocations[i].findClass(binaryFileName, qPackageName, qBinaryFileName); + // if (answer != null) return answer; + // } + return null; + } + + public NameEnvironmentAnswer findType(char[][] compoundName) { + if (compoundName != null) + return findClass(new String(CharOperation.concatWith(compoundName, '/')), compoundName[compoundName.length - 1]); + return null; + } + + public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) { + if (typeName != null) + return findClass(new String(CharOperation.concatWith(packageName, typeName, '/')), typeName); + return null; + } + + public boolean isPackage(char[][] compoundName, char[] packageName) { + return isPackage(new String(CharOperation.concatWith(compoundName, packageName, '/'))); + } + + public boolean isPackage(String qualifiedPackageName) { + // NOTE: the output folders are added at the beginning of the binaryLocations + // for (int i = 0, l = binaryLocations.length; i < l; i++) + // if (binaryLocations[i].isPackage(qualifiedPackageName)) + // return true; + return false; + } + + void setNames(String[] initialTypeNames, SourceFile[] additionalUnits) { + this.initialTypeNames = initialTypeNames; + this.additionalUnits = additionalUnits; + for (int i = 0, l = sourceLocations.length; i < l; i++) + sourceLocations[i].reset(); + // for (int i = 0, l = binaryLocations.length; i < l; i++) + // binaryLocations[i].reset(); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/PHPBuilder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/PHPBuilder.java new file mode 100644 index 0000000..ee59f34 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/PHPBuilder.java @@ -0,0 +1,598 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; + +import net.sourceforge.phpdt.core.IClasspathEntry; +import net.sourceforge.phpdt.core.IJavaModelMarker; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.core.JavaModel; +import net.sourceforge.phpdt.internal.core.JavaModelManager; +import net.sourceforge.phpdt.internal.core.JavaProject; +import net.sourceforge.phpdt.internal.core.Util; +import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable; +import net.sourceforge.phpeclipse.PHPCore; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; + +public class PHPBuilder extends IncrementalProjectBuilder { + + IProject currentProject; + JavaProject javaProject; + IWorkspaceRoot workspaceRoot; + NameEnvironment nameEnvironment; + SimpleLookupTable binaryLocationsPerProject; // maps a project to its binary resources (output folders, class folders, zip/jar files) + State lastState; + BuildNotifier notifier; + char[][] extraResourceFileFilters; + String[] extraResourceFolderFilters; + + public static final String CLASS_EXTENSION = "class"; //$NON-NLS-1$ + + public static boolean DEBUG = true; + + /** + * A list of project names that have been built. + * This list is used to reset the JavaModel.existingExternalFiles cache when a build cycle begins + * so that deleted external jars are discovered. + */ + static ArrayList builtProjects = null; + + public static IMarker[] getProblemsFor(IResource resource) { + try { + if (resource != null && resource.exists()) + return resource.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); + } catch (CoreException e) { + } // assume there are no problems + return new IMarker[0]; + } + + public static IMarker[] getTasksFor(IResource resource) { + try { + if (resource != null && resource.exists()) + return resource.findMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE); + } catch (CoreException e) { + } // assume there are no tasks + return new IMarker[0]; + } + + public static void finishedBuilding(IResourceChangeEvent event) { + BuildNotifier.resetProblemCounters(); + } + + public static void removeProblemsFor(IResource resource) { + try { + if (resource != null && resource.exists()) + resource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); + } catch (CoreException e) { + } // assume there were no problems + } + + public static void removeTasksFor(IResource resource) { + try { + if (resource != null && resource.exists()) + resource.deleteMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE); + } catch (CoreException e) { + } // assume there were no problems + } + + public static void removeProblemsAndTasksFor(IResource resource) { + try { + if (resource != null && resource.exists()) { + resource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); + resource.deleteMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE); + } + } catch (CoreException e) { + } // assume there were no problems + } + + public static State readState(IProject project, DataInputStream in) throws IOException { + return State.read(project, in); + } + + public static void writeState(Object state, DataOutputStream out) throws IOException { + ((State) state).write(out); + } + + public PHPBuilder() { + } + + protected IProject[] build(int kind, Map ignored, IProgressMonitor monitor) throws CoreException { + this.currentProject = getProject(); + if (currentProject == null || !currentProject.isAccessible()) + return new IProject[0]; + + if (DEBUG) + System.out.println("\nStarting build of " + currentProject.getName() //$NON-NLS-1$ + +" @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$ + this.notifier = new BuildNotifier(monitor, currentProject); + notifier.begin(); + boolean ok = false; + try { + notifier.checkCancel(); + initializeBuilder(); + + if (isWorthBuilding()) { + if (kind == FULL_BUILD) { + buildAll(); + } else { + if ((this.lastState = getLastState(currentProject)) == null) { + if (DEBUG) + System.out.println("Performing full build since last saved state was not found"); //$NON-NLS-1$ + buildAll(); + } else if (hasClasspathChanged()) { + // if the output location changes, do not delete the binary files from old location + // the user may be trying something + buildAll(); + } else if (nameEnvironment.sourceLocations.length > 0) { + // if there is no source to compile & no classpath changes then we are done + SimpleLookupTable deltas = findDeltas(); + if (deltas == null) + buildAll(); + else if (deltas.elementSize > 0) + buildDeltas(deltas); + else if (DEBUG) + System.out.println("Nothing to build since deltas were empty"); //$NON-NLS-1$ + } else { + if (hasStructuralDelta()) { // double check that a jar file didn't get replaced in a binary project + buildAll(); + } else { + if (DEBUG) + System.out.println("Nothing to build since there are no source folders and no deltas"); //$NON-NLS-1$ + lastState.tagAsNoopBuild(); + } + } + } + ok = true; + } + } catch (CoreException e) { + Util.log(e, "JavaBuilder handling CoreException"); //$NON-NLS-1$ + IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); + marker.setAttribute(IMarker.MESSAGE, Util.bind("build.inconsistentProject", e.getLocalizedMessage())); //$NON-NLS-1$ + marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); + } catch (ImageBuilderInternalException e) { + Util.log(e.getThrowable(), "JavaBuilder handling ImageBuilderInternalException"); //$NON-NLS-1$ + IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); + marker.setAttribute(IMarker.MESSAGE, Util.bind("build.inconsistentProject", e.coreException.getLocalizedMessage())); //$NON-NLS-1$ + marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); + } catch (MissingClassFileException e) { + // do not log this exception since its thrown to handle aborted compiles because of missing class files + if (DEBUG) + System.out.println(Util.bind("build.incompleteClassPath", e.missingClassFile)); //$NON-NLS-1$ + IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); + marker.setAttribute(IMarker.MESSAGE, Util.bind("build.incompleteClassPath", e.missingClassFile)); //$NON-NLS-1$ + marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); + } catch (MissingSourceFileException e) { + // do not log this exception since its thrown to handle aborted compiles because of missing source files + if (DEBUG) + System.out.println(Util.bind("build.missingSourceFile", e.missingSourceFile)); //$NON-NLS-1$ + removeProblemsAndTasksFor(currentProject); // make this the only problem for this project + IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); + marker.setAttribute(IMarker.MESSAGE, Util.bind("build.missingSourceFile", e.missingSourceFile)); //$NON-NLS-1$ + marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); + } finally { + if (!ok) + // If the build failed, clear the previously built state, forcing a full build next time. + clearLastState(); + notifier.done(); + cleanup(); + } + IProject[] requiredProjects = getRequiredProjects(true); + if (DEBUG) + System.out.println("Finished build of " + currentProject.getName() //$NON-NLS-1$ + +" @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$ + return requiredProjects; + } + + private void buildAll() { + notifier.checkCancel(); + notifier.subTask(Util.bind("build.preparingBuild")); //$NON-NLS-1$ + if (DEBUG && lastState != null) + System.out.println("Clearing last state : " + lastState); //$NON-NLS-1$ + clearLastState(); + BatchImageBuilder imageBuilder = new BatchImageBuilder(this); + imageBuilder.build(); + recordNewState(imageBuilder.newState); + } + + private void buildDeltas(SimpleLookupTable deltas) { + notifier.checkCancel(); + notifier.subTask(Util.bind("build.preparingBuild")); //$NON-NLS-1$ + if (DEBUG && lastState != null) + System.out.println("Clearing last state : " + lastState); //$NON-NLS-1$ + clearLastState(); // clear the previously built state so if the build fails, a full build will occur next time + IncrementalImageBuilder imageBuilder = new IncrementalImageBuilder(this); + if (imageBuilder.build(deltas)) + recordNewState(imageBuilder.newState); + else + buildAll(); + } + + private void cleanup() { + this.nameEnvironment = null; + this.binaryLocationsPerProject = null; + this.lastState = null; + this.notifier = null; + this.extraResourceFileFilters = null; + this.extraResourceFolderFilters = null; + } + + private void clearLastState() { + JavaModelManager.getJavaModelManager().setLastBuiltState(currentProject, null); + } + + boolean filterExtraResource(IResource resource) { + if (extraResourceFileFilters != null) { + char[] name = resource.getName().toCharArray(); + for (int i = 0, l = extraResourceFileFilters.length; i < l; i++) + if (CharOperation.match(extraResourceFileFilters[i], name, true)) + return true; + } + if (extraResourceFolderFilters != null) { + IPath path = resource.getProjectRelativePath(); + String pathName = path.toString(); + int count = path.segmentCount(); + if (resource.getType() == IResource.FILE) + count--; + for (int i = 0, l = extraResourceFolderFilters.length; i < l; i++) + if (pathName.indexOf(extraResourceFolderFilters[i]) != -1) + for (int j = 0; j < count; j++) + if (extraResourceFolderFilters[i].equals(path.segment(j))) + return true; + } + return false; + } + + private SimpleLookupTable findDeltas() { + notifier.subTask(Util.bind("build.readingDelta", currentProject.getName())); //$NON-NLS-1$ + IResourceDelta delta = getDelta(currentProject); + SimpleLookupTable deltas = new SimpleLookupTable(3); + if (delta != null) { + if (delta.getKind() != IResourceDelta.NO_CHANGE) { + if (DEBUG) + System.out.println("Found source delta for: " + currentProject.getName()); //$NON-NLS-1$ + deltas.put(currentProject, delta); + } + } else { + if (DEBUG) + System.out.println("Missing delta for: " + currentProject.getName()); //$NON-NLS-1$ + notifier.subTask(""); //$NON-NLS-1$ + return null; + } + + Object[] keyTable = binaryLocationsPerProject.keyTable; + Object[] valueTable = binaryLocationsPerProject.valueTable; + nextProject : for (int i = 0, l = keyTable.length; i < l; i++) { + IProject p = (IProject) keyTable[i]; + if (p != null && p != currentProject) { + State s = getLastState(p); + if (!lastState.wasStructurallyChanged(p, s)) { // see if we can skip its delta + if (s.wasNoopBuild()) + continue nextProject; // project has no source folders and can be skipped + // ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) valueTable[i]; + boolean canSkip = true; + // for (int j = 0, m = classFoldersAndJars.length; j < m; j++) { + // if (classFoldersAndJars[j].isOutputFolder()) + // classFoldersAndJars[j] = null; // can ignore output folder since project was not structurally changed + // else + // canSkip = false; + // } + if (canSkip) + continue nextProject; // project has no structural changes in its output folders + } + + notifier.subTask(Util.bind("build.readingDelta", p.getName())); //$NON-NLS-1$ + delta = getDelta(p); + if (delta != null) { + if (delta.getKind() != IResourceDelta.NO_CHANGE) { + if (DEBUG) + System.out.println("Found binary delta for: " + p.getName()); //$NON-NLS-1$ + deltas.put(p, delta); + } + } else { + if (DEBUG) + System.out.println("Missing delta for: " + p.getName()); //$NON-NLS-1$ + notifier.subTask(""); //$NON-NLS-1$ + return null; + } + } + } + notifier.subTask(""); //$NON-NLS-1$ + return deltas; + } + + private State getLastState(IProject project) { + return (State) JavaModelManager.getJavaModelManager().getLastBuiltState(project, notifier.monitor); + } + + /* Return the list of projects for which it requires a resource delta. This builder's project + * is implicitly included and need not be specified. Builders must re-specify the list + * of interesting projects every time they are run as this is not carried forward + * beyond the next build. Missing projects should be specified but will be ignored until + * they are added to the workspace. + */ + private IProject[] getRequiredProjects(boolean includeBinaryPrerequisites) { + if (javaProject == null || workspaceRoot == null) + return new IProject[0]; + + ArrayList projects = new ArrayList(); + try { + IClasspathEntry[] entries = javaProject.getExpandedClasspath(true); + for (int i = 0, l = entries.length; i < l; i++) { + IClasspathEntry entry = entries[i]; + IPath path = entry.getPath(); + IProject p = null; + switch (entry.getEntryKind()) { + case IClasspathEntry.CPE_PROJECT : + p = workspaceRoot.getProject(path.lastSegment()); // missing projects are considered too + break; + case IClasspathEntry.CPE_LIBRARY : + if (includeBinaryPrerequisites && path.segmentCount() > 1) { + // some binary resources on the class path can come from projects that are not included in the project references + IResource resource = workspaceRoot.findMember(path.segment(0)); + if (resource instanceof IProject) + p = (IProject) resource; + } + } + if (p != null && !projects.contains(p)) + projects.add(p); + } + } catch (JavaModelException e) { + return new IProject[0]; + } + IProject[] result = new IProject[projects.size()]; + projects.toArray(result); + return result; + } + + private boolean hasClasspathChanged() { + ClasspathMultiDirectory[] newSourceLocations = nameEnvironment.sourceLocations; + ClasspathMultiDirectory[] oldSourceLocations = lastState.sourceLocations; + int newLength = newSourceLocations.length; + int oldLength = oldSourceLocations.length; + int n, o; + for (n = o = 0; n < newLength && o < oldLength; n++, o++) { + if (newSourceLocations[n].equals(oldSourceLocations[o])) + continue; // checks source & output folders + try { + if (newSourceLocations[n].sourceFolder.members().length == 0) { // added new empty source folder + o--; + continue; + } + } catch (CoreException ignore) { + } + if (DEBUG) + System.out.println(newSourceLocations[n] + " != " + oldSourceLocations[o]); //$NON-NLS-1$ + return true; + } + while (n < newLength) { + try { + if (newSourceLocations[n].sourceFolder.members().length == 0) { // added new empty source folder + n++; + continue; + } + } catch (CoreException ignore) { + } + if (DEBUG) + System.out.println("Added non-empty source folder"); //$NON-NLS-1$ + return true; + } + if (o < oldLength) { + if (DEBUG) + System.out.println("Removed source folder"); //$NON-NLS-1$ + return true; + } + + // ClasspathLocation[] newBinaryLocations = nameEnvironment.binaryLocations; + // ClasspathLocation[] oldBinaryLocations = lastState.binaryLocations; + // newLength = newBinaryLocations.length; + // oldLength = oldBinaryLocations.length; + // for (n = o = 0; n < newLength && o < oldLength; n++, o++) { + // if (newBinaryLocations[n].equals(oldBinaryLocations[o])) continue; + // if (DEBUG) + // System.out.println(newBinaryLocations[n] + " != " + oldBinaryLocations[o]); //$NON-NLS-1$ + // return true; + // } + // if (n < newLength || o < oldLength) { + // if (DEBUG) + // System.out.println("Number of binary folders/jar files has changed"); //$NON-NLS-1$ + // return true; + // } + return false; + } + + private boolean hasStructuralDelta() { + // handle case when currentProject has only .class file folders and/or jar files... no source/output folders + IResourceDelta delta = getDelta(currentProject); + if (delta != null && delta.getKind() != IResourceDelta.NO_CHANGE) { + // ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) binaryLocationsPerProject.get(currentProject); + // if (classFoldersAndJars != null) { + // for (int i = 0, l = classFoldersAndJars.length; i < l; i++) { + // ClasspathLocation classFolderOrJar = classFoldersAndJars[i]; // either a .class file folder or a zip/jar file + // if (classFolderOrJar != null) { + // IPath p = classFolderOrJar.getProjectRelativePath(); + // if (p != null) { + // IResourceDelta binaryDelta = delta.findMember(p); + // if (binaryDelta != null && binaryDelta.getKind() != IResourceDelta.NO_CHANGE) + // return true; + // } + // } + // } + // } + } + return false; + } + + private void initializeBuilder() throws CoreException { + this.javaProject = (JavaProject) PHPCore.create(currentProject); + this.workspaceRoot = currentProject.getWorkspace().getRoot(); + + // Flush the existing external files cache if this is the beginning of a build cycle + String projectName = currentProject.getName(); + if (builtProjects == null || builtProjects.contains(projectName)) { + JavaModel.flushExternalFileCache(); + builtProjects = new ArrayList(); + } + builtProjects.add(projectName); + + this.binaryLocationsPerProject = new SimpleLookupTable(3); + this.nameEnvironment = new NameEnvironment(workspaceRoot, javaProject, binaryLocationsPerProject); + + String filterSequence = javaProject.getOption(PHPCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, true); + char[][] filters = filterSequence != null && filterSequence.length() > 0 ? CharOperation.splitAndTrimOn(',', filterSequence.toCharArray()) : null; + if (filters == null) { + this.extraResourceFileFilters = null; + this.extraResourceFolderFilters = null; + } else { + int fileCount = 0, folderCount = 0; + for (int i = 0, l = filters.length; i < l; i++) { + char[] f = filters[i]; + if (f.length == 0) + continue; + if (f[f.length - 1] == '/') + folderCount++; + else + fileCount++; + } + this.extraResourceFileFilters = new char[fileCount][]; + this.extraResourceFolderFilters = new String[folderCount]; + for (int i = 0, l = filters.length; i < l; i++) { + char[] f = filters[i]; + if (f.length == 0) + continue; + if (f[f.length - 1] == '/') + extraResourceFolderFilters[--folderCount] = new String(CharOperation.subarray(f, 0, f.length - 1)); + else + extraResourceFileFilters[--fileCount] = f; + } + } + } + + private boolean isClasspathBroken(IClasspathEntry[] classpath, IProject p) throws CoreException { + if (classpath == JavaProject.INVALID_CLASSPATH) // the .classpath file could not be read + return true; + + IMarker[] markers = p.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); + for (int i = 0, l = markers.length; i < l; i++) + if (((Integer) markers[i].getAttribute(IMarker.SEVERITY)).intValue() == IMarker.SEVERITY_ERROR) + return true; + return false; + } + + private boolean isWorthBuilding() throws CoreException { + boolean abortBuilds = PHPCore.ABORT.equals(javaProject.getOption(PHPCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, true)); + if (!abortBuilds) + return true; + + // Abort build only if there are classpath errors +// if (isClasspathBroken(javaProject.getRawClasspath(), currentProject)) { +// if (DEBUG) +// System.out.println("Aborted build because project has classpath errors (incomplete or involved in cycle)"); //$NON-NLS-1$ +// +// JavaModelManager.getJavaModelManager().deltaProcessor.addForRefresh(javaProject); +// +// removeProblemsAndTasksFor(currentProject); // remove all compilation problems +// +// IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); +// marker.setAttribute(IMarker.MESSAGE, Util.bind("build.abortDueToClasspathProblems")); //$NON-NLS-1$ +// marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); +// return false; +// } + + // make sure all prereq projects have valid build states... only when aborting builds since projects in cycles do not have build states + // except for projects involved in a 'warning' cycle (see below) + IProject[] requiredProjects = getRequiredProjects(false); + next : for (int i = 0, l = requiredProjects.length; i < l; i++) { + IProject p = requiredProjects[i]; + if (getLastState(p) == null) { + // The prereq project has no build state: if this prereq project has a 'warning' cycle marker then allow build (see bug id 23357) + JavaProject prereq = (JavaProject) PHPCore.create(p); + if (prereq.hasCycleMarker() && PHPCore.WARNING.equals(javaProject.getOption(PHPCore.CORE_CIRCULAR_CLASSPATH, true))) + continue; + if (DEBUG) + System.out.println("Aborted build because prereq project " + p.getName() //$NON-NLS-1$ + +" was not built"); //$NON-NLS-1$ + + removeProblemsAndTasksFor(currentProject); // make this the only problem for this project + IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); + marker.setAttribute(IMarker.MESSAGE, isClasspathBroken(prereq.getRawClasspath(), p) ? Util.bind("build.prereqProjectHasClasspathProblems", p.getName()) //$NON-NLS-1$ + : Util.bind("build.prereqProjectMustBeRebuilt", p.getName())); //$NON-NLS-1$ + marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); + return false; + } + } + return true; + } + + /* + * Instruct the build manager that this project is involved in a cycle and + * needs to propagate structural changes to the other projects in the cycle. + */ + void mustPropagateStructuralChanges() { + HashSet cycleParticipants = new HashSet(3); + javaProject.updateCycleParticipants(null, new ArrayList(), cycleParticipants, workspaceRoot, new HashSet(3)); + IPath currentPath = javaProject.getPath(); + Iterator i = cycleParticipants.iterator(); + while (i.hasNext()) { + IPath participantPath = (IPath) i.next(); + if (participantPath != currentPath) { + IProject project = this.workspaceRoot.getProject(participantPath.segment(0)); + if (hasBeenBuilt(project)) { + if (DEBUG) + System.out.println("Requesting another build iteration since cycle participant " + project.getName() //$NON-NLS-1$ + +" has not yet seen some structural changes"); //$NON-NLS-1$ + needRebuild(); + return; + } + } + } + } + + private void recordNewState(State state) { + Object[] keyTable = binaryLocationsPerProject.keyTable; + for (int i = 0, l = keyTable.length; i < l; i++) { + IProject prereqProject = (IProject) keyTable[i]; + if (prereqProject != null && prereqProject != currentProject) + state.recordStructuralDependency(prereqProject, getLastState(prereqProject)); + } + + if (DEBUG) + System.out.println("Recording new state : " + state); //$NON-NLS-1$ + // state.dump(); + JavaModelManager.getJavaModelManager().setLastBuiltState(currentProject, state); + } + + /** + * String representation for debugging purposes + */ + public String toString() { + return currentProject == null ? "JavaBuilder for unknown project" //$NON-NLS-1$ + : "JavaBuilder for " + currentProject.getName(); //$NON-NLS-1$ + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ProblemFactory.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ProblemFactory.java new file mode 100644 index 0000000..e3124ae --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ProblemFactory.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import java.util.Locale; + +import net.sourceforge.phpdt.internal.compiler.problem.DefaultProblemFactory; +import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable; + +public class ProblemFactory extends DefaultProblemFactory { + +static SimpleLookupTable factories = new SimpleLookupTable(5); + +private ProblemFactory(Locale locale) { + super(locale); +} + +public static ProblemFactory getProblemFactory(Locale locale) { + ProblemFactory factory = (ProblemFactory) factories.get(locale); + if (factory == null) + factories.put(locale, factory = new ProblemFactory(locale)); + return factory; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ReferenceCollection.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ReferenceCollection.java new file mode 100644 index 0000000..0691a69 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/ReferenceCollection.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import java.util.ArrayList; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants; + +public class ReferenceCollection { + +char[][][] qualifiedNameReferences; // contains no simple names as in just 'a' which is kept in simpleNameReferences instead +char[][] simpleNameReferences; + +protected ReferenceCollection(char[][][] qualifiedNameReferences, char[][] simpleNameReferences) { + this.qualifiedNameReferences = internQualifiedNames(qualifiedNameReferences); + this.simpleNameReferences = internSimpleNames(simpleNameReferences, true); +} + +boolean includes(char[] simpleName) { + for (int i = 0, l = simpleNameReferences.length; i < l; i++) + if (simpleName == simpleNameReferences[i]) return true; + return false; +} + +boolean includes(char[][] qualifiedName) { + for (int i = 0, l = qualifiedNameReferences.length; i < l; i++) + if (qualifiedName == qualifiedNameReferences[i]) return true; + return false; +} + +boolean includes(char[][][] qualifiedNames, char[][] simpleNames) { + // if either collection of names is null, it means it contained a well known name so we know it already has a match + if (simpleNames == null || qualifiedNames == null) { + if (simpleNames == null && qualifiedNames == null) { + if (PHPBuilder.DEBUG) + System.out.println("Found well known match"); //$NON-NLS-1$ + return true; + } else if (qualifiedNames == null) { + for (int i = 0, l = simpleNames.length; i < l; i++) { + if (includes(simpleNames[i])) { + if (PHPBuilder.DEBUG) + System.out.println("Found match in well known package to " + new String(simpleNames[i])); //$NON-NLS-1$ + return true; + } + } + } else { + for (int i = 0, l = qualifiedNames.length; i < l; i++) { + char[][] qualifiedName = qualifiedNames[i]; + if (qualifiedName.length == 1 ? includes(qualifiedName[0]) : includes(qualifiedName)) { + if (PHPBuilder.DEBUG) + System.out.println("Found well known match in " + CharOperation.toString(qualifiedName)); //$NON-NLS-1$ + return true; + } + } + } + } else { + for (int i = 0, l = simpleNames.length; i < l; i++) { + if (includes(simpleNames[i])) { + for (int j = 0, m = qualifiedNames.length; j < m; j++) { + char[][] qualifiedName = qualifiedNames[j]; + if (qualifiedName.length == 1 ? includes(qualifiedName[0]) : includes(qualifiedName)) { + if (PHPBuilder.DEBUG) + System.out.println("Found match in " + CharOperation.toString(qualifiedName) //$NON-NLS-1$ + + " to " + new String(simpleNames[i])); //$NON-NLS-1$ + return true; + } + } + return false; + } + } + } + return false; +} + + +// When any type is compiled, its methods are verified for certain problems +// the MethodVerifier requests 3 well known types which end up in the reference collection +// having WellKnownQualifiedNames & WellKnownSimpleNames, saves every type 40 bytes +// NOTE: These collections are sorted by length +static final char[][][] WellKnownQualifiedNames = new char[][][] { + TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION, + TypeConstants.JAVA_LANG_THROWABLE, + TypeConstants.JAVA_LANG_OBJECT, + TypeConstants.JAVA_LANG, + new char[][] {TypeConstants.JAVA}, + new char[][] {new char[] {'o', 'r', 'g'}}, + new char[][] {new char[] {'c', 'o', 'm'}}, + CharOperation.NO_CHAR_CHAR}; // default package +static final char[][] WellKnownSimpleNames = new char[][] { + TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION[2], + TypeConstants.JAVA_LANG_THROWABLE[2], + TypeConstants.JAVA_LANG_OBJECT[2], + TypeConstants.JAVA, + TypeConstants.LANG, + new char[] {'o', 'r', 'g'}, + new char[] {'c', 'o', 'm'}}; + +static final char[][][] EmptyQualifiedNames = new char[0][][]; +static final char[][] EmptySimpleNames = CharOperation.NO_CHAR_CHAR; + +// each array contains qualified char[][], one for size 2, 3, 4, 5, 6, 7 & the rest +static final int MaxQualifiedNames = 7; +static ArrayList[] InternedQualifiedNames = new ArrayList[MaxQualifiedNames]; +// each array contains simple char[], one for size 1 to 29 & the rest +static final int MaxSimpleNames = 30; +static ArrayList[] InternedSimpleNames = new ArrayList[MaxSimpleNames]; +static { + for (int i = 0; i < MaxQualifiedNames; i++) + InternedQualifiedNames[i] = new ArrayList(37); + for (int i = 0; i < MaxSimpleNames; i++) + InternedSimpleNames[i] = new ArrayList(11); +} + +static char[][][] internQualifiedNames(ArrayList qualifiedStrings) { + if (qualifiedStrings == null) return EmptyQualifiedNames; + int length = qualifiedStrings.size(); + if (length == 0) return EmptyQualifiedNames; + + char[][][] result = new char[length][][]; + for (int i = 0; i < length; i++) + result[i] = CharOperation.splitOn('/', ((String) qualifiedStrings.get(i)).toCharArray()); + return internQualifiedNames(result); +} + +static char[][][] internQualifiedNames(char[][][] qualifiedNames) { + if (qualifiedNames == null) return EmptyQualifiedNames; + int length = qualifiedNames.length; + if (length == 0) return EmptyQualifiedNames; + + char[][][] keepers = new char[length][][]; + int index = 0; + next : for (int i = 0; i < length; i++) { + char[][] qualifiedName = qualifiedNames[i]; + int qLength = qualifiedName.length; + for (int j = 0, m = WellKnownQualifiedNames.length; j < m; j++) { + char[][] wellKnownName = WellKnownQualifiedNames[j]; + if (qLength > wellKnownName.length) + break; // all remaining well known names are shorter + if (CharOperation.equals(qualifiedName, wellKnownName)) + continue next; + } + + // InternedQualifiedNames[0] is for the rest (> 7 & 1) + // InternedQualifiedNames[1] is for size 2... + // InternedQualifiedNames[6] is for size 7 + ArrayList internedNames = InternedQualifiedNames[qLength <= MaxQualifiedNames ? qLength - 1 : 0]; + for (int j = 0, m = internedNames.size(); j < m; j++) { + char[][] internedName = (char[][]) internedNames.get(j); + if (CharOperation.equals(qualifiedName, internedName)) { + keepers[index++] = internedName; + continue next; + } + } + qualifiedName = internSimpleNames(qualifiedName, false); + internedNames.add(qualifiedName); + keepers[index++] = qualifiedName; + } + if (length > index) { + if (length == 0) return EmptyQualifiedNames; + System.arraycopy(keepers, 0, keepers = new char[index][][], 0, index); + } + return keepers; +} + +static char[][] internSimpleNames(ArrayList simpleStrings) { + if (simpleStrings == null) return EmptySimpleNames; + int length = simpleStrings.size(); + if (length == 0) return EmptySimpleNames; + + char[][] result = new char[length][]; + for (int i = 0; i < length; i++) + result[i] = ((String) simpleStrings.get(i)).toCharArray(); + return internSimpleNames(result, true); +} + +static char[][] internSimpleNames(char[][] simpleNames, boolean removeWellKnown) { + if (simpleNames == null) return EmptySimpleNames; + int length = simpleNames.length; + if (length == 0) return EmptySimpleNames; + + char[][] keepers = new char[length][]; + int index = 0; + next : for (int i = 0; i < length; i++) { + char[] name = simpleNames[i]; + int sLength = name.length; + for (int j = 0, m = WellKnownSimpleNames.length; j < m; j++) { + char[] wellKnownName = WellKnownSimpleNames[j]; + if (sLength > wellKnownName.length) + break; // all remaining well known names are shorter + if (CharOperation.equals(name, wellKnownName)) { + if (!removeWellKnown) + keepers[index++] = WellKnownSimpleNames[j]; + continue next; + } + } + + // InternedSimpleNames[0] is for the rest (> 29) + // InternedSimpleNames[1] is for size 1... + // InternedSimpleNames[29] is for size 29 + ArrayList internedNames = InternedSimpleNames[sLength < MaxSimpleNames ? sLength : 0]; + for (int j = 0, m = internedNames.size(); j < m; j++) { + char[] internedName = (char[]) internedNames.get(j); + if (CharOperation.equals(name, internedName)) { + keepers[index++] = internedName; + continue next; + } + } + internedNames.add(name); + keepers[index++] = name; + } + if (length > index) { + if (index == 0) return EmptySimpleNames; + System.arraycopy(keepers, 0, keepers = new char[index][], 0, index); + } + return keepers; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/SourceFile.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/SourceFile.java new file mode 100644 index 0000000..279708e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/SourceFile.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; +import net.sourceforge.phpdt.internal.core.Util; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +public class SourceFile implements ICompilationUnit { + +IFile resource; +ClasspathMultiDirectory sourceLocation; +String initialTypeName; +String encoding; + +public SourceFile(IFile resource, ClasspathMultiDirectory sourceLocation, String encoding) { + this.resource = resource; + this.sourceLocation = sourceLocation; + this.initialTypeName = extractTypeName(); + this.encoding = encoding; +} + +public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SourceFile)) return false; + + SourceFile f = (SourceFile) o; + return sourceLocation == f.sourceLocation && resource.getFullPath().equals(f.resource.getFullPath()); +} + +String extractTypeName() { + // answer a String with the qualified type name for the source file in the form: 'p1/p2/A' + IPath fullPath = resource.getFullPath(); + int resourceSegmentCount = fullPath.segmentCount(); + int sourceFolderSegmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount(); + int charCount = (resourceSegmentCount - sourceFolderSegmentCount - 1) - 5; // length of ".java" + for (int i = sourceFolderSegmentCount; i < resourceSegmentCount; i++) + charCount += fullPath.segment(i).length(); + + char[] result = new char[charCount]; + int offset = 0; + resourceSegmentCount--; // deal with the last segment separately + for (int i = sourceFolderSegmentCount; i < resourceSegmentCount; i++) { + String segment = fullPath.segment(i); + int size = segment.length(); + segment.getChars(0, size, result, offset); + offset += size; + result[offset++] = '/'; + } + String segment = fullPath.segment(resourceSegmentCount); + int size = segment.length() - 5; // length of ".java" + segment.getChars(0, size, result, offset); + return new String(result); +} + +public char[] getContents() { + + try { + return Util.getResourceContentsAsCharArray(resource, this.encoding); + } catch (CoreException e) { + throw new AbortCompilation(true, new MissingSourceFileException(resource.getFullPath().toString())); + } +} + +public char[] getFileName() { + return resource.getFullPath().toString().toCharArray(); // do not know what you want to return here +} + +public char[] getMainTypeName() { + char[] typeName = initialTypeName.toCharArray(); + int lastIndex = CharOperation.lastIndexOf('/', typeName); + return CharOperation.subarray(typeName, lastIndex + 1, -1); +} + +public char[][] getPackageName() { + char[] typeName = initialTypeName.toCharArray(); + int lastIndex = CharOperation.lastIndexOf('/', typeName); + return CharOperation.splitOn('/', typeName, 0, lastIndex); +} + +String typeLocator() { + return resource.getProjectRelativePath().toString(); +} + +public String toString() { + return "SourceFile[" //$NON-NLS-1$ + + resource.getFullPath() + "]"; //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/State.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/State.java new file mode 100644 index 0000000..057d387 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/State.java @@ -0,0 +1,613 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +public class State { +// NOTE: this state cannot contain types that are not defined in this project + +String javaProjectName; +ClasspathMultiDirectory[] sourceLocations; +//ClasspathLocation[] binaryLocations; +// keyed by the project relative path of the type (ie. "src1/p1/p2/A.java"), value is a ReferenceCollection or an AdditionalTypeCollection +SimpleLookupTable references; +// keyed by qualified type name "p1/p2/A", value is the project relative path which defines this type "src1/p1/p2/A.java" +SimpleLookupTable typeLocators; + +int buildNumber; +long lastStructuralBuildTime; +SimpleLookupTable structuralBuildTimes; + +private String[] knownPackageNames; // of the form "p1/p2" + +static final byte VERSION = 0x0007; + +static final byte SOURCE_FOLDER = 1; +static final byte BINARY_FOLDER = 2; +static final byte EXTERNAL_JAR = 3; +static final byte INTERNAL_JAR = 4; + +State() { +} + +protected State(PHPBuilder javaBuilder) { + this.knownPackageNames = null; + this.javaProjectName = javaBuilder.currentProject.getName(); + this.sourceLocations = javaBuilder.nameEnvironment.sourceLocations; +// this.binaryLocations = javaBuilder.nameEnvironment.binaryLocations; + this.references = new SimpleLookupTable(7); + this.typeLocators = new SimpleLookupTable(7); + + this.buildNumber = 0; // indicates a full build + this.lastStructuralBuildTime = System.currentTimeMillis(); + this.structuralBuildTimes = new SimpleLookupTable(3); +} + +void copyFrom(State lastState) { + try { + this.knownPackageNames = null; + this.buildNumber = lastState.buildNumber + 1; + this.lastStructuralBuildTime = lastState.lastStructuralBuildTime; + this.references = (SimpleLookupTable) lastState.references.clone(); + this.typeLocators = (SimpleLookupTable) lastState.typeLocators.clone(); + } catch (CloneNotSupportedException e) { + this.references = new SimpleLookupTable(lastState.references.elementSize); + Object[] keyTable = lastState.references.keyTable; + Object[] valueTable = lastState.references.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) + if (keyTable[i] != null) + this.references.put(keyTable[i], valueTable[i]); + + this.typeLocators = new SimpleLookupTable(lastState.typeLocators.elementSize); + keyTable = lastState.typeLocators.keyTable; + valueTable = lastState.typeLocators.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) + if (keyTable[i] != null) + this.typeLocators.put(keyTable[i], valueTable[i]); + } +} + +char[][] getDefinedTypeNamesFor(String typeLocator) { + Object c = references.get(typeLocator); + if (c instanceof AdditionalTypeCollection) + return ((AdditionalTypeCollection) c).definedTypeNames; + return null; // means only one type is defined with the same name as the file... saves space +} + +boolean isDuplicateLocator(String qualifiedTypeName, String typeLocator) { + String existing = (String) typeLocators.get(qualifiedTypeName); + return existing != null && !existing.equals(typeLocator); +} + +boolean isKnownPackage(String qualifiedPackageName) { + if (knownPackageNames == null) { + ArrayList names = new ArrayList(typeLocators.elementSize); + Object[] keyTable = typeLocators.keyTable; + for (int i = 0, l = keyTable.length; i < l; i++) { + if (keyTable[i] != null) { + String packageName = (String) keyTable[i]; // is a type name of the form p1/p2/A + int last = packageName.lastIndexOf('/'); + packageName = last == -1 ? null : packageName.substring(0, last); + while (packageName != null && !names.contains(packageName)) { + names.add(packageName); + last = packageName.lastIndexOf('/'); + packageName = last == -1 ? null : packageName.substring(0, last); + } + } + } + knownPackageNames = new String[names.size()]; + names.toArray(knownPackageNames); + } + for (int i = 0, l = knownPackageNames.length; i < l; i++) + if (knownPackageNames[i].equals(qualifiedPackageName)) + return true; + return false; +} + +void record(String typeLocator, char[][][] qualifiedRefs, char[][] simpleRefs, char[] mainTypeName, ArrayList typeNames) { + if (typeNames.size() == 1 && CharOperation.equals(mainTypeName, (char[]) typeNames.get(0))) { + references.put(typeLocator, new ReferenceCollection(qualifiedRefs, simpleRefs)); + } else { + char[][] definedTypeNames = new char[typeNames.size()][]; // can be empty when no types are defined + typeNames.toArray(definedTypeNames); + references.put(typeLocator, new AdditionalTypeCollection(definedTypeNames, qualifiedRefs, simpleRefs)); + } +} + +void recordLocatorForType(String qualifiedTypeName, String typeLocator) { + this.knownPackageNames = null; + typeLocators.put(qualifiedTypeName, typeLocator); +} + +void recordStructuralDependency(IProject prereqProject, State prereqState) { + if (prereqState != null) + structuralBuildTimes.put(prereqProject.getName(), new Long(prereqState.lastStructuralBuildTime)); +} + +void removeLocator(String typeLocatorToRemove) { + this.knownPackageNames = null; + references.removeKey(typeLocatorToRemove); + typeLocators.removeValue(typeLocatorToRemove); +} + +void removePackage(IResourceDelta sourceDelta) { + IResource resource = sourceDelta.getResource(); + switch(resource.getType()) { + case IResource.FOLDER : + IResourceDelta[] children = sourceDelta.getAffectedChildren(); + for (int i = 0, l = children.length; i < l; i++) + removePackage(children[i]); + return; + case IResource.FILE : + IPath typeLocatorPath = resource.getProjectRelativePath(); + if (Util.isJavaFileName(typeLocatorPath.lastSegment())) + removeLocator(typeLocatorPath.toString()); + } +} + +void removeQualifiedTypeName(String qualifiedTypeNameToRemove) { + this.knownPackageNames = null; + typeLocators.removeKey(qualifiedTypeNameToRemove); +} + +static State read(IProject project, DataInputStream in) throws IOException { + if (PHPBuilder.DEBUG) + System.out.println("About to read state..."); //$NON-NLS-1$ + if (VERSION != in.readByte()) { + if (PHPBuilder.DEBUG) + System.out.println("Found non-compatible state version... answered null"); //$NON-NLS-1$ + return null; + } + + State newState = new State(); + newState.javaProjectName = in.readUTF(); + if (!project.getName().equals(newState.javaProjectName)) { + if (PHPBuilder.DEBUG) + System.out.println("Project's name does not match... answered null"); //$NON-NLS-1$ + return null; + } + newState.buildNumber = in.readInt(); + newState.lastStructuralBuildTime = in.readLong(); + + int length = in.readInt(); + newState.sourceLocations = new ClasspathMultiDirectory[0]; +// newState.sourceLocations = new ClasspathMultiDirectory[length]; +// for (int i = 0; i < length; i++) { +// IContainer sourceFolder = project, outputFolder = project; +// String folderName; +// if ((folderName = in.readUTF()).length() > 0) sourceFolder = project.getFolder(folderName); +// if ((folderName = in.readUTF()).length() > 0) outputFolder = project.getFolder(folderName); +// ClasspathMultiDirectory md = +// (ClasspathMultiDirectory) ClasspathLocation.forSourceFolder(sourceFolder, outputFolder, readNames(in)); +// if (in.readBoolean()) +// md.hasIndependentOutputFolder = true; +// newState.sourceLocations[i] = md; +// } + + length = in.readInt(); +// newState.binaryLocations = new ClasspathLocation[length]; +// IWorkspaceRoot root = project.getWorkspace().getRoot(); +// for (int i = 0; i < length; i++) { +// switch (in.readByte()) { +// case SOURCE_FOLDER : +// newState.binaryLocations[i] = newState.sourceLocations[in.readInt()]; +// break; +// case BINARY_FOLDER : +// IPath path = new Path(in.readUTF()); +// IContainer outputFolder = path.segmentCount() == 1 +// ? (IContainer) root.getProject(path.toString()) +// : (IContainer) root.getFolder(path); +// newState.binaryLocations[i] = ClasspathLocation.forBinaryFolder(outputFolder, in.readBoolean()); +// break; +// case EXTERNAL_JAR : +// newState.binaryLocations[i] = ClasspathLocation.forLibrary(in.readUTF()); +// break; +// case INTERNAL_JAR : +// newState.binaryLocations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF()))); +// } +// } + + newState.structuralBuildTimes = new SimpleLookupTable(length = in.readInt()); + for (int i = 0; i < length; i++) + newState.structuralBuildTimes.put(in.readUTF(), new Long(in.readLong())); + + String[] internedTypeLocators = new String[length = in.readInt()]; + for (int i = 0; i < length; i++) + internedTypeLocators[i] = in.readUTF(); + + newState.typeLocators = new SimpleLookupTable(length = in.readInt()); + for (int i = 0; i < length; i++) + newState.typeLocators.put(in.readUTF(), internedTypeLocators[in.readInt()]); + + char[][] internedSimpleNames = ReferenceCollection.internSimpleNames(readNames(in), false); + char[][][] internedQualifiedNames = new char[length = in.readInt()][][]; + for (int i = 0; i < length; i++) { + int qLength = in.readInt(); + char[][] qName = new char[qLength][]; + for (int j = 0; j < qLength; j++) + qName[j] = internedSimpleNames[in.readInt()]; + internedQualifiedNames[i] = qName; + } + internedQualifiedNames = ReferenceCollection.internQualifiedNames(internedQualifiedNames); + + newState.references = new SimpleLookupTable(length = in.readInt()); + for (int i = 0; i < length; i++) { + String typeLocator = internedTypeLocators[in.readInt()]; + ReferenceCollection collection = null; + switch (in.readByte()) { + case 1 : + char[][] additionalTypeNames = readNames(in); + char[][][] qualifiedNames = new char[in.readInt()][][]; + for (int j = 0, m = qualifiedNames.length; j < m; j++) + qualifiedNames[j] = internedQualifiedNames[in.readInt()]; + char[][] simpleNames = new char[in.readInt()][]; + for (int j = 0, m = simpleNames.length; j < m; j++) + simpleNames[j] = internedSimpleNames[in.readInt()]; + collection = new AdditionalTypeCollection(additionalTypeNames, qualifiedNames, simpleNames); + break; + case 2 : + char[][][] qNames = new char[in.readInt()][][]; + for (int j = 0, m = qNames.length; j < m; j++) + qNames[j] = internedQualifiedNames[in.readInt()]; + char[][] sNames = new char[in.readInt()][]; + for (int j = 0, m = sNames.length; j < m; j++) + sNames[j] = internedSimpleNames[in.readInt()]; + collection = new ReferenceCollection(qNames, sNames); + } + newState.references.put(typeLocator, collection); + } + if (PHPBuilder.DEBUG) + System.out.println("Successfully read state for " + newState.javaProjectName); //$NON-NLS-1$ + return newState; +} + +private static char[][] readNames(DataInputStream in) throws IOException { + int length = in.readInt(); + char[][] names = new char[length][]; + for (int i = 0; i < length; i++) { + int nLength = in.readInt(); + char[] name = new char[nLength]; + for (int j = 0; j < nLength; j++) + name[j] = in.readChar(); + names[i] = name; + } + return names; +} + +void tagAsNoopBuild() { + this.buildNumber = -1; // tag the project since it has no source folders and can be skipped +} + +boolean wasNoopBuild() { + return buildNumber == -1; +} + +void tagAsStructurallyChanged() { + this.lastStructuralBuildTime = System.currentTimeMillis(); +} + +boolean wasStructurallyChanged(IProject prereqProject, State prereqState) { + if (prereqState != null) { + Object o = structuralBuildTimes.get(prereqProject.getName()); + long previous = o == null ? 0 : ((Long) o).longValue(); + if (previous == prereqState.lastStructuralBuildTime) return false; + } + return true; +} + +void write(DataOutputStream out) throws IOException { + int length; + Object[] keyTable; + Object[] valueTable; + +/* + * byte VERSION + * String project name + * int build number + * int last structural build number +*/ + out.writeByte(VERSION); + out.writeUTF(javaProjectName); + out.writeInt(buildNumber); + out.writeLong(lastStructuralBuildTime); + +/* + * ClasspathMultiDirectory[] + * int id + * String path(s) +*/ + out.writeInt(length = sourceLocations.length); + for (int i = 0; i < length; i++) { + ClasspathMultiDirectory md = sourceLocations[i]; + out.writeUTF(md.sourceFolder.getProjectRelativePath().toString()); + out.writeUTF(md.binaryFolder.getProjectRelativePath().toString()); + writeNames(md.exclusionPatterns, out); + out.writeBoolean(md.hasIndependentOutputFolder); + } + +/* + * ClasspathLocation[] + * int id + * String path(s) +*/ +// out.writeInt(length = binaryLocations.length); +// next : for (int i = 0; i < length; i++) { +// ClasspathLocation c = binaryLocations[i]; +// if (c instanceof ClasspathMultiDirectory) { +// out.writeByte(SOURCE_FOLDER); +// for (int j = 0, m = sourceLocations.length; j < m; j++) { +// if (sourceLocations[j] == c) { +// out.writeInt(j); +// continue next; +// } +// } +// } else if (c instanceof ClasspathDirectory) { +// out.writeByte(BINARY_FOLDER); +// ClasspathDirectory cd = (ClasspathDirectory) c; +// out.writeUTF(cd.binaryFolder.getFullPath().toString()); +// out.writeBoolean(cd.isOutputFolder); +// } else { +// ClasspathJar jar = (ClasspathJar) c; +// if (jar.resource == null) { +// out.writeByte(EXTERNAL_JAR); +// out.writeUTF(jar.zipFilename); +// } else { +// out.writeByte(INTERNAL_JAR); +// out.writeUTF(jar.resource.getFullPath().toString()); +// } +// } +// } + +/* + * Structural build numbers table + * String prereq project name + * int last structural build number +*/ + out.writeInt(length = structuralBuildTimes.elementSize); + if (length > 0) { + keyTable = structuralBuildTimes.keyTable; + valueTable = structuralBuildTimes.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) { + if (keyTable[i] != null) { + length--; + out.writeUTF((String) keyTable[i]); + out.writeLong(((Long) valueTable[i]).longValue()); + } + } + if (PHPBuilder.DEBUG && length != 0) + System.out.println("structuralBuildNumbers table is inconsistent"); //$NON-NLS-1$ + } + +/* + * String[] Interned type locators + */ + out.writeInt(length = references.elementSize); + ArrayList internedTypeLocators = new ArrayList(length); + if (length > 0) { + keyTable = references.keyTable; + for (int i = 0, l = keyTable.length; i < l; i++) { + if (keyTable[i] != null) { + length--; + String key = (String) keyTable[i]; + out.writeUTF(key); + internedTypeLocators.add(key); + } + } + if (PHPBuilder.DEBUG && length != 0) + System.out.println("references table is inconsistent"); //$NON-NLS-1$ + } + +/* + * Type locators table + * String type name + * int interned locator id + */ + out.writeInt(length = typeLocators.elementSize); + if (length > 0) { + keyTable = typeLocators.keyTable; + valueTable = typeLocators.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) { + if (keyTable[i] != null) { + length--; + out.writeUTF((String) keyTable[i]); + out.writeInt(internedTypeLocators.indexOf((String) valueTable[i])); + } + } + if (PHPBuilder.DEBUG && length != 0) + System.out.println("typeLocators table is inconsistent"); //$NON-NLS-1$ + } + +/* + * char[][][] Interned qualified names + * char[][] Interned simple names + */ + ArrayList internedQualifiedNames = new ArrayList(31); + ArrayList internedSimpleNames = new ArrayList(31); + valueTable = references.valueTable; + for (int i = 0, l = valueTable.length; i < l; i++) { + if (valueTable[i] != null) { + ReferenceCollection collection = (ReferenceCollection) valueTable[i]; + char[][][] qNames = collection.qualifiedNameReferences; + for (int j = 0, m = qNames.length; j < m; j++) { + char[][] qName = qNames[j]; + if (!internedQualifiedNames.contains(qName)) { // remember the names have been interned + internedQualifiedNames.add(qName); + for (int k = 0, n = qName.length; k < n; k++) { + char[] sName = qName[k]; + if (!internedSimpleNames.contains(sName)) // remember the names have been interned + internedSimpleNames.add(sName); + } + } + } + char[][] sNames = collection.simpleNameReferences; + for (int j = 0, m = sNames.length; j < m; j++) { + char[] sName = sNames[j]; + if (!internedSimpleNames.contains(sName)) // remember the names have been interned + internedSimpleNames.add(sName); + } + } + } + char[][] internedArray = new char[internedSimpleNames.size()][]; + internedSimpleNames.toArray(internedArray); + writeNames(internedArray, out); + // now write the interned qualified names as arrays of interned simple names + out.writeInt(length = internedQualifiedNames.size()); + for (int i = 0; i < length; i++) { + char[][] qName = (char[][]) internedQualifiedNames.get(i); + int qLength = qName.length; + out.writeInt(qLength); + for (int j = 0; j < qLength; j++) + out.writeInt(internedSimpleNames.indexOf(qName[j])); + } + +/* + * References table + * int interned locator id + * ReferenceCollection +*/ + out.writeInt(length = references.elementSize); + if (length > 0) { + keyTable = references.keyTable; + for (int i = 0, l = keyTable.length; i < l; i++) { + if (keyTable[i] != null) { + length--; + out.writeInt(internedTypeLocators.indexOf((String) keyTable[i])); + ReferenceCollection collection = (ReferenceCollection) valueTable[i]; + if (collection instanceof AdditionalTypeCollection) { + out.writeByte(1); + AdditionalTypeCollection atc = (AdditionalTypeCollection) collection; + writeNames(atc.definedTypeNames, out); + } else { + out.writeByte(2); + } + char[][][] qNames = collection.qualifiedNameReferences; + int qLength = qNames.length; + out.writeInt(qLength); + for (int j = 0; j < qLength; j++) + out.writeInt(internedQualifiedNames.indexOf(qNames[j])); + char[][] sNames = collection.simpleNameReferences; + int sLength = sNames.length; + out.writeInt(sLength); + for (int j = 0; j < sLength; j++) + out.writeInt(internedSimpleNames.indexOf(sNames[j])); + } + } + if (PHPBuilder.DEBUG && length != 0) + System.out.println("references table is inconsistent"); //$NON-NLS-1$ + } +} + +private void writeNames(char[][] names, DataOutputStream out) throws IOException { + int length = names == null ? 0 : names.length; + out.writeInt(length); + for (int i = 0; i < length; i++) { + char[] name = names[i]; + int nLength = name.length; + out.writeInt(nLength); + for (int j = 0; j < nLength; j++) + out.writeChar(name[j]); + } +} + +/** + * Returns a string representation of the receiver. + */ +public String toString() { + return "State for " + javaProjectName //$NON-NLS-1$ + + " (#" + buildNumber //$NON-NLS-1$ + + " @ " + new Date(lastStructuralBuildTime) //$NON-NLS-1$ + + ")"; //$NON-NLS-1$ +} + +/* Debug helper +void dump() { + System.out.println("State for " + javaProjectName + " (" + buildNumber + " @ " + new Date(lastStructuralBuildTime) + ")"); + System.out.println("\tClass path source locations:"); + for (int i = 0, l = sourceLocations.length; i < l; i++) + System.out.println("\t\t" + sourceLocations[i]); + System.out.println("\tClass path binary locations:"); + for (int i = 0, l = binaryLocations.length; i < l; i++) + System.out.println("\t\t" + binaryLocations[i]); + + System.out.print("\tStructural build numbers table:"); + if (structuralBuildTimes.elementSize == 0) { + System.out.print(" "); + } else { + Object[] keyTable = structuralBuildTimes.keyTable; + Object[] valueTable = structuralBuildTimes.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) + if (keyTable[i] != null) + System.out.print("\n\t\t" + keyTable[i].toString() + " -> " + valueTable[i].toString()); + } + + System.out.print("\tType locators table:"); + if (typeLocators.elementSize == 0) { + System.out.print(" "); + } else { + Object[] keyTable = typeLocators.keyTable; + Object[] valueTable = typeLocators.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) + if (keyTable[i] != null) + System.out.print("\n\t\t" + keyTable[i].toString() + " -> " + valueTable[i].toString()); + } + + System.out.print("\n\tReferences table:"); + if (references.elementSize == 0) { + System.out.print(" "); + } else { + Object[] keyTable = references.keyTable; + Object[] valueTable = references.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) { + if (keyTable[i] != null) { + System.out.print("\n\t\t" + keyTable[i].toString()); + ReferenceCollection c = (ReferenceCollection) valueTable[i]; + char[][][] qRefs = c.qualifiedNameReferences; + System.out.print("\n\t\t\tqualified:"); + if (qRefs.length == 0) + System.out.print(" "); + else for (int j = 0, m = qRefs.length; j < m; j++) + System.out.print(" '" + CharOperation.toString(qRefs[j]) + "'"); + char[][] sRefs = c.simpleNameReferences; + System.out.print("\n\t\t\tsimple:"); + if (sRefs.length == 0) + System.out.print(" "); + else for (int j = 0, m = sRefs.length; j < m; j++) + System.out.print(" " + new String(sRefs[j])); + if (c instanceof AdditionalTypeCollection) { + char[][] names = ((AdditionalTypeCollection) c).definedTypeNames; + System.out.print("\n\t\t\tadditional type names:"); + for (int j = 0, m = names.length; j < m; j++) + System.out.print(" " + new String(names[j])); + } + } + } + } + System.out.print("\n\n"); +} +*/ +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/WorkQueue.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/WorkQueue.java new file mode 100644 index 0000000..8d76a90 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/builder/WorkQueue.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.builder; + +import java.util.*; + +public class WorkQueue { + +ArrayList needsCompileList; +ArrayList compiledList; + +public WorkQueue() { + this.needsCompileList = new ArrayList(11); + this.compiledList = new ArrayList(11); +} + +public void add(SourceFile element) { + needsCompileList.add(element); +} + +public void addAll(SourceFile[] elements) { + for (int i = 0, l = elements.length; i < l; i++) + add(elements[i]); +} + +public void clear() { + this.needsCompileList.clear(); + this.compiledList.clear(); +} + +public void finished(SourceFile element) { + needsCompileList.remove(element); + compiledList.add(element); +} + +public boolean isCompiled(SourceFile element) { + return compiledList.contains(element); +} + +public boolean isWaiting(SourceFile element) { + return needsCompileList.contains(element); +} + +public String toString() { + return "WorkQueue: " + needsCompileList; //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/AbstractDOMBuilder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/AbstractDOMBuilder.java new file mode 100644 index 0000000..40fe1be --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/AbstractDOMBuilder.java @@ -0,0 +1,215 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import java.util.Stack; + +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.internal.core.util.ReferenceInfoAdapter; + +/** + * An abstract DOM builder that contains shared functionality of DOMBuilder and SimpleDOMBuilder. + */ +public class AbstractDOMBuilder extends ReferenceInfoAdapter implements ILineStartFinder { + /** + * Set to true when an error is encounterd while + * fuzzy parsing + */ + protected boolean fAbort; + + /** + * True when a compilation unit is being constructed. + * False when any other type of document fragment is + * being constructed. + */ + protected boolean fBuildingCU = false; + + /** + * True when a compilation unit or type is being + * constructed. False when any other type of document + * fragment is being constructed. + */ + protected boolean fBuildingType= false; + + /** + * The String on which the JDOM is being created. + */ + protected char[] fDocument= null; + + /** + * The source positions of all of the line separators in the document. + */ + protected int[] fLineStartPositions = new int[] { 0 }; + + /** + * A stack of enclosing scopes used when constructing + * a compilation unit or type. The top of the stack + * is the document fragment that children are added to. + */ + protected Stack fStack = null; + + /** + * The number of fields constructed in the current + * document. This is used when building a single + * field document fragment, since the DOMBuilder only + * accepts documents with one field declaration. + */ + protected int fFieldCount; + + /** + * The current node being constructed. + */ + protected DOMNode fNode; +/** + * AbstractDOMBuilder constructor. + */ +public AbstractDOMBuilder() { + super(); +} +/** + * Accepts the line separator table and converts it into a line start table. + * + *

        A line separator might corresponds to several characters in the source. + * + * @see IDocumentElementRequestor#acceptLineSeparatorPositions(int[]) + */ +public void acceptLineSeparatorPositions(int[] positions) { + if (positions != null) { + int length = positions.length; + if (length > 0) { + fLineStartPositions = new int[length + 1]; + fLineStartPositions[0] = 0; + int documentLength = fDocument.length; + for (int i = 0; i < length; i++) { + int iPlusOne = i + 1; + int positionPlusOne = positions[i] + 1; + if (positionPlusOne < documentLength) { + if (iPlusOne < length) { + // more separators + fLineStartPositions[iPlusOne] = positionPlusOne; + } else { + // no more separators + if (fDocument[positionPlusOne] == '\n') { + fLineStartPositions[iPlusOne] = positionPlusOne + 1; + } else { + fLineStartPositions[iPlusOne] = positionPlusOne; + } + } + } else { + fLineStartPositions[iPlusOne] = positionPlusOne; + } + } + } + } +} +/** + * Does nothing. + */ +public void acceptProblem(IProblem problem) {} //TODO: (olivier) unused? +/** + * Adds the given node to the current enclosing scope, building the JDOM + * tree. Nodes are only added to an enclosing scope when a compilation unit or type + * is being built (since those are the only nodes that have children). + * + *

        NOTE: nodes are added to the JDOM via the method #basicAddChild such that + * the nodes in the newly created JDOM are not fragmented. + */ +protected void addChild(IDOMNode child) { + if (fStack.size() > 0) { + DOMNode parent = (DOMNode) fStack.peek(); + if (fBuildingCU || fBuildingType) { + parent.basicAddChild(child); + } + } +} +/** + * @see IDOMFactory#createCompilationUnit(String, String) + */ +public IDOMCompilationUnit createCompilationUnit(char[] contents, char[] name) { + return createCompilationUnit(new CompilationUnit(contents, name)); +} +/** + * @see IDOMFactory#createCompilationUnit(String, String) + */ +public IDOMCompilationUnit createCompilationUnit(ICompilationUnit compilationUnit) { + if (fAbort) { + return null; + } + fNode.normalize(this); + return (IDOMCompilationUnit)fNode; +} +/** + * @see IDocumentElementRequestor#enterClass(int, int[], int, int, int, char[], int, int, char[], int, int, char[][], int[], int[], int) + */ +public void enterCompilationUnit() { + if (fBuildingCU) { + IDOMCompilationUnit cu= new DOMCompilationUnit(fDocument, new int[] {0, fDocument.length - 1}); + fStack.push(cu); + } +} +/** + * Finishes the configuration of the compilation unit DOM object which + * was created by a previous enterCompilationUnit call. + * + * @see IDocumentElementRequestor#exitCompilationUnit(int) + */ +public void exitCompilationUnit(int declarationEnd) { + DOMCompilationUnit cu = (DOMCompilationUnit) fStack.pop(); + cu.setSourceRangeEnd(declarationEnd); + fNode = cu; +} +/** + * Finishes the configuration of the class and interface DOM objects. + * + * @param bodyEnd - a source position corresponding to the closing bracket of the class + * @param declarationEnd - a source position corresponding to the end of the class + * declaration. This can include whitespace and comments following the closing bracket. + */ +protected void exitType(int bodyEnd, int declarationEnd) { + DOMType type = (DOMType)fStack.pop(); + type.setSourceRangeEnd(declarationEnd); + type.setCloseBodyRangeStart(bodyEnd); + type.setCloseBodyRangeEnd(bodyEnd); + fNode = type; +} +/** + * @see ILineStartFinder#getLineStart(int) + */ +public int getLineStart(int position) { + int lineSeparatorCount = fLineStartPositions.length; + // reverse traversal intentional. + for(int i = lineSeparatorCount - 1; i >= 0; i--) { + if (fLineStartPositions[i] <= position) + return fLineStartPositions[i]; + } + return 0; +} +/** + * Initializes the builder to create a document fragment. + * + * @param sourceCode - the document containing the source code to be analyzed + * @param buildingCompilationUnit - true if a the document is being analyzed to + * create a compilation unit, otherwise false + * @param buildingType - true if the document is being analyzed to create a + * type or compilation unit + */ +protected void initializeBuild(char[] sourceCode, boolean buildingCompilationUnit, boolean buildingType) { + fBuildingCU = buildingCompilationUnit; + fBuildingType = buildingType; + fStack = new Stack(); + fDocument = sourceCode; + fFieldCount = 0; + fAbort = false; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/CompilationUnit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/CompilationUnit.java new file mode 100644 index 0000000..dcb38a5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/CompilationUnit.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; + +/** + * Implements a very simple version of the ICompilationUnit. + * + *

        Please do not use outside of jdom.

        + */ +public class CompilationUnit implements ICompilationUnit { + protected char[] fContents; + protected char[] fFileName; + protected char[] fMainTypeName; +public CompilationUnit(char[] contents, char[] filename) { + fContents = contents; + fFileName = filename; + + String file = new String(filename); + int start = file.lastIndexOf("/") + 1; //$NON-NLS-1$ + if (start == 0 || start < file.lastIndexOf("\\")) //$NON-NLS-1$ + start = file.lastIndexOf("\\") + 1; //$NON-NLS-1$ + + int end = file.lastIndexOf("."); //$NON-NLS-1$ + if (end == -1) + end = file.length(); + + fMainTypeName = file.substring(start, end).toCharArray(); +} +public char[] getContents() { + return fContents; +} +public char[] getFileName() { + return fFileName; +} +public char[] getMainTypeName() { + return fMainTypeName; +} +public char[][] getPackageName() { + return null; +} +public String toString() { + return "CompilationUnit[" + new String(fFileName) + "]"; //$NON-NLS-2$ //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMBuilder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMBuilder.java new file mode 100644 index 0000000..f1faf41 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMBuilder.java @@ -0,0 +1,713 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import java.util.ArrayList; +import java.util.Map; + +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit; +import net.sourceforge.phpdt.core.jdom.IDOMField; +import net.sourceforge.phpdt.core.jdom.IDOMImport; +import net.sourceforge.phpdt.core.jdom.IDOMInitializer; +import net.sourceforge.phpdt.core.jdom.IDOMMethod; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.core.jdom.IDOMPackage; +import net.sourceforge.phpdt.core.jdom.IDOMType; +import net.sourceforge.phpdt.internal.compiler.DocumentElementParser; +import net.sourceforge.phpdt.internal.compiler.IDocumentElementRequestor; +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; +import net.sourceforge.phpdt.internal.compiler.problem.DefaultProblemFactory; +import net.sourceforge.phpdt.internal.core.util.CharArrayOps; +import net.sourceforge.phpeclipse.PHPCore; + +/** + * The DOMBuilder constructs each type of JDOM document fragment, + * for the DOMFactory. The DOMBuilder has been separated from the + * DOMFactory to hide the implmentation of node creation and the + * public Requestor API methods. + * + */ + +public class DOMBuilder extends AbstractDOMBuilder implements IDocumentElementRequestor { + + /** + * True when parsing a single member - ignore any problems + * encountered after the member. + */ + protected boolean fBuildingSingleMember= false; + + /** + * True when the single member being built has been + * exited. + */ + protected boolean fFinishedSingleMember = false; + + /** + * Collection of multiple fields in one declaration + */ + protected ArrayList fFields; + + Map options = PHPCore.getOptions(); + +/** + * Creates a new DOMBuilder + */ +public DOMBuilder() {} +/** + * @see IDocumentElementRequestor#acceptImport(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, int nameStartPosition, boolean onDemand) + */ +public void acceptImport(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, + int nameStart, boolean onDemand) { + int[] sourceRange = {declarationStart, declarationEnd}; + int[] nameRange = {nameStart, declarationEnd - 1}; + + /* See 1FVII1P */ + String importName = CharArrayOps.substring(fDocument, nameRange[0], nameRange[1] + 1 - nameRange[0]); + + fNode= new DOMImport(fDocument, sourceRange, importName, nameRange, onDemand); + addChild(fNode); + if (fBuildingSingleMember) { + fFinishedSingleMember= true; + } +} +/** + * @see IDocumentElementRequestor#acceptInitializer(int declarationStart, int declarationEnd, int[] javaDocPositions, int modifiers, int modifiersStart, int bodyStart, int bodyEnd) + */ +public void acceptInitializer(int declarationStart, int declarationEnd, int[] javaDocPositions, int modifiers, + int modifiersStart, int bodyStart, int bodyEnd) { + int[] sourceRange = {declarationStart, declarationEnd}; + int[] commentRange = {-1, -1}; + if (javaDocPositions != null) { + int length = javaDocPositions.length; + commentRange[0] = javaDocPositions[length - 2]; + commentRange[1] = javaDocPositions[length - 1]; + } + + int[] modifiersRange = {-1, -1}; + if (modifiersStart > declarationStart) { + modifiersRange[0] = modifiersStart; + modifiersRange[1] = bodyStart - 1; + } + fNode = new DOMInitializer(fDocument, sourceRange, commentRange, modifiers, + modifiersRange, bodyStart); + addChild(fNode); + if (fBuildingSingleMember) { + fFinishedSingleMember= true; + } +} +/** + * @see IDocumentElementRequestor#acceptPackage(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, int nameStartPosition) + */ +public void acceptPackage(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, + int nameStartPosition) { + int[] sourceRange = {declarationStart, declarationEnd}; + int[] nameRange = {nameStartPosition, declarationEnd - 1}; + fNode= new DOMPackage(fDocument, sourceRange, CharArrayOps.charToString(name), nameRange); + addChild(fNode); + if (fBuildingSingleMember) { + fFinishedSingleMember= true; + } +} +/** + * Sets the abort flag to true. The parser has encountered an error + * in the current document. If we are only building a single member, and + * we are done with the member - don't worry about the error. + * + * @see IDocumentElementRequestor + */ +public void acceptProblem(IProblem problem){ + if (fBuildingSingleMember && fFinishedSingleMember) { + return; + } + fAbort= true; +} +/** + * Adds the given node to the current enclosing scope, building the JDOM + * tree. Nodes are only added to an enclosing scope when a compilation unit or type + * is being built (since those are the only nodes that have children). + * + *

        NOTE: nodes are added to the JDOM via the method #basicAddChild such that + * the nodes in the newly created JDOM are not fragmented. + */ +protected void addChild(IDOMNode child) { + super.addChild(child); + if (fStack.isEmpty() && fFields != null) { + fFields.add(child); + } +} +/** + * @see IDOMFactory#createCompilationUnit() + */ +public IDOMCompilationUnit createCompilationUnit() { + return new DOMCompilationUnit(); +} +/** + * @see IDOMFactory#createCompilationUnit(String, String) + */ +public IDOMCompilationUnit createCompilationUnit(ICompilationUnit compilationUnit) { + initializeBuild(compilationUnit.getContents(), true, true, false); + getParser(options).parseCompilationUnit(compilationUnit); + return super.createCompilationUnit(compilationUnit); +} +/** + * @see IDOMFactory#createField(String) + */ +//public IDOMField createField(char[] sourceCode) { +// initializeBuild(sourceCode, false, false, true); +// getParser(options).parseField(sourceCode); +// if (fAbort || fNode == null) { +// return null; +// } +// +// // we only accept field declarations with one field +// if (fFieldCount > 1) { +// return null; +// } +// +// fNode.normalize(this); +// return (IDOMField)fNode; +//} +/** + * + */ +//public IDOMField[] createFields(char[] sourceCode) { +// initializeBuild(sourceCode, false, false, false); +// fFields= new ArrayList(); +// getParser(options).parseField(sourceCode); +// if (fAbort) { +// return null; +// } +// IDOMField[] fields= new IDOMField[fFields.size()]; +// fFields.toArray(fields); +// for (int i= 0; i < fields.length; i++) { +// DOMNode node= (DOMNode)fields[i]; +// if (i < (fields.length - 1)) { +// DOMNode next= (DOMNode)fields[i + 1]; +// node.fNextNode= next; +// next.fPreviousNode= node; +// } +// ((DOMNode)fields[i]).normalize(this); +// } +// return fields; +//} +/** + * @see IDOMFactory#createImport() + */ +//public IDOMImport createImport() { +// return new DOMImport(); +//} +/** + * @see IDOMFactory#createImport(String) + */ +//public IDOMImport createImport(char[] sourceCode) { +// initializeBuild(sourceCode, false, false, true); +// getParser(options).parseImport(sourceCode); +// if (fAbort || fNode == null) { +// return null; +// } +// fNode.normalize(this); +// return (IDOMImport)fNode; +//} +/** + * Creates an INITIALIZER document fragment from the given source. + * + * @see IDOMFactory#createInitializer(String) + */ +//public IDOMInitializer createInitializer(char[] sourceCode) { +// initializeBuild(sourceCode, false, false, true); +// getParser(options).parseInitializer(sourceCode); +// if (fAbort || fNode == null || !(fNode instanceof IDOMInitializer)) { +// return null; +// } +// fNode.normalize(this); +// return (IDOMInitializer)fNode; +//} +/** + * @see IDOMFactory#createMethod(String) + */ +//public IDOMMethod createMethod(char[] sourceCode) { +// initializeBuild(sourceCode, false, false, true); +// getParser(options).parseMethod(sourceCode); +// if (fAbort || fNode == null) { +// return null; +// } +// fNode.normalize(this); +// return (IDOMMethod)fNode; +//} +/** + * @see IDOMFactory#createPackage() + */ +public IDOMPackage createPackage() { + return new DOMPackage(); +} +/** + * @see IDOMFactory#createPackage(String) + */ +//public IDOMPackage createPackage(char[] sourceCode) { +// initializeBuild(sourceCode, false, false, true); +// getParser(options).parsePackage(sourceCode); +// if (fAbort || fNode == null) { +// return null; +// } +// fNode.normalize(this); +// return (IDOMPackage)fNode; +//} +/** + * @see IDOMFactory#createType(String) + */ +//public IDOMType createType(char[] sourceCode) { +// initializeBuild(sourceCode, false, true, false); +// getParser(options).parseType(sourceCode); +// if (fAbort) { +// return null; +// } +// if (fNode != null) fNode.normalize(this); +// return (IDOMType)fNode; +//} +/** + * Creates a new DOMMethod and inizializes. + * + * @param declarationStart - a source position corresponding to the first character + * of this constructor declaration + * @param modifiers - the modifiers for this constructor converted to a flag + * @param modifiersStart - a source position corresponding to the first character of the + * textual modifiers + * @param returnType - the name of the return type + * @param returnTypeStart - a source position corresponding to the first character + * of the return type + * @param returnTypeEnd - a source position corresponding to the last character + * of the return type + * @param returnTypeDimensionCount - the array dimension count as supplied on the + * return type (for instance, 'public int[] foo() {}') + * @param name - the name of this constructor + * @param nameStart - a source position corresponding to the first character of the name + * @param nameEnd - a source position corresponding to the last character of the name + * @param parameterTypes - a list of parameter type names + * @param parameterTypeStarts - a list of source positions corresponding to the + * first character of each parameter type name + * @param parameterTypeEnds - a list of source positions corresponding to the + * last character of each parameter type name + * @param parameterNames - a list of the names of the parameters + * @param parametersEnd - a source position corresponding to the last character of the + * parameter list + * @extendedReturnTypeDimensionCount - the array dimension count as supplied on the + * end of the parameter list (for instance, 'public int foo()[] {}') + * @extendedReturnTypeDimensionEnd - a source position corresponding to the last character + * of the extended return type dimension + * @param exceptionTypes - a list of the exception types + * @param exceptionTypeStarts - a list of source positions corresponding to the first + * character of the respective exception types + * @param exceptionTypeEnds - a list of source positions corresponding to the last + * character of the respective exception types + * @param bodyStart - a source position corresponding to the start of this + * constructor's body + */ +protected void enterAbstractMethod(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, + char[] returnType, int returnTypeStart, int returnTypeEnd, int returnTypeDimensionCount, + char[] name, int nameStart, int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts, + int[] parameterTypeEnds, char[][] parameterNames, int[] parameterNameStarts, + int[] parameterNameEnds, int parametersEnd, int extendedReturnTypeDimensionCount, + int extendedReturnTypeDimensionEnd, char[][] exceptionTypes, int[] exceptionTypeStarts, + int[] exceptionTypeEnds, int bodyStart, boolean isConstructor) { + int[] sourceRange = {declarationStart, -1}; // will be fixed up on exit + int[] nameRange = {nameStart, nameEnd}; + int[] commentRange = {-1, -1}; + if (javaDocPositions != null) { + int length = javaDocPositions.length; + commentRange[0] = javaDocPositions[0]; + commentRange[1] = javaDocPositions[length - 1]; + } + int[] modifiersRange = {-1, -1}; + if (modifiersStart > -1) { + modifiersRange[0] = modifiersStart; + if (isConstructor) { + modifiersRange[1] = nameStart - 1; + } else { + modifiersRange[1] = returnTypeStart - 1; + } + } + int[] returnTypeRange = null; + + if (extendedReturnTypeDimensionCount > 0) + returnTypeRange = new int[] {returnTypeStart, returnTypeEnd, + parametersEnd + 1, extendedReturnTypeDimensionEnd}; + else + returnTypeRange = new int[] {returnTypeStart, returnTypeEnd}; + int[] parameterRange = {nameEnd + 1, parametersEnd}; + int[] exceptionRange = {-1, -1}; + if (exceptionTypes != null && exceptionTypes.length > 0) { + int exceptionCount = exceptionTypes.length; + exceptionRange[0] = exceptionTypeStarts[0]; + exceptionRange[1] = exceptionTypeEnds[exceptionCount - 1]; + } + int[] bodyRange = null; + if (exceptionRange[1] > -1) { + bodyRange = new int[] {exceptionRange[1] + 1, -1}; // will be fixed up on exit + } else { + bodyRange = new int[] {parametersEnd + 1, -1}; + } + fNode = new DOMMethod(fDocument, sourceRange, CharArrayOps.charToString(name), nameRange, commentRange, modifiers, + modifiersRange, isConstructor, CharArrayOps.charToString(returnType), returnTypeRange, + CharArrayOps.charcharToString(parameterTypes), + CharArrayOps.charcharToString(parameterNames), + parameterRange, CharArrayOps.charcharToString(exceptionTypes), exceptionRange, bodyRange); + addChild(fNode); + fStack.push(fNode); +} +/** + * @see IDocumentElementRequestor#enterClass( + int declarationStart, + int[] javaDocPositions, + int modifiers, + int modifiersStart, + int classStart, + char[] name, + int nameStart, + int nameEnd, + char[] superclass, + int superclassStart, + int superclassEnd, + char[][] superinterfaces, + int[] superinterfaceStarts, + int[] superinterfaceEnds, + int bodyStart) + */ +public void enterClass(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, int keywordStart, + char[] name, int nameStart, int nameEnd, char[] superclass, int superclassStart, + int superclassEnd, char[][] superinterfaces, int[] superinterfaceStarts, + int[] superinterfaceEnds, int bodyStart) { + + enterType(declarationStart, javaDocPositions, modifiers, modifiersStart, keywordStart, + name, nameStart, nameEnd, superclass, superclassStart, + superclassEnd, superinterfaces, superinterfaceStarts, + superinterfaceEnds, bodyStart, true); +} +/** + * @see IDocumentElementRequestor#enterConstructor( + int declarationStart, + int[] javaDocPositions, + int modifiers, + int modifiersStart, + char[] name, + int nameStart, + int nameEnd, + char[][] parameterTypes, + int [] parameterTypeStarts, + int [] parameterTypeEnds, + char[][] parameterNames, + int [] parameterNameStarts, + int [] parameterNameEnds, + int parametersEnd, + char[][] exceptionTypes, + int [] exceptionTypeStarts, + int [] exceptionTypeEnds, + int bodyStart) + */ +public void enterConstructor(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, + char[] name, int nameStart, int nameEnd, char[][] parameterTypes, + int[] parameterTypeStarts, int[] parameterTypeEnds, char[][] parameterNames, + int[] parameterNameStarts, int[] parameterNameEnds, int parametersEnd, + char[][] exceptionTypes, int[] exceptionTypeStarts, int[] exceptionTypeEnds, + int bodyStart) { + + /* see 1FVIIQZ */ + String nameString = new String(fDocument, nameStart, nameEnd - nameStart); + int openParenPosition = nameString.indexOf('('); + if (openParenPosition > -1) + nameEnd = nameStart + openParenPosition - 1; + + enterAbstractMethod(declarationStart, javaDocPositions, modifiers, modifiersStart, + null, -1, -1, 0, + name, nameStart, nameEnd, parameterTypes, parameterTypeStarts, + parameterTypeEnds, parameterNames, parameterNameStarts, + parameterNameEnds, parametersEnd, 0, + -1, exceptionTypes, exceptionTypeStarts, + exceptionTypeEnds, bodyStart,true); +} +/** + * @see IDocumentElementRequestor#enterField( + int declarationStart, + int[] javaDocPositions, + int modifiers, + int modifiersStart, + char[] type, + int typeStart, + int typeEnd, + int typeDimensionCount, + char[] name, + int nameStart, + int nameEnd, + int extendedTypeDimensionCount, + int extendedTypeDimensionEnd) + */ +public void enterField(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, + char[] type, int typeStart, int typeEnd, int typeDimensionCount, char[] name, + int nameStart, int nameEnd, int extendedTypeDimensionCount, + int extendedTypeDimensionEnd) { + int[] sourceRange = {declarationStart, + (extendedTypeDimensionEnd > nameEnd) ? extendedTypeDimensionEnd : nameEnd}; + int[] nameRange = {nameStart, nameEnd}; + int[] commentRange = {-1, -1}; + if (javaDocPositions != null) { + int length = javaDocPositions.length; + commentRange[0] = javaDocPositions[0]; + commentRange[1] = javaDocPositions[length - 1]; + } + int[] modifiersRange = {-1, -1}; + if (modifiersStart > -1) { + modifiersRange[0] = modifiersStart; + modifiersRange[1] = typeStart - 1; + } + int[] typeRange = {typeStart, typeEnd}; + boolean hasInitializer = false; // fixed on exitField + int[] initializerRange = {-1, -1}; // fixed on exitField + boolean isVariableDeclarator = false; + if (fNode instanceof DOMField) { + DOMField field = (DOMField)fNode; + if (field.fTypeRange[0] == typeStart) + isVariableDeclarator = true; + } + fNode = new DOMField(fDocument, sourceRange, CharArrayOps.charToString(name), nameRange, commentRange, + modifiers, modifiersRange, typeRange, CharArrayOps.charToString(type), hasInitializer, + initializerRange, isVariableDeclarator); + addChild(fNode); + fStack.push(fNode); +} +/** + * @see IDocumentElementRequestor#enterInterface( + int declarationStart, + int[] javaDocPositions, + int modifiers, + int modifiersStart, + int interfaceStart, + char[] name, + int nameStart, + int nameEnd, + char[][] superinterfaces, + int[] superinterfaceStarts, + int[] superinterfaceEnds, + int bodyStart) + */ +public void enterInterface(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, int keywordStart, + char[] name, int nameStart, int nameEnd, char[][] superinterfaces, + int[] superinterfaceStarts, int[] superinterfaceEnds, int bodyStart) { + + enterType(declarationStart, javaDocPositions, modifiers, modifiersStart, keywordStart, + name, nameStart, nameEnd, null, -1, -1, superinterfaces, + superinterfaceStarts, superinterfaceEnds, bodyStart, false); +} +/** + * @see IDocumentElementRequestor#enterMethod( + int declarationStart, + int[] javaDocPositions, + int modifiers, + int modifiersStart, + char[] returnType, + int returnTypeStart, + int returnTypeEnd, + int returnTypeDimensionCount, + char[] name, + int nameStart, + int nameEnd, + char[][] parameterTypes, + int [] parameterTypeStarts, + int [] parameterTypeEnds, + char[][] parameterNames, + int [] parameterNameStarts, + int [] parameterNameEnds, + int parametersEnd, + int extendedReturnTypeDimensionCount, + int extendedReturnTypeDimensionEnd, + char[][] exceptionTypes, + int [] exceptionTypeStarts, + int [] exceptionTypeEnds, + int bodyStart) + */ +public void enterMethod(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, + char[] returnType, int returnTypeStart, int returnTypeEnd, int returnTypeDimensionCount, + char[] name, int nameStart, int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts, + int[] parameterTypeEnds, char[][] parameterNames, int[] parameterNameStarts, + int[] parameterNameEnds, int parametersEnd, int extendedReturnTypeDimensionCount, + int extendedReturnTypeDimensionEnd, char[][] exceptionTypes, int[] exceptionTypeStarts, + int[] exceptionTypeEnds, int bodyStart) { + enterAbstractMethod(declarationStart, javaDocPositions, modifiers, modifiersStart, + returnType, returnTypeStart, returnTypeEnd, returnTypeDimensionCount, + name, nameStart, nameEnd, parameterTypes, parameterTypeStarts, + parameterTypeEnds, parameterNames, parameterNameStarts, + parameterNameEnds, parametersEnd, extendedReturnTypeDimensionCount, + extendedReturnTypeDimensionEnd, exceptionTypes, exceptionTypeStarts, + exceptionTypeEnds, bodyStart,false); +} + +protected void enterType(int declarationStart, int[] javaDocPositions, + int modifiers, int modifiersStart, int keywordStart, char[] name, + int nameStart, int nameEnd, char[] superclass, int superclassStart, + int superclassEnd, char[][] superinterfaces, int[] superinterfaceStarts, + int[] superinterfaceEnds, int bodyStart, boolean isClass) { + if (fBuildingType) { + int[] sourceRange = {declarationStart, -1}; // will be fixed in the exit + int[] commentRange = {-1, -1}; + if (javaDocPositions != null) { + int length = javaDocPositions.length; + commentRange[0] = javaDocPositions[0]; + commentRange[1] = javaDocPositions[length - 1]; + } + int[] modifiersRange = {-1, -1}; + if (modifiersStart > -1) { + modifiersRange[0] = modifiersStart; + modifiersRange[1] = (modifiersStart > -1) ? keywordStart - 1 : -1; + } + int[] typeKeywordRange = {keywordStart, nameStart - 1}; + int[] nameRange = new int[] {nameStart, nameEnd}; + int[] extendsKeywordRange = {-1, -1}; + int[] superclassRange = {-1, -1}; + int[] implementsKeywordRange = {-1, -1}; + int[] interfacesRange = {-1, -1}; + if (isClass) { + if (superclass != null) { + extendsKeywordRange[0] = nameEnd + 1; + extendsKeywordRange[1] = superclassStart - 1; + superclassRange[0] = superclassStart; + superclassRange[1] = bodyStart - 1; + } + if (superinterfaces != null && superinterfaces.length > 0) { + superclassRange[1] = superclassEnd; + if (superclassEnd > -1) { + implementsKeywordRange[0] = superclassEnd + 1; + } else { + implementsKeywordRange[0] = nameEnd + 1; + } + implementsKeywordRange[1] = superinterfaceStarts[0] - 1; + interfacesRange[0] = superinterfaceStarts[0]; + interfacesRange[1] = superinterfaceEnds[superinterfaces.length - 1]; + } + } else { + if (superinterfaces != null && superinterfaces.length > 0) { + extendsKeywordRange[0] = nameEnd + 1; + extendsKeywordRange[1] = superinterfaceStarts[0] - 1; + interfacesRange[0] = superinterfaceStarts[0]; + interfacesRange[1] = superinterfaceEnds[superinterfaces.length - 1]; + } + } + int[] openBodyRange = {bodyStart, -1}; // fixed by setTypeRanges(DOMNode) + int[] closeBodyRange = {-1, -1}; // will be fixed in exit + fNode = new DOMType(fDocument, sourceRange, new String(name), nameRange, commentRange, + modifiers, modifiersRange, typeKeywordRange, superclassRange, extendsKeywordRange, + CharArrayOps.charcharToString(superinterfaces), interfacesRange, + implementsKeywordRange, openBodyRange, + closeBodyRange, isClass); + addChild(fNode); + fStack.push(fNode); + } +} +/** + * Finishes the configuration of the constructors and methods. + * + * @param bodyEnd - a source position corresponding to the closing bracket of the method + * @param declarationEnd - a source position corresponding to the end of the method + * declaration. This can include whitespace and comments following the closing bracket. + */ +protected void exitAbstractMethod(int bodyEnd, int declarationEnd) { + DOMMethod method = (DOMMethod) fStack.pop(); + method.setSourceRangeEnd(declarationEnd); + method.setBodyRangeEnd(bodyEnd + 1); + fNode = method; + if (fBuildingSingleMember) { + fFinishedSingleMember= true; + } +} +/** + * Finishes the configuration of the class DOM object which + * was created by a previous enterClass call. + * + * @see IDocumentElementRequestor#exitClass(int, int) + */ +public void exitClass(int bodyEnd, int declarationEnd) { + exitType(bodyEnd, declarationEnd); +} +/** + * Finishes the configuration of the method DOM object which + * was created by a previous enterConstructor call. + * + * @see IDocumentElementRequestor#exitConstructor(int, int) + */ +public void exitConstructor(int bodyEnd, int declarationEnd) { + exitAbstractMethod(bodyEnd, declarationEnd); +} +/** + * Finishes the configuration of the field DOM object which + * was created by a previous enterField call. + * + * @see IDocumentElementRequestor#exitField(int, int) + */ +public void exitField(int bodyEnd, int declarationEnd) { + DOMField field = (DOMField)fStack.pop(); + if (field.getEndPosition() < declarationEnd) { + field.setSourceRangeEnd(declarationEnd); + int nameEnd = field.fNameRange[1]; + if (nameEnd < bodyEnd) { + /* see 1FVIIV8 - obtain initializer range */ + String initializer = new String(fDocument, nameEnd + 1, bodyEnd - nameEnd); + int index = initializer.indexOf('='); + if (index > -1) { + field.setHasInitializer(true); + field.setInitializerRange(nameEnd + index + 2, bodyEnd); + } + } + } + fFieldCount++; + fNode = field; + if (fBuildingSingleMember) { + fFinishedSingleMember= true; + } +} +/** + * Finishes the configuration of the interface DOM object which + * was created by a previous enterInterface call. + * + * @see IDocumentElementRequestor#exitInterface(int, int) + */ +public void exitInterface(int bodyEnd, int declarationEnd) { + exitType(bodyEnd, declarationEnd); +} +/** + * Finishes the configuration of the method DOM object which + * was created by a previous enterMethod call. + * + * @see IDocumentElementRequestor#exitMethod(int, int) + */ +public void exitMethod(int bodyEnd, int declarationEnd) { + exitAbstractMethod(bodyEnd, declarationEnd); +} +/** + * Creates a new parser. + */ +protected DocumentElementParser getParser(Map settings) { + return new DocumentElementParser(this, new DefaultProblemFactory());//, new CompilerOptions(settings)); +} +/** + * Initializes the builder to create a document fragment. + * + * @param sourceCode - the document containing the source code to be analyzed + * @param buildingCompilationUnit - true if a the document is being analyzed to + * create a compilation unit, otherwise false + * @param buildingType - true if the document is being analyzed to create a + * type or compilation unit + * @param singleMember - true if building a single member + */ +protected void initializeBuild(char[] sourceCode, boolean buildingCompilationUnit, boolean buildingType, boolean singleMember) { + super.initializeBuild(sourceCode, buildingCompilationUnit, buildingType); + fBuildingSingleMember= singleMember; + fFinishedSingleMember= false; + +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMCompilationUnit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMCompilationUnit.java new file mode 100644 index 0000000..10c07ef --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMCompilationUnit.java @@ -0,0 +1,184 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import net.sourceforge.phpdt.core.Flags; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.core.jdom.IDOMType; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpdt.internal.core.util.CharArrayBuffer; +import net.sourceforge.phpdt.internal.core.util.CharArrayOps; + +/** + * DOMCompilation unit provides an implementation of IDOMCompilationUnit. + * + * @see IDOMCompilationUnit + * @see DOMNode + */ +class DOMCompilationUnit extends DOMNode implements IDOMCompilationUnit { + + /** + * The comment and/or whitespace preceding the + * first document fragment in this compilation + * unit. + */ + protected String fHeader; +/** + * Creates a new empty COMPILATION_UNIT document fragment. + */ +DOMCompilationUnit() { + fHeader=""; //$NON-NLS-1$ +} +/** + * Creates a new COMPILATION_UNIT on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * A compilation unit's source range is the entire document - + * the first integer is zero, and the second integer is the position + * of the last character in the document. + */ +DOMCompilationUnit(char[] document, int[] sourceRange) { + super(document, sourceRange, null, new int[]{-1, -1}); + fHeader = ""; //$NON-NLS-1$ +} +/** + * @see DOMNode#appendContents(CharArrayBuffer) + */ +protected void appendFragmentedContents(CharArrayBuffer buffer) { + buffer.append(getHeader()); + appendContentsOfChildren(buffer); +} +/** + * @see IDOMNode#canHaveChildren() + */ +public boolean canHaveChildren() { + return true; +} +/** + * @see IDOMCompilationUnit#getHeader() + */ +public String getHeader() { + return fHeader; +} +/** + * @see IDOMNode#getJavaElement + */ +public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException { + if (parent.getElementType() == IJavaElement.PACKAGE_FRAGMENT) { + return ((IPackageFragment)parent).getCompilationUnit(getName()); + } else { + throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$ + } +} +/** + * @see IDOMCompilationUnit#getName() + */ +public String getName() { + IDOMType topLevelType= null; + IDOMType firstType= null; + IDOMNode child= fFirstChild; + while (child != null) { + if (child.getNodeType() == IDOMNode.TYPE) { + IDOMType type= (IDOMType)child; + if (firstType == null) { + firstType= type; + } + if (Flags.isPublic(type.getFlags())) { + topLevelType= type; + break; + } + } + child= child.getNextNode(); + } + if (topLevelType == null) { + topLevelType= firstType; + } + if (topLevelType != null) { + return topLevelType.getName() + ".java"; //$NON-NLS-1$ + } else { + return null; + } +} +/** + * @see IDOMNode#getNodeType() + */ +public int getNodeType() { + return IDOMNode.COMPILATION_UNIT; +} +/** + * Sets the header + */ +protected void initalizeHeader() { + DOMNode child = (DOMNode)getFirstChild(); + if (child != null) { + int childStart = child.getStartPosition(); + if (childStart > 1) { + setHeader(CharArrayOps.substring(fDocument, 0, childStart)); + } + } +} +/** + * @see IDOMNode#isAllowableChild(IDOMNode) + */ +public boolean isAllowableChild(IDOMNode node) { + if (node != null) { + int type= node.getNodeType(); + return type == IDOMNode.PACKAGE || type == IDOMNode.IMPORT || type == IDOMNode.TYPE; + } else { + return false; + } + +} +/** + * @see DOMNode + */ +protected DOMNode newDOMNode() { + return new DOMCompilationUnit(); +} +/** + * Normalizes this DOMNode's source positions to include whitespace preceeding + * the node on the line on which the node starts, and all whitespace after the node up to + * the next node's start + */ +void normalize(ILineStartFinder finder) { + super.normalize(finder); + initalizeHeader(); +} +/** + * @see IDOMCompilationUnit@setHeader(String) + */ +public void setHeader(String comment) { + fHeader= comment; + fragment(); +} +/** + * @see IDOMCompilationUnit#setName(String) + */ +public void setName(String name) {} +/** + * @see DOMNode#shareContents(DOMNode) + */ +protected void shareContents(DOMNode node) { + super.shareContents(node); + fHeader= ((DOMCompilationUnit)node).fHeader; +} +/** + * @see IDOMNode#toString() + */ +public String toString() { + return "COMPILATION_UNIT: " + getName(); //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMField.java new file mode 100644 index 0000000..32ebdb1 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMField.java @@ -0,0 +1,618 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import java.util.Enumeration; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.jdom.DOMException; +import net.sourceforge.phpdt.core.jdom.IDOMField; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpdt.internal.core.util.CharArrayBuffer; +import net.sourceforge.phpdt.internal.core.util.CharArrayOps; + +/** + * DOMField provides an implementation of IDOMField. + * + * @see IDOMField + * @see DOMNode + */ +class DOMField extends DOMMember implements IDOMField { + + /** + * Contains the type of the field when the type + * has been altered from the contents in the + * document, otherwise null. + */ + protected String fType; + + /** + * The original inclusive source range of the + * field's type in the document. + */ + protected int[] fTypeRange; + + /** + * The contents of the initializer when the + * initializer has been altered from the + * original state in the document, otherwise + * null. + */ + protected String fInitializer; + + /** + * The original inclusive source range of the + * initializer in the document. + */ + protected int[] fInitializerRange; + +/** + * Constructs an empty field node. + */ +DOMField() { +} +/** + * Creates a new detailed FIELD document fragment on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * Contents start on and include the character at the first position. + * Contents end on and include the character at the last position. + * An array of -1's indicates this node's contents do not exist + * in the document. + * @param name - the identifier portion of the name of this field, + * corresponding to VariableDeclaratorId (JLS 8.3). + * @param nameRange - a two element array of integers describing the + * entire inclusive source range of this node's name within its document, + * including any array qualifiers that might follow the name. + * @param commentRange - a two element array describing the comments that precede + * the member declaration. The first matches the start of this node's + * sourceRange, and the second is the new-line or first non-whitespace + * character following the last comment. If no comments are present, + * this array contains two -1's. + * @param flags - an integer representing the modifiers for this member. The + * integer can be analyzed with org.eclipse.jdt.core.Flags + * @param modifierRange - a two element array describing the location of + * modifiers for this member within its source range. The first integer + * is the first character of the first modifier for this member, and + * the second integer is the last whitespace character preceeding the + * next part of this member declaration. If there are no modifiers present + * in this node's source code (that is, package default visibility), this array + * contains two -1's. + * @param typeRange- a two element array describing the location of the + * typeName in the document - the positions of the first and last characters + * of the typeName. + * @param type - the type of the field, in normalized form, as defined in + * Type in Field Declaration (JLS 8.3) + * @param hasInitializer - true if this field declaration includes an initializer, + * otherwise false + * @param initRange - a two element array describing the location of the initializer + * in the declaration. The first integer is the position of the character + * following the equals sign, and the position of the last character is the last + * in the initializer. If this field has no initializer, this array contains + * two -1's. + * @param isVariableDeclarator - true if the field is a seconday variable declarator + * for a previous field declaration. + */ +DOMField(char[] document, int[] sourceRange, String name, int[] nameRange, int[] commentRange, int flags, int[] modifierRange, int[] typeRange, String type, boolean hasInitializer, int[] initRange, boolean isVariableDeclarator) { + super(document, sourceRange, name, nameRange, commentRange, flags, modifierRange); + + fType= type; + fTypeRange= typeRange; + setHasInitializer(hasInitializer); + fInitializerRange= initRange; + setIsVariableDeclarator(isVariableDeclarator); + setMask(MASK_DETAILED_SOURCE_INDEXES, true); + +} +/** + * Creates a new simple FIELD document fragment on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * Contents start on and include the character at the first position. + * Contents end on and include the character at the last position. + * An array of -1's indicates this node's contents do not exist + * in the document. + * @param name - the identifier portion of the name of this field, + * corresponding to VariableDeclaratorId (JLS 8.3). + * @param nameRange - a two element array of integers describing the + * entire inclusive source range of this node's name within its document, + * including any array qualifiers that might follow the name. + * @param flags - an integer representing the modifiers for this member. The + * integer can be analyzed with org.eclipse.jdt.core.Flags + * @param type - the type of the field, in normalized form, as defined in + * Type in Field Declaration (JLS 8.3) + * @param isVariableDeclarator - true if the field is a seconday variable declarator + * for a previous field declaration. + */ +DOMField(char[] document, int[] sourceRange, String name, int[] nameRange, int flags, String type, boolean isVariableDeclarator) { + this(document, sourceRange, name, nameRange, new int[] {-1, -1}, flags, new int[] {-1, -1}, new int[] {-1, -1}, type, false, new int[] {-1, -1}, isVariableDeclarator); + setMask(MASK_DETAILED_SOURCE_INDEXES, false); +} +/** + * Appends this member's body contents to the given CharArrayBuffer. + * Body contents include the member body and any trailing whitespace. + * + *

        A field does not have a body. + * + * @see DOMMember#appendMemberBodyContents(CharArrayBuffer) + */ +protected void appendMemberBodyContents(CharArrayBuffer buffer) {} +/** + * @see DOMMember#appendMemberDeclarationContents(CharArrayBuffer) + */ +protected void appendMemberDeclarationContents(CharArrayBuffer buffer) { + + if (isVariableDeclarator()) { + buffer.append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0]); + } else { + buffer + .append(getTypeContents()) + .append(fDocument, fTypeRange[1] + 1, fNameRange[0] - fTypeRange[1] - 1); + } + + buffer.append(getNameContents()); + if (hasInitializer()) { + if (fInitializerRange[0] < 0) { + buffer + .append('=') + .append(fInitializer) + .append(fDocument, fNameRange[1] + 1, fSourceRange[1] - fNameRange[1]); + } else { + buffer + .append(fDocument, fNameRange[1] + 1, fInitializerRange[0] - fNameRange[1] - 1) + .append(getInitializer()) + .append(fDocument, fInitializerRange[1] + 1, fSourceRange[1] - fInitializerRange[1]); + } + } else { + if (fInitializerRange[0] < 0) { + buffer.append(fDocument, fNameRange[1] + 1, fSourceRange[1] - fNameRange[1]); + } else { + buffer.append(fDocument, fInitializerRange[1] + 1, fSourceRange[1] - fInitializerRange[1]); + } + } + +} +/** + * Appends this member's header contents to the given CharArrayBuffer. + * Header contents include any preceding comments and modifiers. + * + *

        If this field is a secondary variable declarator, there is no header. + * + * @see DOMMember#appendMemberHeaderFragment(CharArrayBuffer) + */ +protected void appendMemberHeaderFragment(CharArrayBuffer buffer) { + + if (isVariableDeclarator()) { + return; + } else { + super.appendMemberHeaderFragment(buffer); + } + +} +/** + * @see DOMMember#appendSimpleContents(CharArrayBuffer) + */ +protected void appendSimpleContents(CharArrayBuffer buffer) { + // append eveything before my name + buffer.append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0]); + // append my name + buffer.append(fName); + // append everything after my name + buffer.append(fDocument, fNameRange[1] + 1, fSourceRange[1] - fNameRange[1]); +} +/** + * Generates detailed source indexes for this node if possible. + * + * @exception DOMException if unable to generate detailed source indexes + * for this node + */ +//protected void becomeDetailed() throws DOMException { +// if (!isDetailed()) { +// if (isVariableDeclarator() || hasMultipleVariableDeclarators()) { +// DOMNode first = getFirstFieldDeclaration(); +// DOMNode last = getLastFieldDeclaration(); +// DOMNode node= first; +// String source= first.getContents(); +// while (node != last) { +// node= node.fNextNode; +// source+=node.getContents(); +// } +// DOMBuilder builder = new DOMBuilder(); +// IDOMField[] details= builder.createFields(source.toCharArray()); +// if (details.length == 0) { +// throw new DOMException(Util.bind("dom.cannotDetail")); //$NON-NLS-1$ +// } else { +// node= this; +// for (int i= 0; i < details.length; i++) { +// node.shareContents((DOMNode)details[i]); +// node= node.fNextNode; +// } +// } +// } else { +// super.becomeDetailed(); +// } +// +// } +//} +/** + * @see IDOMNode#clone() + */ +public Object clone() { +// if (isVariableDeclarator() || hasMultipleVariableDeclarators()) { +// return getFactory().createField(new String(getSingleVariableDeclaratorContents())); +// } else { + return super.clone(); +// } +} +/** + * Expands all variable declarators in this field declaration into + * stand-alone field declarations. + */ +protected void expand() { + if (isVariableDeclarator() || hasMultipleVariableDeclarators()) { + Enumeration siblings= new SiblingEnumeration(getFirstFieldDeclaration()); + DOMField field= (DOMField)siblings.nextElement(); + DOMNode next= field.fNextNode; + while (siblings.hasMoreElements() && (next instanceof DOMField) && (((DOMField)next).isVariableDeclarator())) { + field.localizeContents(); + if (field.fParent != null) { + field.fParent.fragment(); + } + field= (DOMField)siblings.nextElement(); + next= field.fNextNode; + } + field.localizeContents(); + } +} +/** + * @see DOMNode#getDetailedNode() + */ +//protected DOMNode getDetailedNode() { +// if (isVariableDeclarator() || hasMultipleVariableDeclarators()) { +// return (DOMNode)getFactory().createField(new String(getSingleVariableDeclaratorContents())); +// } else { +// return (DOMNode)getFactory().createField(getContents()); +// } +//} +/** + * Returns the first field document fragment that defines + * the type for this variable declarator. + */ +protected DOMField getFirstFieldDeclaration() { + if (isVariableDeclarator()) { + return ((DOMField)fPreviousNode).getFirstFieldDeclaration(); + } else { + return this; + } +} +/** + * @see IDOMField#getInitializer() + */ +public String getInitializer() { + becomeDetailed(); + if (hasInitializer()) { + if (fInitializer != null) { + return fInitializer; + } else { + return CharArrayOps.substring(fDocument, fInitializerRange[0], fInitializerRange[1] + 1 - fInitializerRange[0]); + } + } else { + return null; + } +} +/** + * @see IDOMNode#getJavaElement + */ +public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException { + if (parent.getElementType() == IJavaElement.TYPE) { + return ((IType)parent).getField(getName()); + } else { + throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$ + } +} +/** + * Returns the last field document fragment in this muli-declarator statement. + */ +protected DOMField getLastFieldDeclaration() { + DOMField field = this; + while (field.isVariableDeclarator() || field.hasMultipleVariableDeclarators()) { + if (field.fNextNode instanceof DOMField && ((DOMField)field.fNextNode).isVariableDeclarator()) { + field= (DOMField)field.fNextNode; + } else { + break; + } + } + return field; +} +/** + * @see DOMMember#getMemberDeclarationStartPosition() + */ +protected int getMemberDeclarationStartPosition() { + return fTypeRange[0]; +} +/** + * @see IDOMNode#getNodeType() + */ +public int getNodeType() { + return IDOMNode.FIELD; +} +/** + * Returns a String representing this field declaration as a field + * declaration with one variable declarator. + */ +protected char[] getSingleVariableDeclaratorContents() { + + + CharArrayBuffer buffer= new CharArrayBuffer(); + DOMField first= getFirstFieldDeclaration(); + if (first.isDetailed()) { + first.appendMemberHeaderFragment(buffer); + buffer.append(getType()); + if (isVariableDeclarator()) { + buffer.append(' '); + } else { + buffer.append(fDocument, fTypeRange[1] + 1, fNameRange[0] - fTypeRange[1] - 1); + } + } else { + buffer.append(first.fDocument, first.fSourceRange[0], first.fNameRange[0] - first.fSourceRange[0]); + } + + buffer.append(getName()); + if (hasInitializer()) { + if (fInitializerRange[0] < 0) { + buffer + .append('=') + .append(fInitializer) + .append(';') + .append(Util.LINE_SEPARATOR); + } else { + buffer + .append(fDocument, fNameRange[1] + 1, fInitializerRange[0] - fNameRange[1] - 1) + .append(getInitializer()) + .append(';') + .append(Util.LINE_SEPARATOR); + } + } else { + buffer.append(';').append(Util.LINE_SEPARATOR); + } + return buffer.getContents(); +} +/** + * @see IDOMField#getType() + */ +public String getType() { + return fType; +} +/** + * Returns the souce code to be used for this + * field's type. + */ +protected char[] getTypeContents() { + if (isTypeAltered()) { + return fType.toCharArray(); + } else { + return CharArrayOps.subarray(fDocument, fTypeRange[0], fTypeRange[1] + 1 - fTypeRange[0]); + } +} +/** + * Returns true if this field has an initializer expression, + * otherwise false. + */ +protected boolean hasInitializer() { + return getMask(MASK_FIELD_HAS_INITIALIZER); +} +/** + * Returns true is this field declarations has more than one + * variable declarator, otherwise false; + */ +protected boolean hasMultipleVariableDeclarators() { + return fNextNode != null && (fNextNode instanceof DOMField) && + ((DOMField)fNextNode).isVariableDeclarator(); +} +/** + * Inserts the given un-parented node as a sibling of this node, immediately before + * this node. Once inserted, the sibling is only dependent on this document fragment. + * + *

        When a sibling is inserted before a variable declarator, it must first + * be expanded. + * + * @see IDOMNode#insertSibling(IDOMNode) + */ +public void insertSibling(IDOMNode sibling) throws IllegalArgumentException, DOMException { + if (isVariableDeclarator()) { + expand(); + } + super.insertSibling(sibling); +} +/** + * Returns true if this field's type has been altered + * from the original document contents. + */ +protected boolean isTypeAltered() { + return getMask(MASK_FIELD_TYPE_ALTERED); +} +/** + * Returns true if this field is declared as a secondary variable + * declarator for a previous field declaration. + */ +protected boolean isVariableDeclarator() { + return getMask(MASK_FIELD_IS_VARIABLE_DECLARATOR); +} +/** + * @see DOMNode + */ +protected DOMNode newDOMNode() { + return new DOMField(); +} +/** + * Normalizes this DOMNode's end position. + */ +void normalizeEndPosition(ILineStartFinder finder, DOMNode next) { + if (next == null) { + // this node's end position includes all of the characters up + // to the end of the enclosing node + DOMNode parent = (DOMNode) getParent(); + if (parent == null || parent instanceof DOMCompilationUnit) { + setSourceRangeEnd(fDocument.length - 1); + } else { + // parent is a type + int temp = ((DOMType)parent).getCloseBodyPosition() - 1; + setSourceRangeEnd(temp); + fInsertionPosition = Math.max(finder.getLineStart(temp + 1), getEndPosition()); + } + } else { + // this node's end position is just before the start of the next node + // unless the next node is a field that is declared along with this one + int temp = next.getStartPosition() - 1; + fInsertionPosition = Math.max(finder.getLineStart(temp + 1), getEndPosition()); + + next.normalizeStartPosition(getEndPosition(), finder); + if (next instanceof DOMField) { + DOMField field = (DOMField) next; + if (field.isVariableDeclarator() && fTypeRange[0] == field.fTypeRange[0]) + return; + } + setSourceRangeEnd(next.getStartPosition() - 1); + } +} +/** + * Normalizes this DOMNode's start position. + */ +void normalizeStartPosition(int endPosition, ILineStartFinder finder) { + if (isVariableDeclarator()) { + // start position is end of last element + setStartPosition(fPreviousNode.getEndPosition() + 1); + } else { + super.normalizeStartPosition(endPosition, finder); + } +} +/** + * Offsets all the source indexes in this node by the given amount. + */ +protected void offset(int offset) { + super.offset(offset); + offsetRange(fInitializerRange, offset); + offsetRange(fTypeRange, offset); +} +/** + * Separates this node from its parent and siblings, maintaining any ties that + * this node has to the underlying document fragment. + * + *

        When a field with multiple declarators is removed, its declaration + * must first be expanded. + * + * @see IDOMNode#remove() + */ +public void remove() { + expand(); + super.remove(); +} +/** + * @see IDOMMember#setComment(String) + */ +public void setComment(String comment) { + expand(); + super.setComment(comment); +} +/** + * @see IDOMMember#setFlags(int) + */ +public void setFlags(int flags) { + expand(); + super.setFlags(flags); +} +/** + * Sets the state of this field declaration as having + * an initializer expression. + */ +protected void setHasInitializer(boolean hasInitializer) { + setMask(MASK_FIELD_HAS_INITIALIZER, hasInitializer); +} +/** + * @see IDOMField#setInitializer(char[]) + */ +public void setInitializer(String initializer) { + becomeDetailed(); + fragment(); + setHasInitializer(initializer != null); + fInitializer= initializer; +} +/** + * Sets the initializer range. + */ +void setInitializerRange(int start, int end) { + fInitializerRange[0] = start; + fInitializerRange[1] = end; +} +/** + * Sets the state of this field declaration as being a + * secondary variable declarator for a previous field + * declaration. + */ +protected void setIsVariableDeclarator(boolean isVariableDeclarator) { + setMask(MASK_FIELD_IS_VARIABLE_DECLARATOR, isVariableDeclarator); +} +/** + * @see IDOMField#setName(char[]) + */ +public void setName(String name) throws IllegalArgumentException { + if (name == null) { + throw new IllegalArgumentException(Util.bind("element.nullName")); //$NON-NLS-1$ + } else { + super.setName(name); + setTypeAltered(true); + } +} +/** + * @see IDOMField#setType(char[]) + */ +public void setType(String typeName) throws IllegalArgumentException { + if (typeName == null) { + throw new IllegalArgumentException(Util.bind("element.nullType")); //$NON-NLS-1$ + } + becomeDetailed(); + expand(); + fragment(); + setTypeAltered(true); + setNameAltered(true); + fType= typeName; +} +/** + * Sets the state of this field declaration as having + * the field type altered from the original document. + */ +protected void setTypeAltered(boolean typeAltered) { + setMask(MASK_FIELD_TYPE_ALTERED, typeAltered); +} +/** + * @see DOMNode#shareContents(DOMNode) + */ +protected void shareContents(DOMNode node) { + super.shareContents(node); + DOMField field= (DOMField)node; + fInitializer= field.fInitializer; + fInitializerRange= rangeCopy(field.fInitializerRange); + fType= field.fType; + fTypeRange= rangeCopy(field.fTypeRange); +} +/** + * @see IDOMNode#toString() + */ +public String toString() { + return "FIELD: " + getName(); //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMImport.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMImport.java new file mode 100644 index 0000000..3ff5280 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMImport.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.jdom.IDOMImport; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpdt.internal.core.util.CharArrayBuffer; + +/** + * DOMImport provides an implementation of IDOMImport. + * + * @see IDOMImport + * @see DOMNode + */ +class DOMImport extends DOMNode implements IDOMImport { + /** + * Indicates if this import is an on demand type import + */ + protected boolean fOnDemand; +/** + * Creates a new empty IMPORT node. + */ +DOMImport() { + fName = "java.lang.*"; //$NON-NLS-1$ + setMask(MASK_DETAILED_SOURCE_INDEXES, true); +} +/** + * Creates a new detailed IMPORT document fragment on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * Contents start on and include the character at the first position. + * Contents end on and include the character at the last position. + * An array of -1's indicates this node's contents do not exist + * in the document. + * @param name - the identifier portion of the name of this node, or + * null if this node does not have a name + * @param nameRange - a two element array of integers describing the + * entire inclusive source range of this node's name within its document, + * including any array qualifiers that might immediately follow the name + * or -1's if this node does not have a name. + * @param onDemand - indicates if this import is an on demand style import + */ +DOMImport(char[] document, int[] sourceRange, String name, int[] nameRange, boolean onDemand) { + super(document, sourceRange, name, nameRange); + fOnDemand = onDemand; + setMask(MASK_DETAILED_SOURCE_INDEXES, true); +} +/** + * Creates a new simple IMPORT document fragment on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * Contents start on and include the character at the first position. + * Contents end on and include the character at the last position. + * An array of -1's indicates this node's contents do not exist + * in the document. + * @param name - the identifier portion of the name of this node, or + * null if this node does not have a name + * @param onDemand - indicates if this import is an on demand style import + */ +DOMImport(char[] document, int[] sourceRange, String name, boolean onDemand) { + this(document, sourceRange, name, new int[] {-1, -1}, onDemand); + fOnDemand = onDemand; + setMask(MASK_DETAILED_SOURCE_INDEXES, false); +} +/** + * @see DOMNode#appendFragmentedContents(CharArrayBuffer) + */ +protected void appendFragmentedContents(CharArrayBuffer buffer) { + if (fNameRange[0] < 0) { + buffer + .append("import ") //$NON-NLS-1$ + .append(fName) + .append(';') + .append(Util.LINE_SEPARATOR); + } else { + buffer.append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0]); + //buffer.append(fDocument, fNameRange[0], fNameRange[1] - fNameRange[0] + 1); + buffer.append(fName); + buffer.append(fDocument, fNameRange[1] + 1, fSourceRange[1] - fNameRange[1]); + } +} +/** + * @see IDOMNode#getContents() + */ +public String getContents() { + if (fName == null) { + return null; + } else { + return super.getContents(); + } +} +/** + * @see DOMNode#getDetailedNode() + */ +//protected DOMNode getDetailedNode() { +// return (DOMNode)getFactory().createImport(getContents()); +//} +/** + * @see IDOMNode#getJavaElement + */ +public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException { +// if (parent.getElementType() == IJavaElement.COMPILATION_UNIT) { +// return ((ICompilationUnit)parent).getImport(getName()); +// } else { + throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$ +// } +} +/** + * @see IDOMNode#getNodeType() + */ +public int getNodeType() { + return IDOMNode.IMPORT; +} +/** + * @see IDOMImport#isOnDemand() + */ +public boolean isOnDemand() { + return fOnDemand; +} +/** + * @see DOMNode + */ +protected DOMNode newDOMNode() { + return new DOMImport(); +} +/** + * @see IDOMNode#setName(char[]) + */ +public void setName(String name) { + if (name == null) { + throw new IllegalArgumentException(Util.bind("element.nullName")); //$NON-NLS-1$ + } + becomeDetailed(); + super.setName(name); + fOnDemand = name.endsWith(".*"); //$NON-NLS-1$ +} +/** + * @see IDOMNode#toString() + */ +public String toString() { + return "IMPORT: " + getName(); //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMInitializer.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMInitializer.java new file mode 100644 index 0000000..314ee35 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMInitializer.java @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.jdom.IDOMInitializer; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpdt.internal.core.util.CharArrayBuffer; +import net.sourceforge.phpdt.internal.core.util.CharArrayOps; + +/** + * DOMInitializer provides an implementation of IDOMInitializer. + * + * @see IDOMInitializer + * @see DOMNode + */ +class DOMInitializer extends DOMMember implements IDOMInitializer { + + /** + * The contents of the initializer's body when the + * body has been altered from the contents in the + * document, otherwise null. + */ + protected String fBody; + + /** + * The original inclusive source range of the + * body in the document. + */ + protected int[] fBodyRange; + +/** + * Constructs an empty initializer node. + */ +DOMInitializer() { + +} +/** + * Creates a new detailed INITIALIZER document fragment on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * Contents start on and include the character at the first position. + * Contents end on and include the character at the last position. + * An array of -1's indicates this node's contents do not exist + * in the document. + * @param commentRange - a two element array describing the comments that precede + * the member declaration. The first matches the start of this node's + * sourceRange, and the second is the new-line or first non-whitespace + * character following the last comment. If no comments are present, + * this array contains two -1's. + * @param flags - an integer representing the modifiers for this member. The + * integer can be analyzed with org.eclipse.jdt.core.Flags + * @param modifierRange - a two element array describing the location of + * modifiers for this member within its source range. The first integer + * is the first character of the first modifier for this member, and + * the second integer is the last whitespace character preceeding the + * next part of this member declaration. If there are no modifiers present + * in this node's source code (that is, package default visibility), this array + * contains two -1's. + * @param bodyStartPosition - the position of the open brace of the body + * of this initialzer. + */ +DOMInitializer(char[] document, int[] sourceRange, int[] commentRange, int flags, int[] modifierRange, int bodyStartPosition) { + super(document, sourceRange, null, new int[]{-1, -1}, commentRange, flags, modifierRange); + fBodyRange= new int[2]; + fBodyRange[0]= bodyStartPosition; + fBodyRange[1]= sourceRange[1]; + setHasBody(true); + setMask(MASK_DETAILED_SOURCE_INDEXES, true); +} +/** + * Creates a new simple INITIALIZER document fragment on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * Contents start on and include the character at the first position. + * Contents end on and include the character at the last position. + * An array of -1's indicates this node's contents do not exist + * in the document. + * @param flags - an integer representing the modifiers for this member. The + * integer can be analyzed with org.eclipse.jdt.core.Flags + */ +DOMInitializer(char[] document, int[] sourceRange, int flags) { + this(document, sourceRange, new int[] {-1, -1}, flags, new int[] {-1, -1}, -1); + setMask(MASK_DETAILED_SOURCE_INDEXES, false); + +} +/** + * @see DOMMember#appendMemberBodyContents(CharArrayBuffer) + */ +protected void appendMemberBodyContents(CharArrayBuffer buffer) { + if (hasBody()) { + buffer + .append(getBody()) + .append(fDocument, fBodyRange[1] + 1, fSourceRange[1] - fBodyRange[1]); + } else { + buffer.append("{}").append(Util.LINE_SEPARATOR); //$NON-NLS-1$ + } +} +/** + * @see DOMMember#appendMemberDeclarationContents(CharArrayBuffer) + */ +protected void appendMemberDeclarationContents(CharArrayBuffer buffer) {} +/** + * @see DOMNode#appendSimpleContents(CharArrayBuffer) + */ +protected void appendSimpleContents(CharArrayBuffer buffer) { + // append eveything before my name + buffer.append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0]); + // append my name + buffer.append(fName); + // append everything after my name + buffer.append(fDocument, fNameRange[1] + 1, fSourceRange[1] - fNameRange[1]); +} +/** + * @see IDOMInitializer#getBody() + */ +public String getBody() { + becomeDetailed(); + if (hasBody()) { + if (fBody != null) { + return fBody; + } else { + return CharArrayOps.substring(fDocument, fBodyRange[0], fBodyRange[1] + 1 - fBodyRange[0]); + } + } else { + return null; + } +} +/** + * @see DOMNode#getDetailedNode() + */ +//protected DOMNode getDetailedNode() { +// return (DOMNode)getFactory().createInitializer(getContents()); +//} +/** + * @see IDOMNode#getJavaElement + */ +public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException { +// if (parent.getElementType() == IJavaElement.TYPE) { +// int count = 1; +// IDOMNode previousNode = getPreviousNode(); +// while (previousNode != null) { +// if (previousNode instanceof DOMInitializer) { +// count++; +// } +// previousNode = previousNode.getPreviousNode(); +// } +// return ((IType) parent).getInitializer(count); +// } else { + throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$ +// } +} +/** + * @see DOMMember#getMemberDeclarationStartPosition() + */ +protected int getMemberDeclarationStartPosition() { + return fBodyRange[0]; +} +/** + * @see IDOMNode#getNodeType() + */ +public int getNodeType() { + return IDOMNode.INITIALIZER; +} +/** + * @see IDOMNode#isSigantureEqual(IDOMNode). + * + *

        This method always answers false since an initializer + * does not have a signature. + */ +public boolean isSignatureEqual(IDOMNode node) { + return false; +} +/** + * @see DOMNode + */ +protected DOMNode newDOMNode() { + return new DOMInitializer(); +} +/** + * Offsets all the source indexes in this node by the given amount. + */ +protected void offset(int offset) { + super.offset(offset); + offsetRange(fBodyRange, offset); +} +/** + * @see IDOMInitializer#setBody(char[]) + */ +public void setBody(String body) { + becomeDetailed(); + fBody= body; + setHasBody(body != null); + fragment(); +} +/** + * @see IDOMInitializer#setName(String) + */ +public void setName(String name) {} +/** + * @see DOMNode#shareContents(DOMNode) + */ +protected void shareContents(DOMNode node) { + super.shareContents(node); + DOMInitializer init= (DOMInitializer)node; + fBody= init.fBody; + fBodyRange= rangeCopy(init.fBodyRange); +} +/** + * @see IDOMNode#toString() + */ +public String toString() { + return "INITIALIZER"; //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMMember.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMMember.java new file mode 100644 index 0000000..19bde2e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMMember.java @@ -0,0 +1,351 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import net.sourceforge.phpdt.core.Flags; +import net.sourceforge.phpdt.core.jdom.IDOMMember; +import net.sourceforge.phpdt.internal.compiler.env.IConstants; +import net.sourceforge.phpdt.internal.core.util.CharArrayBuffer; +import net.sourceforge.phpdt.internal.core.util.CharArrayOps; + +/** + * DOMMember provides an implementation of IDOMMember. + * + * @see IDOMMember + * @see DOMNode + */ + +abstract class DOMMember extends DOMNode implements IDOMMember { + + /** + * The modifier flags for this member that can be + * analyzed with org.eclipse.jdt.core.Flags + */ + protected int fFlags= 0; + + /** + * The member's comments when it has been altered from + * the contents in the document, otherwise null. + */ + protected String fComment= null; + + /** + * The original inclusive source range of the + * member's preceding comments in the document, + * or -1's if the member did not originally have a + * comment. + */ + protected int[] fCommentRange; + + + /** + * The member's modifiers textual representation when + * the modifiers (flags) have been altered from + * their original contents, otherwise null. + */ + protected char[] fModifiers= null; + + /** + * The original inclusive source range of the + * member's modifiers in the document, or -1's if + * the member did not originally have modifiers in + * the source code (that is, package default visibility). + */ + protected int[] fModifierRange; + +/** + * Constructs an empty member node. + */ +DOMMember() { + +} +/** + * Creates a new member document fragment on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * Contents start on and include the character at the first position. + * Contents end on and include the character at the last position. + * An array of -1's indicates this node's contents do not exist + * in the document. + * @param name - the identifier portion of the name of this node, or + * null if this node does not have a name + * @param nameRange - a two element array of integers describing the + * entire inclusive source range of this node's name within its document, + * including any array qualifiers that might immediately follow the name. + * @param commentRange - a two element array describing the comments that precede + * the member declaration. The first matches the start of this node's + * sourceRange, and the second is the new-line or first non-whitespace + * character following the last comment. If no comments are present, + * this array contains two -1's. + * @param flags - an integer representing the modifiers for this member. The + * integer can be analyzed with org.eclipse.jdt.core.Flags + * @param modifierRange - a two element array describing the location of + * modifiers for this member within its source range. The first integer + * is the first character of the first modifier for this member, and + * the second integer is the last whitespace character preceeding the + * next part of this member declaration. If there are no modifiers present + * in this node's source code (that is, package default visibility), this array + * contains two -1's. + */ +DOMMember(char[] document, int[] sourceRange, String name, int[] nameRange, int[] commentRange, int flags, int[] modifierRange) { + super(document, sourceRange, name, nameRange); + fFlags= flags; + fComment= null; + fCommentRange= commentRange; + fModifierRange= modifierRange; + setHasComment(commentRange[0] >= 0); +} +/** + * Appends the contents of this node to the given CharArrayBuffer, using + * the original document and indicies as a form for the current attribute values + * of this node. + * + *

        To facilitate the implementation of generating contents for members, + * the content of members is split into three sections - the header, + * declaration, and body sections. The header section includes any preceding + * comments and modifiers. The declaration section includes the portion of + * the member declaration that follows any modifiers and precedes the + * member body. The body section includes the member body and any trailing + * whitespace. + * + * @see DOMNode#appendFragmentedContents(CharArrayBuffer) + */ +protected void appendFragmentedContents(CharArrayBuffer buffer) { + if (isDetailed()) { + appendMemberHeaderFragment(buffer); + appendMemberDeclarationContents(buffer); + appendMemberBodyContents(buffer); + } else { + appendSimpleContents(buffer); + } +} +/** + * Appends this member's body contents to the given CharArrayBuffer. + * Body contents include the member body and any trailing whitespace. + */ +protected abstract void appendMemberBodyContents(CharArrayBuffer buffer); +/** + * Appends this member's declaration contents to the given CharArrayBuffer. + * The declaration contents includes the portion of this member that + * appears after any modifiers and precedes the body. + */ +protected abstract void appendMemberDeclarationContents(CharArrayBuffer buffer); +/** + * Appends this member's header contents to the given CharArrayBuffer. + * Header contents include any preceding comments and modifiers. + */ +protected void appendMemberHeaderFragment(CharArrayBuffer buffer) { + + int spaceStart, spaceEnd; + + // space before comment + if (hasComment()) { + spaceStart= fSourceRange[0]; + spaceEnd= fCommentRange[0]; + if (spaceEnd > 0) { + buffer.append(fDocument, spaceStart, spaceEnd - spaceStart); + } + } + + String fragment= getComment(); + if (fragment != null) { + buffer.append(fragment); + } + + if (fCommentRange[1] >= 0) { + spaceStart= fCommentRange[1] + 1; + } else { + spaceStart= fSourceRange[0]; + } + if (fModifierRange[0] >= 0) { + spaceEnd= fModifierRange[0] - 1; + } else { + spaceEnd= getMemberDeclarationStartPosition() - 1; + } + + if (spaceEnd >= spaceStart) { + buffer.append(fDocument, spaceStart, spaceEnd + 1 - spaceStart); + } + buffer.append(getModifiersText()); + +} +/** + * Appends the contents of this node to the given CharArrayBuffer, using + * the original document and indicies as a form for the current attribute values + * of this node. This method is called when this node is know not to have + * detailed source indexes. + */ +protected abstract void appendSimpleContents(CharArrayBuffer buffer); +/** + * Returns a copy of the given array with the new element appended + * to the end of the array. + */ +protected String[] appendString(String[] list, String element) { + String[] copy= new String[list.length + 1]; + System.arraycopy(list, 0, copy, 0, list.length); + copy[list.length]= element; + return copy; +} +/** + * Returns a String describing the modifiers for this member, + * ending with whitespace (if not empty). This value serves as a replacement + * value for the member's modifier range when the modifiers have been altered + * from their original contents. + */ +protected char[] generateFlags() { + char[] flags= Flags.toString(getFlags()).toCharArray(); + if (flags.length == 0) { + return flags; + } else { + return CharArrayOps.concat(flags, new char[] {' '}); + } +} +/** + * @see IDOMMember#getComment() + */ +public String getComment() { + becomeDetailed(); + if (hasComment()) { + if (fComment != null) { + return fComment; + } else { + return CharArrayOps.substring(fDocument, fCommentRange[0], fCommentRange[1] + 1 - fCommentRange[0]); + } + } else { + return null; + } +} +/** + * @see IDOMMember#getFlags() + */ +public int getFlags() { + return fFlags; +} +/** + * Returns the location of the first character in the member's declaration + * section. + * + * @see DOMMember#getMemberDeclarationContents() + * @see DOMMember#getFragmentedContents() + */ +protected abstract int getMemberDeclarationStartPosition(); +/** + * Returns the String to be used for this member's flags when + * generating contents - either the original contents in the document + * or the replacement value. + */ +protected char[] getModifiersText() { + if (fModifiers == null) { + if (fModifierRange[0] < 0) { + return null; + } else { + return CharArrayOps.subarray(fDocument, fModifierRange[0], fModifierRange[1] + 1 - fModifierRange[0]); + } + } else { + return fModifiers; + } +} +/** + * Returns true if this member currently has a body. + */ +protected boolean hasBody() { + return getMask(MASK_HAS_BODY); +} +/** + * Returns true if this member currently has a comment. + */ +protected boolean hasComment() { + return getMask(MASK_HAS_COMMENT); +} +/** + * Offsets all the source indexes in this node by the given amount. + */ +protected void offset(int offset) { + super.offset(offset); + offsetRange(fCommentRange, offset); + offsetRange(fModifierRange, offset); +} +/** + * @see IDOMMember#setComment(String) + */ +public void setComment(String comment) { + becomeDetailed(); + fComment= comment; + fragment(); + setHasComment(comment != null); + /* see 1FVIJAH */ + if (comment != null) { + String commentString = new String(comment); + if (commentString.indexOf("@deprecated") >= 0) { //$NON-NLS-1$ + fFlags= fFlags | IConstants.AccDeprecated; + return; + } + + } + fFlags= fFlags & (~IConstants.AccDeprecated); + +} +/** + * @see IDOMMember#setFlags(int) + */ +public void setFlags(int flags) { + becomeDetailed(); + if (Flags.isDeprecated(fFlags)) { + fFlags= flags | IConstants.AccDeprecated; + } else { + fFlags= flags & (~IConstants.AccDeprecated); + } + fragment(); + fModifiers= generateFlags(); +} +/** + * Sets the state of this member declaration as having + * a body. + */ +protected void setHasBody(boolean hasBody) { + setMask(MASK_HAS_BODY, hasBody); +} +/** + * Sets the state of this member declaration as having + * a preceding comment. + */ +protected void setHasComment(boolean hasComment) { + setMask(MASK_HAS_COMMENT, hasComment); +} +/** + * Sets the original position of the first character of this node's contents + * in its document. This method is only used during DOM creation while + * normalizing the source range of each node. + * + * Synchronize the start of the comment position with the start of the + * node. + */ +protected void setStartPosition(int start) { + if (fCommentRange[0] >= 0) { + fCommentRange[0]= start; + } + super.setStartPosition(start); +} +/** + * @see DOMNode#shareContents(DOMNode) + */ +protected void shareContents(DOMNode node) { + super.shareContents(node); + DOMMember member= (DOMMember)node; + fComment= member.fComment; + fCommentRange= rangeCopy(member.fCommentRange); + fFlags= member.fFlags; + fModifiers= member.fModifiers; + fModifierRange= rangeCopy(member.fModifierRange); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMMethod.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMMethod.java new file mode 100644 index 0000000..3221fdf --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMMethod.java @@ -0,0 +1,718 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.Signature; +import net.sourceforge.phpdt.core.jdom.IDOMMethod; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpdt.internal.core.util.CharArrayBuffer; +import net.sourceforge.phpdt.internal.core.util.CharArrayOps; + +/** + * DOMMethod provides an implementation of IDOMMethod. + * + * @see IDOMMethod + * @see DOMNode + */ + +class DOMMethod extends DOMMember implements IDOMMethod { + + /** + * Contains the return type of the method when the + * return type has been altered from the contents + * in the document, otherwise null. + */ + protected String fReturnType; + + /** + * The original inclusive source range of the + * method's return type in the document, or -1's + * if no return type is present in the document. + * If the return type of this method is qualified with + * '[]' following the parameter list, this array has + * four entries. In this case, the last two entries + * of the array are the inclusive source range of + * the array qualifiers. + */ + protected int[] fReturnTypeRange; + + /** + * Contains the textual representation of the method's + * parameter list, including open and closing parentheses + * when the parameters had been altered from the contents + * in the document, otherwise null. + */ + protected char[] fParameterList; + + /** + * The original inclusive source range of the + * method's parameter list in the document. + */ + protected int[] fParameterRange; + + /** + * Contains the textual representation of the method's + * exception list when the exceptions had been altered + * from the contents in the document, otherwise + * null. The exception list is a comment + * delimited list of exceptions, not including the "throws" + * keyword. + */ + protected char[] fExceptionList; + + /** + * The original inclusive source range of the + * method's exception list in the document. + */ + protected int[] fExceptionRange; + + /** + * Contains the method's body when the body has + * been altered from the contents in the document, + * otherwise null. The body includes everything + * between and including the enclosing braces, and trailing + * whitespace. + */ + protected String fBody; + + /** + * The original inclusive source range of the + * method's body. + */ + protected int[] fBodyRange; + + + /** + * Names of parameters in the method parameter list, + * or null if the method has no parameters. + */ + protected String[] fParameterNames; + + /** + * Types of parameters in the method parameter list, + * or null if the method has no parameters. + */ + protected String[] fParameterTypes; + + /** + * The exceptions the method throws, or null + * if the method throws no exceptions. + */ + protected String[] fExceptions; + + +/** + * Constructs an empty method node. + */ +DOMMethod() { + +} +/** + * Creates a new detailed METHOD document fragment on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * Contents start on and include the character at the first position. + * Contents end on and include the character at the last position. + * An array of -1's indicates this node's contents do not exist + * in the document. + * @param name - the identifier portion of the name of this node, or + * null if this node does not have a name + * @param nameRange - a two element array of integers describing the + * entire inclusive source range of this node's name within its document, + * including any array qualifiers that might immediately follow the name + * or -1's if this node does not have a name. + * @param commentRange - a two element array describing the comments that precede + * the member declaration. The first matches the start of this node's + * sourceRange, and the second is the new-line or first non-whitespace + * character following the last comment. If no comments are present, + * this array contains two -1's. + * @param flags - an integer representing the modifiers for this member. The + * integer can be analyzed with org.eclipse.jdt.core.Flags + * @param modifierRange - a two element array describing the location of + * modifiers for this member within its source range. The first integer + * is the first character of the first modifier for this member, and + * the second integer is the last whitespace character preceeding the + * next part of this member declaration. If there are no modifiers present + * in this node's source code (that is, package default visibility), this array + * contains two -1's. + * @param isConstructor - true if the method is a contructor, otherwise false + * @param returnType - the normalized return type of this method + * @param returnTypeRange - a two element array describing the location of the + * return type within the method's source range. The first integer is is + * the position of the first character in the return type, and the second + * integer is the position of the last character in the return type. + * For constructors, the contents of this array are -1's. + * If the return type of this method is qualified with '[]' following the + * parameter list, this array has four entries. In this case, the last + * two entries of the array are the inclusive source range of the array + * qualifiers. + * @param parameterTypes - an array of parameter types in the method declaration + * or null if the method has no parameters + * @param parameterNames - an array of parameter names in the method declaration + * or null if the method has no parameters + * @param parameterRange - a two element array describing the location of the + * parameter list in the method. The first integer is the location of the + * open parenthesis and the second integer is the location of the closing + * parenthesis. + * @param exceptions - an array of the names of exceptions thrown by this method + * or null if the method throws no exceptions + * @param exceptionRange - a two element array describing the location of the + * exception list in the method declaration. The first integer is the position + * of the first character in the first exception the method throws, and the + * second integer is the position of the last character of the last exception + * this method throws. + * @param bodyRange - a two element array describing the location of the method's body. + * The first integer is the first character following the method's + * parameter list, or exception list (if present). The second integer is the location + * of the last character in the method's source range. + */ +DOMMethod(char[] document, int[] sourceRange, String name, int[] nameRange, int[] commentRange, int flags, int[] modifierRange, boolean isConstructor, String returnType, int[] returnTypeRange, String[] parameterTypes, String[] parameterNames, int[] parameterRange, String[] exceptions, int[] exceptionRange, int[] bodyRange) { + super(document, sourceRange, name, nameRange, commentRange, flags, modifierRange); + + setMask(MASK_IS_CONSTRUCTOR, isConstructor); + fReturnType= returnType; + fReturnTypeRange= returnTypeRange; + fParameterTypes= parameterTypes; + fParameterNames= parameterNames; + fParameterRange= parameterRange; + fExceptionRange= exceptionRange; + fExceptions= exceptions; + setHasBody(true); + fBodyRange= bodyRange; + setMask(MASK_DETAILED_SOURCE_INDEXES, true); + +} +/** + * Creates a new simple METHOD document fragment on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * Contents start on and include the character at the first position. + * Contents end on and include the character at the last position. + * An array of -1's indicates this node's contents do not exist + * in the document. + * @param name - the identifier portion of the name of this node, or + * null if this node does not have a name + * @param nameRange - a two element array of integers describing the + * entire inclusive source range of this node's name within its document, + * including any array qualifiers that might immediately follow the name + * or -1's if this node does not have a name. + * @param flags - an integer representing the modifiers for this member. The + * integer can be analyzed with org.eclipse.jdt.core.Flags + * @param isConstructor - true if the method is a contructor, otherwise false + * @param returnType - the normalized return type of this method + * @param parameterTypes - an array of parameter types in the method declaration + * or null if the method has no parameters + * @param parameterNames - an array of parameter names in the method declaration + * or null if the method has no parameters + * @param exceptions - an array of the names of exceptions thrown by this method + * or null if the method throws no exceptions + */ +DOMMethod(char[] document, int[] sourceRange, String name, int[] nameRange, int flags, boolean isConstructor, String returnType, String[] parameterTypes, String[] parameterNames, String[] exceptions) { + this(document, sourceRange, name, nameRange, new int[] {-1, -1}, flags, new int[] {-1, -1}, isConstructor, returnType, new int[] {-1, -1}, parameterTypes, parameterNames, new int[] {-1, -1}, exceptions, new int[] {-1, -1}, new int[] {-1, -1}); + setMask(MASK_DETAILED_SOURCE_INDEXES, false); +} +/** + * @see IDOMMethod#addException(String) + */ +public void addException(String name) throws IllegalArgumentException { + if (name == null) { + throw new IllegalArgumentException(Util.bind("dom.nullExceptionType")); //$NON-NLS-1$ + } + if (fExceptions == null) { + fExceptions= new String[1]; + fExceptions[0]= name; + } else { + fExceptions= appendString(fExceptions, name); + } + setExceptions(fExceptions); +} +/** + * @see IDOMMethod#addParameter(String, String) + */ +public void addParameter(String type, String name) throws IllegalArgumentException { + if (type == null) { + throw new IllegalArgumentException(Util.bind("dom.nullTypeParameter")); //$NON-NLS-1$ + } + if (name == null) { + throw new IllegalArgumentException(Util.bind("dom.nullNameParameter")); //$NON-NLS-1$ + } + if (fParameterNames == null) { + fParameterNames= new String[1]; + fParameterNames[0]= name; + } else { + fParameterNames= appendString(fParameterNames, name); + } + if (fParameterTypes == null) { + fParameterTypes= new String[1]; + fParameterTypes[0]= type; + } else { + fParameterTypes= appendString(fParameterTypes, type); + } + setParameters(fParameterTypes, fParameterNames); +} +/** + * @see DOMMember#appendMemberBodyContents(CharArrayBuffer) + */ +protected void appendMemberBodyContents(CharArrayBuffer buffer) { + if (fBody != null) { + buffer.append(fBody); + } else { + buffer.append(fDocument, fBodyRange[0], fBodyRange[1] + 1 - fBodyRange[0]); + } +} +/** + * @see DOMMember#appendMemberDeclarationContents(CharArrayBuffer) + */ +protected void appendMemberDeclarationContents(CharArrayBuffer buffer) { + + if (isConstructor()) { + buffer + .append(getConstructorName()) + .append(fDocument, fNameRange[1] + 1, fParameterRange[0] - fNameRange[1] - 1); + } else { + buffer.append(getReturnTypeContents()); + if (fReturnTypeRange[0] >= 0) { + buffer.append(fDocument, fReturnTypeRange[1] + 1, fNameRange[0] - fReturnTypeRange[1] - 1); + } else { + buffer.append(' '); + } + buffer + .append(getNameContents()) + .append(fDocument, fNameRange[1] + 1, fParameterRange[0] - fNameRange[1] - 1); + } + if (fParameterList != null) { + buffer.append(fParameterList); + } else { + buffer.append(fDocument, fParameterRange[0], fParameterRange[1] + 1 - fParameterRange[0]); + } + int start; + if (hasTrailingArrayQualifier() && isReturnTypeAltered()) { + start= fReturnTypeRange[3] + 1; + } else { + start= fParameterRange[1] + 1; + } + if (fExceptions != null) { + // add 'throws' keyword + if (fExceptionRange[0] >= 0) { + buffer.append(fDocument, start, fExceptionRange[0] - start); + } else { + buffer.append(" throws "); //$NON-NLS-1$ + } + // add exception list + if (fExceptionList != null) { + buffer.append(fExceptionList); + // add space before body + if (fExceptionRange[0] >= 0) { + buffer.append(fDocument, fExceptionRange[1] + 1, fBodyRange[0] - fExceptionRange[1] - 1); + } else { + buffer.append(fDocument, fParameterRange[1] + 1, fBodyRange[0] - fParameterRange[1] - 1); + } + } else { + // add list and space before body + buffer.append(fDocument, fExceptionRange[0], fBodyRange[0] - fExceptionRange[0]); + } + } else { + // add space before body + if (fExceptionRange[0] >= 0) { + buffer.append(fDocument, fExceptionRange[1] + 1, fBodyRange[0] - fExceptionRange[1] - 1); + } else { + buffer.append(fDocument, start, fBodyRange[0] - start); + } + } + +} +/** + * @see DOMNode#appendSimpleContents(CharArrayBuffer) + */ +protected void appendSimpleContents(CharArrayBuffer buffer) { + // append eveything before my name + buffer.append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0]); + // append my name + if (isConstructor()) { + buffer.append(getConstructorName()); + } else { + buffer.append(fName); + } + // append everything after my name + buffer.append(fDocument, fNameRange[1] + 1, fSourceRange[1] - fNameRange[1]); +} +/** + * @see IDOMMethod#getBody() + */ +public String getBody() { + becomeDetailed(); + if (hasBody()) { + if (fBody != null) { + return fBody; + } else { + return CharArrayOps.substring(fDocument, fBodyRange[0], fBodyRange[1] + 1 - fBodyRange[0]); + } + } else { + return null; + } +} +/** + * Returns the simple name of the enclsoing type for this constructor. + * If the constuctor is not currently enclosed in a type, the original + * name of the constructor as found in the documnent is returned. + */ +protected String getConstructorName() { + + if (isConstructor()) { + if (getParent() != null) { + return getParent().getName(); + } else { + // If there is no parent use the original name + return new String(getNameContents()); + } + } else { + return null; + } + +} +/** + * @see DOMNode#getDetailedNode() + */ +//protected DOMNode getDetailedNode() { +// return (DOMNode)getFactory().createMethod(getContents()); +//} +/** + * @see IDOMMethod#getExceptions() + */ +public String[] getExceptions() { + return fExceptions; +} +/** + * @see IDOMNode#getJavaElement + */ +public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException { + if (parent.getElementType() == IJavaElement.TYPE) { + // translate parameter types to signatures + String[] sigs= null; + if (fParameterTypes != null) { + sigs= new String[fParameterTypes.length]; + int i; + for (i= 0; i < fParameterTypes.length; i++) { + sigs[i]= Signature.createTypeSignature(fParameterTypes[i].toCharArray(), false); + } + } + String name= null; + if (isConstructor()) { + name= getConstructorName(); + } else { + name= getName(); + } + return ((IType)parent).getMethod(name, sigs); + } else { + throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$ + } +} +/** + * @see DOMMember#getMemberDeclarationStartPosition() + */ +protected int getMemberDeclarationStartPosition() { + if (fReturnTypeRange[0] >= 0) { + return fReturnTypeRange[0]; + } else { + return fNameRange[0]; + } +} +/** + * @see IDOMNode#getName() + */ +public String getName() { + if (isConstructor()) { + return null; + } else { + return super.getName(); + } +} +/** + * @see IDOMNode#getNodeType() + */ +public int getNodeType() { + return IDOMNode.METHOD; +} +/** + * @see IDOMMethod#getParameterNames() + */ +public String[] getParameterNames() { + return fParameterNames; +} +/** + * @see IDOMMethod#getParameterTypes() + */ +public String[] getParameterTypes() { + return fParameterTypes; +} +/** + * @see IDOMMethod#getReturnType() + */ +public String getReturnType() { + if (isConstructor()) { + return null; + } else { + return fReturnType; + } +} +/** + * Returns the source code to be used for this method's return type + */ +protected char[] getReturnTypeContents() { + if (isConstructor()) { + return null; + } else { + if (isReturnTypeAltered()) { + return fReturnType.toCharArray(); + } else { + return CharArrayOps.subarray(fDocument, fReturnTypeRange[0], fReturnTypeRange[1] + 1 - fReturnTypeRange[0]); + } + + } +} +/** + * Returns true if this method's return type has + * array qualifiers ('[]') following the parameter list. + */ +protected boolean hasTrailingArrayQualifier() { + return fReturnTypeRange.length > 2; +} +/** + * @see IDOMMethod#isConstructor() + */ +public boolean isConstructor() { + return getMask(MASK_IS_CONSTRUCTOR); +} +/** + * Returns true if this method's return type has been altered + * from the original document contents. + */ +protected boolean isReturnTypeAltered() { + return getMask(MASK_RETURN_TYPE_ALTERED); +} +/** + * @see IDOMNode#isSigantureEqual(IDOMNode). + * + *

        Two methods have equal signatures if there names are the same + * and their parameter types are the same. + */ +public boolean isSignatureEqual(IDOMNode node) { + boolean ok= node.getNodeType() == getNodeType(); + if (ok) { + IDOMMethod method= (IDOMMethod)node; + ok = (isConstructor() && method.isConstructor()) || + (!isConstructor() && !method.isConstructor()); + if (ok && !isConstructor()) { + ok= getName().equals(method.getName()); + } + if (!ok) { + return false; + } + + String[] types= method.getParameterTypes(); + if (fParameterTypes == null || fParameterTypes.length == 0) { + // this method has no parameters + if (types == null || types.length == 0) { + // the other method has no parameters either + return true; + } + } else { + // this method has parameters + if (types == null || types.length == 0) { + // the other method has no parameters + return false; + } + if (fParameterTypes.length != types.length) { + // the methods have a different number of parameters + return false; + } + int i; + for (i= 0; i < types.length; i++) { + if (!fParameterTypes[i].equals(types[i])) { + return false; + } + } + return true; + } + } + return false; + +} +/** + * @see DOMNode + */ +protected DOMNode newDOMNode() { + return new DOMMethod(); +} +/** + * Offsets all the source indexes in this node by the given amount. + */ +protected void offset(int offset) { + super.offset(offset); + offsetRange(fBodyRange, offset); + offsetRange(fExceptionRange, offset); + offsetRange(fParameterRange, offset); + offsetRange(fReturnTypeRange, offset); +} +/** + * @see IDOMMethod#setBody + */ +public void setBody(String body) { + becomeDetailed(); + fragment(); + fBody= body; + setHasBody(body != null); + if (!hasBody()) { + fBody= ";"+Util.LINE_SEPARATOR; //$NON-NLS-1$ + } +} +/** + * Sets the end of the body range + */ +void setBodyRangeEnd(int end) { + fBodyRange[1] = end; +} +/** + * @see IDOMMethod#setConstructor(boolean) + */ +public void setConstructor(boolean b) { + becomeDetailed(); + setMask(MASK_IS_CONSTRUCTOR, b); + fragment(); +} +/** + * @see IDOMMethod#setExceptions(char[][]) + */ +public void setExceptions(String[] names) { + becomeDetailed(); + if (names == null || names.length == 0) { + fExceptions= null; + } else { + fExceptions= names; + CharArrayBuffer buffer = new CharArrayBuffer(); + char[] comma = new char[] {',', ' '}; + for (int i = 0, length = names.length; i < length; i++) { + if (i > 0) + buffer.append(comma); + buffer.append(names[i]); + } + fExceptionList= buffer.getContents(); + } + fragment(); +} +/** + * @see IDOMMethod#setName + */ +public void setName(String name) { + if (name == null) { + throw new IllegalArgumentException(Util.bind("element.nullName")); //$NON-NLS-1$ + } else { + super.setName(name); + } +} +/** + * @see IDOMMethod#setParameters(char[][], char[][]) + */ +public void setParameters(String[] types, String[] names) throws IllegalArgumentException { + becomeDetailed(); + if (types== null || names == null) { + if (types == null && names == null) { + fParameterTypes= null; + fParameterNames= null; + fParameterList= new char[] {'(',')'}; + } else { + throw new IllegalArgumentException(Util.bind("dom.mismatchArgNamesAndTypes")); //$NON-NLS-1$ + } + } else if (names.length != types.length) { + throw new IllegalArgumentException(Util.bind("dom.mismatchArgNamesAndTypes")); //$NON-NLS-1$ + } else if (names.length == 0) { + setParameters(null, null); + } else { + fParameterNames= names; + fParameterTypes= types; + CharArrayBuffer parametersBuffer = new CharArrayBuffer(); + parametersBuffer.append("("); //$NON-NLS-1$ + char[] comma = new char[] {',', ' '}; + for (int i = 0; i < names.length; i++) { + if (i > 0) { + parametersBuffer.append(comma); + } + parametersBuffer + .append(types[i]) + .append(' ') + .append(names[i]); + } + parametersBuffer.append(')'); + fParameterList= parametersBuffer.getContents(); + } + fragment(); +} +/** + * @see IDOMMethod#setReturnType(char[]) + */ +public void setReturnType(String name) throws IllegalArgumentException { + if (name == null) { + throw new IllegalArgumentException(Util.bind("dom.nullReturnType")); //$NON-NLS-1$ + } + becomeDetailed(); + fragment(); + setReturnTypeAltered(true); + fReturnType= name; +} +/** + * Sets the state of this method declaration as having + * the return type altered from the original document. + */ +protected void setReturnTypeAltered(boolean typeAltered) { + setMask(MASK_RETURN_TYPE_ALTERED, typeAltered); +} +/** + */ +protected void setSourceRangeEnd(int end) { + super.setSourceRangeEnd(end); + fBodyRange[1]= end; +} +/** + * @see DOMNode#shareContents(DOMNode) + */ +protected void shareContents(DOMNode node) { + super.shareContents(node); + DOMMethod method= (DOMMethod)node; + fBody= method.fBody; + fBodyRange= rangeCopy(method.fBodyRange); + fExceptionList= method.fExceptionList; + fExceptionRange= rangeCopy(method.fExceptionRange); + fExceptions= method.fExceptions; + fParameterList= method.fParameterList; + fParameterNames= method.fParameterNames; + fParameterRange= rangeCopy(method.fParameterRange); + fParameterTypes= method.fParameterTypes; + fReturnType= method.fReturnType; + fReturnTypeRange= rangeCopy(method.fReturnTypeRange); +} +/** + * @see IDOMNode#toString() + */ +public String toString() { + if (isConstructor()) { + return "CONSTRUCTOR"; //$NON-NLS-1$ + } else { + return "METHOD: " + getName(); //$NON-NLS-1$ + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMNode.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMNode.java new file mode 100644 index 0000000..833adf9 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMNode.java @@ -0,0 +1,971 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import java.util.Enumeration; + +import net.sourceforge.phpdt.core.jdom.DOMException; +import net.sourceforge.phpdt.core.jdom.DOMFactory; +import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit; +import net.sourceforge.phpdt.core.jdom.IDOMFactory; +import net.sourceforge.phpdt.core.jdom.IDOMMethod; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpdt.internal.core.util.CharArrayBuffer; + +/** + * DOMNode provides an implementation for IDOMNode. + * + *

        A node represents a document fragment. When a node is created, its + * contents are located in a contiguous range of a shared document. A shared + * document is a char array, and is shared in the sense that the contents of other + * document fragments may also be contained in the array. + * + *

        A node maintains indicies of relevant portions of its contents + * in the shared document. Thus the original document and indicies create a + * form from which to generate the contents of the document fragment. As attributes + * of a node are changed, the node attempts to maintain the original formatting + * by only replacing relevant portions of the shared document with the value + * of new attributes (that is, filling in the form with replacement values). + * + *

        When a node is first created, it is considered unfragmented. When any + * attribute of the node is altered, the node is then considered fragmented + * from that point on. A node is also considered fragmented if any of its + * descendants are fragmented. When a node is unfragmented, the contents of the + * node can be efficiently generated from the original shared document. When + * a node is fragmented, the contents of the node must be created using the + * original document and indicies as a form, filling in replacement values + * as required. + * + *

        Generally, a node's contents consists of complete lines in a shared document. + * The contents of the node are normalized on creation to include any whitespace + * preceding the node on the line where the node begins, and to include and trailing + * whitespace up to the line where the next node begins. Any trailing // comments + * that begin on the line where the current node ends, are considered part of that + * node. + * + * @see IDOMNode + */ +public abstract class DOMNode implements IDOMNode { + + /** + * The first child of this node - null + * when this node has no children. (Children of a node + * are implemented as a doubly linked list). + */ + protected DOMNode fFirstChild= null; + + /** + * The last child of this node - null + * when this node has no children. Used for efficient + * access to the last child when adding new children + * at the end of the linked list of children. + */ + protected DOMNode fLastChild= null; + + /** + * The sibling node following this node - null + * for the last node in the sibling list. + */ + protected DOMNode fNextNode= null; + + /** + * The parent of this node. A null + * parent indicates that this node is a root + * node of a document fragment. + */ + protected DOMNode fParent= null; + + /** + * The sibling node preceding this node - null + * for the first node in the sibling list. + */ + protected DOMNode fPreviousNode= null; + + /** + * True when this node has attributes that have + * been altered from their original state in the + * shared document, or when the attributes of a + * descendant have been altered. False when the + * contents of this node and all descendants are + * consistent with the content of the shared + * document. + */ + protected boolean fIsFragmented= false; + + /** + * The name of this node. For efficiency, the + * name of a node is duplicated in this variable + * on creation, rather than always having to fetch + * the name from the shared document. + */ + protected String fName= null; + + /** + * The original inclusive indicies of this node's name in + * the shared document. Values of -1 indiciate the name + * does not exist in the document. + */ + protected int[] fNameRange; + + /** + * The shared document that the contents for this node + * are contained in. Attribute indicies are positions + * in this character array. + */ + protected char[] fDocument= null; + + /** + * The original entire inclusive range of this node's contents + * within its document. Values of -1 indicate the contents + * of this node do not exist in the document. + */ + protected int[] fSourceRange; + + /** + * The current state of bit masks defined by this node. + * Initially all bit flags are turned off. All bit masks + * are defined by this class to avoid overlap, although + * bit masks are node type specific. + * + * @see #setMask + * @see #getMask + */ + protected int fStateMask= 0; + + /** + * This position is the position of the end of the last line separator before the closing brace starting + * position of the receiver. + */ + protected int fInsertionPosition; + + /** + * A bit mask indicating this field has an initializer + * expression + */ + protected static final int MASK_FIELD_HAS_INITIALIZER= 0x00000001; + + /** + * A bit mask indicating this field is a secondary variable + * declarator for a previous field declaration. + */ + protected static final int MASK_FIELD_IS_VARIABLE_DECLARATOR= 0x00000002; + + /** + * A bit mask indicating this field's type has been + * altered from its original contents in the document. + */ + protected static final int MASK_FIELD_TYPE_ALTERED= 0x00000004; + + /** + * A bit mask indicating this node's name has been + * altered from its original contents in the document. + */ + protected static final int MASK_NAME_ALTERED= 0x00000008; + + /** + * A bit mask indicating this node currently has a + * body. + */ + protected static final int MASK_HAS_BODY= 0x00000010; + + /** + * A bit mask indicating this node currently has a + * preceding comment. + */ + protected static final int MASK_HAS_COMMENT= 0x00000020; + + /** + * A bit mask indicating this method is a constructor. + */ + protected static final int MASK_IS_CONSTRUCTOR= 0x00000040; + + /** + * A bit mask indicating this type is a class. + */ + protected static final int MASK_TYPE_IS_CLASS= 0x00000080; + + /** + * A bit mask indicating this type has a superclass + * (requires or has an 'extends' clause). + */ + protected static final int MASK_TYPE_HAS_SUPERCLASS= 0x00000100; + + /** + * A bit mask indicating this type implements + * or extends some interfaces + */ + protected static final int MASK_TYPE_HAS_INTERFACES= 0x00000200; + + /** + * A bit mask indicating this return type of this method has + * been altered from the original contents. + */ + protected static final int MASK_RETURN_TYPE_ALTERED= 0x00000400; + + /** + * A bit mask indicating this node has detailed source indexes + */ + protected static final int MASK_DETAILED_SOURCE_INDEXES = 0x00000800; + +/** + * Creates a new empty document fragment. + */ +DOMNode() { + fName= null; + fDocument= null; + fSourceRange= new int[]{-1, -1}; + fNameRange= new int[]{-1, -1}; + fragment(); +} +/** + * Creates a new document fragment on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * Contents start on and include the character at the first position. + * Contents end on and include the character at the last position. + * An array of -1's indicates this node's contents do not exist + * in the document. + * @param name - the identifier portion of the name of this node, or + * null if this node does not have a name + * @param nameRange - a two element array of integers describing the + * entire inclusive source range of this node's name within its document, + * including any array qualifiers that might immediately follow the name + * or -1's if this node does not have a name. + */ +DOMNode(char[] document, int[] sourceRange, String name, int[] nameRange) { + super(); + fDocument= document; + fSourceRange= sourceRange; + fName= name; + fNameRange= nameRange; + +} +/** + * Adds the given un-parented node (document fragment) as the last child of + * this node. + * + *

        When a child is added, this node must be considered fragmented such that + * the contents of this node are properly generated. + * + * @see IDOMNode#addChild(IDOMNode) + */ +public void addChild(IDOMNode child) throws IllegalArgumentException, DOMException { + basicAddChild(child); + + // if the node is a constructor, it must also be fragmented to update the constructor's name + if (child.getNodeType() == IDOMNode.METHOD && ((IDOMMethod)child).isConstructor()) { + ((DOMNode)child).fragment(); + } else { + fragment(); + } +} +/** + * Appends the current contents of this document fragment + * to the given CharArrayBuffer. + * + *

        If this node is fragmented, contents must be generated by + * using the original document and indicies as a form for the current + * attribute values of this node. If this node not fragmented, the + * contents can be obtained from the document. + * + */ +protected void appendContents(CharArrayBuffer buffer) { + if (isFragmented()) { + appendFragmentedContents(buffer); + } else { + buffer.append(fDocument, fSourceRange[0], fSourceRange[1] + 1 - fSourceRange[0]); + } +} +/** + * Appends the contents of all children of this node to the + * given CharArrayBuffer. + * + *

        This algorithm used minimizes String generation by merging + * adjacent unfragmented children into one substring operation. + * + */ +protected void appendContentsOfChildren(CharArrayBuffer buffer) { + DOMNode child= fFirstChild; + DOMNode sibling; + + int start= 0, end= 0; + if (child != null) { + start= child.getStartPosition(); + end= child.getEndPosition(); + } + while (child != null) { + sibling= child.fNextNode; + if (sibling != null) { + if (sibling.isContentMergableWith(child)) { + end= sibling.getEndPosition(); + } else { + if (child.isFragmented()) { + child.appendContents(buffer); + } else { + buffer.append(child.getDocument(), start, end + 1 - start); + } + start= sibling.getStartPosition(); + end= sibling.getEndPosition(); + } + } else { + if (child.isFragmented()) { + child.appendContents(buffer); + } else { + buffer.append(child.getDocument(), start, end + 1 - start); + } + } + child= sibling; + } +} +/** + * Appends the contents of this node to the given CharArrayBufer, using + * the original document and indicies as a form for the current attribute + * values of this node. + */ +protected abstract void appendFragmentedContents(CharArrayBuffer buffer); +/** + * Adds the given un-parented node (document fragment) as the last child of + * this node without setting this node's 'fragmented' flag. This + * method is only used by the DOMBuilder when creating a new DOM such + * that a new DOM is unfragmented. + */ +void basicAddChild(IDOMNode child) throws IllegalArgumentException, DOMException { + // verify child may be added + if (!canHaveChildren()) { + throw new DOMException(Util.bind("dom.unableAddChild")); //$NON-NLS-1$ + } + if (child == null) { + throw new IllegalArgumentException(Util.bind("dom.addNullChild")); //$NON-NLS-1$ + } + if (!isAllowableChild(child)) { + throw new DOMException(Util.bind("dom.addIncompatibleChild")); //$NON-NLS-1$ + } + if (child.getParent() != null) { + throw new DOMException(Util.bind("dom.addChildWithParent")); //$NON-NLS-1$ + } + /* NOTE: To test if the child is an ancestor of this node, we + * need only test if the root of this node is the child (the child + * is already a root since we have just guarenteed it has no parent). + */ + if (child == getRoot()) { + throw new DOMException(Util.bind("dom.addAncestorAsChild")); //$NON-NLS-1$ + } + + DOMNode node= (DOMNode)child; + + // if the child is not already part of this document, localize its contents + // before adding it to the tree + if (node.getDocument() != getDocument()) { + node.localizeContents(); + } + + // add the child last + if (fFirstChild == null) { + // this is the first and only child + fFirstChild= node; + } else { + fLastChild.fNextNode= node; + node.fPreviousNode= fLastChild; + } + fLastChild= node; + node.fParent= this; +} +/** + * Generates detailed source indexes for this node if possible. + * + * @exception DOMException if unable to generate detailed source indexes + * for this node + */ +protected void becomeDetailed() throws DOMException { + if (!isDetailed()) { + DOMNode detailed= getDetailedNode(); + if (detailed == null) { + throw new DOMException(Util.bind("dom.cannotDetail")); //$NON-NLS-1$ + } + if (detailed != this) { + shareContents(detailed); + } + } +} +/** + * Returns true if this node is allowed to have children, otherwise false. + * + *

        Default implementation of IDOMNode interface method returns false; this + * method must be overridden by subclasses that implement nodes that allow + * children. + * + * @see IDOMNode#canHaveChildren() + */ +public boolean canHaveChildren() { + return false; +} +/** + * @see IDOMNode#clone() + */ +public Object clone() { + + // create a new buffer with all my contents and children contents + int length= 0; + char[] buffer= null; + int offset= fSourceRange[0]; + + if (offset >= 0) { + length= fSourceRange[1] - offset + 1; + buffer= new char[length]; + System.arraycopy(fDocument, offset, buffer, 0, length); + } + DOMNode clone= newDOMNode(); + clone.shareContents(this); + clone.fDocument = buffer; + + if (offset > 0) { + clone.offset(0 - offset); + } + + // clone my children + if (canHaveChildren()) { + Enumeration children= getChildren(); + while (children.hasMoreElements()) { + DOMNode child= (DOMNode)children.nextElement(); + if (child.fDocument == fDocument) { + DOMNode childClone= child.cloneSharingDocument(buffer, offset); + clone.basicAddChild(childClone); + } else { + DOMNode childClone= (DOMNode)child.clone(); + clone.addChild(childClone); + } + + } + } + + return clone; +} +private DOMNode cloneSharingDocument(char[] document, int rootOffset) { + + DOMNode clone = newDOMNode(); + clone.shareContents(this); + clone.fDocument = document; + if (rootOffset > 0) { + clone.offset(0 - rootOffset); + } + + if (canHaveChildren()) { + Enumeration children = getChildren(); + while (children.hasMoreElements()) { + DOMNode child = (DOMNode) children.nextElement(); + if (child.fDocument == fDocument) { + DOMNode childClone= child.cloneSharingDocument(document, rootOffset); + clone.basicAddChild(childClone); + } else { + DOMNode childClone= (DOMNode)child.clone(); + clone.addChild(childClone); + } + } + } + return clone; +} +/** + * Sets this node's fragmented flag and all ancestor fragmented flags + * to true. This happens when an attribute of this node or a descendant + * node has been altered. When a node is fragmented, its contents must + * be generated from its attributes and original "form" rather than + * from the original contents in the document. + */ +protected void fragment() { + if (!isFragmented()) { + fIsFragmented= true; + if (fParent != null) { + fParent.fragment(); + } + } +} +/** + * @see IDOMNode#getCharacters() + */ +public char[] getCharacters() { + CharArrayBuffer buffer= new CharArrayBuffer(); + appendContents(buffer); + return buffer.getContents(); +} +/** + * @see IDOMNode#getChild(String) + */ +public IDOMNode getChild(String name) { + DOMNode child = fFirstChild; + while (child != null) { + String n = child.getName(); + if (name == null) { + if (n == null) { + return child; + } + } else { + if (name.equals(n)) { + return child; + } + } + child = child.fNextNode; + } + return null; +} +/** + * @see IDOMNode#getChildren() + */ +public Enumeration getChildren() { + return new SiblingEnumeration(fFirstChild); +} +/** + * Returns the current contents of this document fragment, + * or null if this node has no contents. + * + *

        If this node is fragmented, contents must be generated by + * using the original document and indicies as a form for the current + * attribute values of this node. If this node not fragmented, the + * contents can be obtained from the document. + * + * @see IDOMNode#getContents() + */ +public String getContents() { + CharArrayBuffer buffer= new CharArrayBuffer(); + appendContents(buffer); + return buffer.toString(); +} +/** + * Returns a new document fragment representing this node with + * detailed source indexes. Subclasses that provide a detailed + * implementation must override this method. + */ +protected DOMNode getDetailedNode() { + return this; +} +/** + * Returns the document containing this node's original contents. + * The document may be shared by other nodes. + */ +protected char[] getDocument() { + return fDocument; +} +/** + * Returns the original position of the last character of this + * node's contents in its document. + */ +public int getEndPosition() { + return fSourceRange[1]; +} +/** + * Returns a factory with which to create new document fragments. + */ +protected IDOMFactory getFactory() { + return new DOMFactory(); +} +/** + * @see IDOMNode#getFirstChild() + */ +public IDOMNode getFirstChild() { + return fFirstChild; +} +/** + * Returns the position at which the first child of this node should be inserted. + */ +public int getInsertionPosition() { + return fInsertionPosition; +} +/** + * Returns true if the given mask of this node's state flag + * is turned on, otherwise false. + */ +protected boolean getMask(int mask) { + return (fStateMask & mask) > 0; +} +/** + * @see IDOMNode#getName() + */ +public String getName() { + return fName; +} +/** + * Returns the source code to be used for this node's name. + */ +protected char[] getNameContents() { + if (isNameAltered()) { + return fName.toCharArray(); + } else { + if (fName == null || fNameRange[0] < 0) { + return null; + } else { + int length = fNameRange[1] + 1 - fNameRange[0]; + char[] result = new char[length]; + System.arraycopy(fDocument, fNameRange[0], result, 0, length); + return result; + } + } +} +/** + * @see IDOMNode#getNextNode() + */ +public IDOMNode getNextNode() { + return fNextNode; +} +/** + * @see IDOMNode#getParent() + */ +public IDOMNode getParent() { + return fParent; +} +/** + * Answers a source position which corresponds to the end of the parent + * element's declaration. + */ +protected int getParentEndDeclaration() { + IDOMNode parent = getParent(); + if (parent == null) { + return 0; + } else { + if (parent instanceof IDOMCompilationUnit) { + return 0; + } else { + return ((DOMType)parent).getOpenBodyEnd(); + } + } +} +/** + * @see IDOMNode#getPreviousNode() + */ +public IDOMNode getPreviousNode() { + return fPreviousNode; +} +/** + * Returns the root node of this document fragment. + */ +protected IDOMNode getRoot() { + if (fParent == null) { + return this; + } else { + return fParent.getRoot(); + } +} +/** + * Returns the original position of the first character of this + * node's contents in its document. + */ +public int getStartPosition() { + return fSourceRange[0]; +} +/** + * @see IDOMNode#insertSibling(IDOMNode) + */ +public void insertSibling(IDOMNode sibling) throws IllegalArgumentException, DOMException { + // verify sibling may be added + if (sibling == null) { + throw new IllegalArgumentException(Util.bind("dom.addNullSibling")); //$NON-NLS-1$ + } + if (fParent == null) { + throw new DOMException(Util.bind("dom.addSiblingBeforeRoot")); //$NON-NLS-1$ + } + if (!fParent.isAllowableChild(sibling)) { + throw new DOMException(Util.bind("dom.addIncompatibleSibling")); //$NON-NLS-1$ + } + if (sibling.getParent() != null) { + throw new DOMException(Util.bind("dom.addSiblingWithParent")); //$NON-NLS-1$ + } + /* NOTE: To test if the sibling is an ancestor of this node, we + * need only test if the root of this node is the child (the sibling + * is already a root since we have just guaranteed it has no parent). + */ + if (sibling == getRoot()) { + throw new DOMException(Util.bind("dom.addAncestorAsSibling")); //$NON-NLS-1$ + } + + DOMNode node= (DOMNode)sibling; + + // if the sibling is not already part of this document, localize its contents + // before inserting it into the tree + if (node.getDocument() != getDocument()) { + node.localizeContents(); + } + + // insert the node + if (fPreviousNode == null) { + fParent.fFirstChild= node; + } else { + fPreviousNode.fNextNode= node; + } + node.fParent= fParent; + node.fPreviousNode= fPreviousNode; + node.fNextNode= this; + fPreviousNode= node; + + // if the node is a constructor, it must also be fragmented to update the constructor's name + if (node.getNodeType() == IDOMNode.METHOD && ((IDOMMethod)node).isConstructor()) { + node.fragment(); + } else { + fParent.fragment(); + } +} +/** + * @see IDOMNode + */ +public boolean isAllowableChild(IDOMNode node) { + return false; +} +/** + * Returns true if the contents of this node are from the same document as + * the given node, the contents of this node immediately follow the contents + * of the given node, and neither this node or the given node are fragmented - + * otherwise false. + */ +protected boolean isContentMergableWith(DOMNode node) { + return !node.isFragmented() && !isFragmented() && node.getDocument() == getDocument() && + node.getEndPosition() + 1 == getStartPosition(); +} +/** + * Returns true if this node has detailed source index information, + * or false if this node has limited source index information. To + * perform some manipulations, detailed indexes are required. + */ +protected boolean isDetailed() { + return getMask(MASK_DETAILED_SOURCE_INDEXES); +} +/** + * Returns true if this node's or a descendant node's contents + * have been altered since this node was created. This indicates + * that the contents of this node are no longer consistent with + * the contents of this node's document. + */ +protected boolean isFragmented() { + return fIsFragmented; +} +/** + * Returns true if this noed's name has been altered + * from the original document contents. + */ +protected boolean isNameAltered() { + return getMask(MASK_NAME_ALTERED); +} +/** + * @see IDOMNode#isSignatureEqual(IDOMNode). + * + *

        By default, the signatures of two nodes are equal if their + * type and names are equal. Node types that have other requirements + * for equality must override this method. + */ +public boolean isSignatureEqual(IDOMNode node) { + return getNodeType() == node.getNodeType() && getName().equals(node.getName()); +} +/** + * Localizes the contents of this node and all descendant nodes, + * such that this node is no longer dependent on its original + * document in order to generate its contents. This node and all + * descendant nodes become unfragmented and share a new + * document. + */ +protected void localizeContents() { + + DOMNode clone= (DOMNode)clone(); + shareContents(clone); + +} +/** + * Returns a new empty DOMNode for this instance. + */ +protected abstract DOMNode newDOMNode(); +/** + * Normalizes this DOMNode's source positions to include whitespace preceeding + * the node on the line on which the node starts, and all whitespace after the node up to + * the next node's start + */ +void normalize(ILineStartFinder finder) { + if (getPreviousNode() == null) + normalizeStartPosition(getParentEndDeclaration(), finder); + + // Set the children's position + if (canHaveChildren()) { + Enumeration children = getChildren(); + while(children.hasMoreElements()) + ((DOMNode)children.nextElement()).normalize(finder); + } + + normalizeEndPosition(finder, (DOMNode)getNextNode()); +} +/** + * Normalizes this DOMNode's end position. + */ +void normalizeEndPosition(ILineStartFinder finder, DOMNode next) { + if (next == null) { + // this node's end position includes all of the characters up + // to the end of the enclosing node + DOMNode parent = (DOMNode) getParent(); + if (parent == null || parent instanceof DOMCompilationUnit) { + setSourceRangeEnd(fDocument.length - 1); + } else { + // parent is a type + int temp = ((DOMType)parent).getCloseBodyPosition() - 1; + setSourceRangeEnd(temp); + fInsertionPosition = Math.max(finder.getLineStart(temp + 1), getEndPosition()); + } + } else { + // this node's end position is just before the start of the next node + int temp = next.getStartPosition() - 1; + fInsertionPosition = Math.max(finder.getLineStart(temp + 1), getEndPosition()); + next.normalizeStartPosition(getEndPosition(), finder); + setSourceRangeEnd(next.getStartPosition() - 1); + } +} +/** + * Normalizes this DOMNode's start position. + */ +void normalizeStartPosition(int previousEnd, ILineStartFinder finder) { + int nodeStart = getStartPosition(); + int lineStart = finder.getLineStart(nodeStart); + if (nodeStart > lineStart && (lineStart > previousEnd || (previousEnd == 0 && lineStart == 0))) + setStartPosition(lineStart); +} +/** + * Offsets all the source indexes in this node by the given amount. + */ +protected void offset(int offset) { + offsetRange(fNameRange, offset); + offsetRange(fSourceRange, offset); +} +/** + * Offsets the source range by the given amount + */ +protected void offsetRange(int[] range, int offset) { + for (int i= 0; i < range.length; i++) { + range[i]+=offset; + if (range[i] < 0) { + range[i]= -1; + } + } +} +/** + * Returns a copy of the given range. + */ +protected int[] rangeCopy(int[] range) { + int[] copy= new int[range.length]; + for (int i= 0; i < range.length; i++) { + copy[i]= range[i]; + } + return copy; +} +/** + * Separates this node from its parent and siblings, maintaining any ties that + * this node has to the underlying document fragment. + * + *

        When a child is removed, its parent is fragmented such that it properly + * generates its contents. + * + * @see IDOMNode#remove() + */ +public void remove() { + + if (fParent != null) { + fParent.fragment(); + } + + // link siblings + if (fNextNode != null) { + fNextNode.fPreviousNode= fPreviousNode; + } + if (fPreviousNode != null) { + fPreviousNode.fNextNode= fNextNode; + } + // fix parent's pointers + if (fParent != null) { + if (fParent.fFirstChild == this) { + fParent.fFirstChild= fNextNode; + } + if (fParent.fLastChild == this) { + fParent.fLastChild= fPreviousNode; + } + } + // remove myself + fParent= null; + fNextNode= null; + fPreviousNode= null; +} +/** + * Sets the specified mask of this node's state mask on or off + * based on the boolean value - true -> on, false -> off. + */ +protected void setMask(int mask, boolean on) { + if (on) { + fStateMask |= mask; + } else { + fStateMask &= ~mask; + } +} +/** + * @see IDOMNode#setName + */ +public void setName(String name) { + fName= name; + setNameAltered(true); + fragment(); +} +/** + * Sets the state of this node as having + * its name attribute altered from the original + * document contents. + */ +protected void setNameAltered(boolean altered) { + setMask(MASK_NAME_ALTERED, altered); +} +/** + * Sets the original position of the last character of this node's contents + * in its document. This method is only used during DOM creation while + * normalizing the source range of each node. + */ +protected void setSourceRangeEnd(int end) { + fSourceRange[1]= end; +} +/** + * Sets the original position of the first character of this node's contents + * in its document. This method is only used during DOM creation while + * normalizing the source range of each node. + */ +protected void setStartPosition(int start) { + fSourceRange[0]= start; +} +/** + * Sets the contents of this node and descendant nodes to be the + * (identical) contents of the given node and its descendants. This + * does not effect this node's parent and sibling configuration, + * only the contents of this node. This is used only to localize + * the contents of this node. + */ +protected void shareContents(DOMNode node) { + fDocument= node.fDocument; + fIsFragmented= node.fIsFragmented; + fName= node.fName; + fNameRange= rangeCopy(node.fNameRange); + fSourceRange= rangeCopy(node.fSourceRange); + fStateMask= node.fStateMask; + + + if (canHaveChildren()) { + Enumeration myChildren= getChildren(); + Enumeration otherChildren= node.getChildren(); + DOMNode myChild, otherChild; + while (myChildren.hasMoreElements()) { + myChild= (DOMNode)myChildren.nextElement(); + otherChild= (DOMNode)otherChildren.nextElement(); + myChild.shareContents(otherChild); + } + } +} +/** + * Returns a String representing this node - for Debug purposes only. + */ +public abstract String toString(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMPackage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMPackage.java new file mode 100644 index 0000000..0b80fc7 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMPackage.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.core.jdom.IDOMPackage; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpdt.internal.core.util.CharArrayBuffer; + +/** + * DOMPackage provides an implementation of IDOMPackage. + * + * @see IDOMPackage + * @see DOMNode + */ +class DOMPackage extends DOMNode implements IDOMPackage { + +/** + * Creates an empty PACKAGE node. + */ +DOMPackage() { + setMask(MASK_DETAILED_SOURCE_INDEXES, true); +} +/** + * Creates a new simple PACKAGE document fragment on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * Contents start on and include the character at the first position. + * Contents end on and include the character at the last position. + * An array of -1's indicates this node's contents do not exist + * in the document. + * @param name - the identifier portion of the name of this node, or + * null if this node does not have a name + */ +DOMPackage(char[] document, int[] sourceRange, String name) { + super(document, sourceRange, name, new int[] {-1, -1}); + setMask(MASK_DETAILED_SOURCE_INDEXES, false); +} +/** + * Creates a new detailed PACKAGE document fragment on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * Contents start on and include the character at the first position. + * Contents end on and include the character at the last position. + * An array of -1's indicates this node's contents do not exist + * in the document. + * @param name - the identifier portion of the name of this node, or + * null if this node does not have a name + * @param nameRange - a two element array of integers describing the + * entire inclusive source range of this node's name within its document, + * including any array qualifiers that might immediately follow the name + * or -1's if this node does not have a name. + */ +DOMPackage(char[] document, int[] sourceRange, String name, int[] nameRange) { + super(document, sourceRange, name, nameRange); + setMask(MASK_DETAILED_SOURCE_INDEXES, true); +} +/** + * @see DOMNode#appendFragmentedContents(CharArrayBuffer) + */ +protected void appendFragmentedContents(CharArrayBuffer buffer) { + if (fNameRange[0] < 0) { + buffer + .append("package ") //$NON-NLS-1$ + .append(fName) + .append(';') + .append(Util.LINE_SEPARATOR) + .append(Util.LINE_SEPARATOR); + } else { + buffer + .append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0]) + .append(fName) + .append(fDocument, fNameRange[1] + 1, fSourceRange[1] - fNameRange[1]); + } +} +/** + * @see IDOMNode#getContents() + */ +public String getContents() { + if (fName == null) { + return null; + } else { + return super.getContents(); + } +} +/** + * @see DOMNode#getDetailedNode() + */ +//protected DOMNode getDetailedNode() { +// return (DOMNode)getFactory().createPackage(getContents()); +//} +/** + * @see IDOMNode#getJavaElement + */ +public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException { + if (parent.getElementType() == IJavaElement.COMPILATION_UNIT) { + return ((ICompilationUnit)parent).getPackageDeclaration(getName()); + } else { + throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$ + } +} +/** + * @see IDOMNode#getNodeType() + */ +public int getNodeType() { + return IDOMNode.PACKAGE; +} +/** + * @see DOMNode + */ +protected DOMNode newDOMNode() { + return new DOMPackage(); +} +/** + * @see IDOMNode#setName + */ +public void setName(String name) { + becomeDetailed(); + super.setName(name); +} +/** + * @see IDOMNode#toString() + */ +public String toString() { + return "PACKAGE: " + getName(); //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMType.java new file mode 100644 index 0000000..0ec3b3f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMType.java @@ -0,0 +1,721 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import java.util.Enumeration; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.compiler.ITerminalSymbols; +import net.sourceforge.phpdt.core.compiler.InvalidInputException; +import net.sourceforge.phpdt.core.jdom.IDOMMethod; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.core.jdom.IDOMType; +import net.sourceforge.phpdt.internal.compiler.parser.Scanner; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpdt.internal.core.util.CharArrayBuffer; +import net.sourceforge.phpdt.internal.core.util.CharArrayOps; + +/** + * DOMType provides an implementation of IDOMType. + * + * @see IDOMType + * @see DOMNode + */ + +/* package */ class DOMType extends DOMMember implements IDOMType { + + /** + * The 'class' or 'interface' keyword if altered + * from the documents contents, otherwise null. + */ + protected String fTypeKeyword; + + /** + * The original inclusive source range of the 'class' + * or 'interface' keyword in the document. + */ + protected int[] fTypeRange; + + /** + * The superclass name for the class declaration + * if altered from the document's contents, otherwise + * null. Also null when this + * type represents an interface. + */ + protected String fSuperclass; + + /** + * The original inclusive source range of the superclass + * name in the document, or -1's of no superclass was + * specified in the document. + */ + protected int[] fSuperclassRange; + + + /** + * The original inclusive souce range of the 'extends' keyword + * in the document, including surrounding whitespace, or -1's if + * the keyword was not present in the document. + */ + protected int[] fExtendsRange; + + /** + * The original inclusive souce range of the 'implements' keyword + * in the document, including surrounding whitespace, or -1's if + * the keyword was not present in the document. + */ + protected int[] fImplementsRange; + + /** + * The comma delimited list of interfaces this type implements + * or extends, if altered from the document's contents, otherwise + * null. Also null if this type does + * not implement or extend any interfaces. + */ + protected char[] fInterfaces; + + /** + * The original inclusive source range of the list of interfaces this + * type implements or extends, not including any surrouding whitespace. + * If the document did not specify interfaces, this array contains -1's. + */ + protected int[] fInterfacesRange; + + + + /** + * The original source range of the first character following the + * type name superclass name, or interface list, up to and including + * the first character before the first type member. + */ + protected int[] fOpenBodyRange; + + /** + * The original source range of the first new line or non whitespace + * character preceding the close brace of the type's body, up to the + * and including the first character before the next node (if there are + * no following nodes, the range ends at the position of the last + * character in the document). + */ + protected int[] fCloseBodyRange; + + /** + * A list of interfaces this type extends or implements. + * null when this type does not extend + * or implement any interfaces. + */ + protected String[] fSuperInterfaces= new String[0]; + + /** + * This position is the position of the end of the last line separator before the closing brace starting + * position of the receiver. + */ +// protected int fInsertionPosition; + +/** + * Constructs an empty type node. + */ +DOMType() { + +} +/** + * Creates a new detailed TYPE document fragment on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * Contents start on and include the character at the first position. + * Contents end on and include the character at the last position. + * An array of -1's indicates this node's contents do not exist + * in the document. + * @param name - the identifier portion of the name of this node, or + * null if this node does not have a name + * @param nameRange - a two element array of integers describing the + * entire inclusive source range of this node's name within its document, + * including any array qualifiers that might immediately follow the name + * or -1's if this node does not have a name. + * @param commentRange - a two element array describing the comments that precede + * the member declaration. The first matches the start of this node's + * sourceRange, and the second is the new-line or first non-whitespace + * character following the last comment. If no comments are present, + * this array contains two -1's. + * @param flags - an integer representing the modifiers for this member. The + * integer can be analyzed with org.eclipse.jdt.core.Flags + * @param modifierRange - a two element array describing the location of + * modifiers for this member within its source range. The first integer + * is the first character of the first modifier for this member, and + * the second integer is the last whitespace character preceeding the + * next part of this member declaration. If there are no modifiers present + * in this node's source code (that is, package default visibility), this array + * contains two -1's. + * @param typeRange - a two element array describing the location of the 'class' + * or 'interface' keyword in the type declaration - first and last character + * positions. + * @param superclassRange - a two element array describing the location of the + * superclass name in the type declaration - first and last character + * positions or two -1's if a superclass is not present in the document. + * @param extendsRange - a two element array describing the location of the + * 'extends' keyword in the type declaration, including any surrounding + * whitespace, or -1's if the 'extends' keyword is not present in the document. + * @param implementsList - an array of names of the interfaces this type implements + * or extends, or null if this type does not implement or extend + * any interfaces. + * @param implementsRange - a two element array describing the location of the + * comment delimited list of interfaces this type implements or extends, + * not including any surrounding whitespace, or -1's if no interface list + * is present in the document. + * @param implementsKeywordRange - a two element array describing the location of the + * 'implements' keyword, including any surrounding whitespace, or -1's if no + * 'implements' keyword is present in the document. + * @param openBodyRange - a two element array describing the location of the + * open brace of the type's body and whitespace following the type declaration + * and preceeding the first member in the type. + * @param closeBodyRange - a two element array describing the source range of the + * first new line or non whitespace character preceeding the close brace of the + * type's body, up to the close brace + * @param isClass - true is the type is a class, false if it is an interface + */ +DOMType(char[] document, int[] sourceRange, String name, int[] nameRange, int[] commentRange, int flags, int[] modifierRange, int[] typeRange, int[] superclassRange, int[] extendsRange, String[] implementsList, int[] implementsRange, int[] implementsKeywordRange, int[] openBodyRange, int[] closeBodyRange, boolean isClass) { + super(document, sourceRange, name, nameRange, commentRange, flags, modifierRange); + + fTypeRange= typeRange; + setMask(MASK_TYPE_IS_CLASS, isClass); + + fExtendsRange= extendsRange; + fImplementsRange= implementsKeywordRange; + fSuperclassRange= superclassRange; + fInterfacesRange= implementsRange; + fCloseBodyRange= closeBodyRange; + setMask(MASK_TYPE_HAS_SUPERCLASS, superclassRange[0] > 0); + setMask(MASK_TYPE_HAS_INTERFACES, implementsList != null); + fSuperInterfaces= implementsList; + fOpenBodyRange= openBodyRange; + fCloseBodyRange= closeBodyRange; + setMask(MASK_DETAILED_SOURCE_INDEXES, true); + +} +/** + * Creates a new simple TYPE document fragment on the given range of the document. + * + * @param document - the document containing this node's original contents + * @param sourceRange - a two element array of integers describing the + * entire inclusive source range of this node within its document. + * Contents start on and include the character at the first position. + * Contents end on and include the character at the last position. + * An array of -1's indicates this node's contents do not exist + * in the document. + * @param name - the identifier portion of the name of this node, or + * null if this node does not have a name + * @param nameRange - a two element array of integers describing the + * entire inclusive source range of this node's name within its document, + * including any array qualifiers that might immediately follow the name + * or -1's if this node does not have a name. + * @param flags - an integer representing the modifiers for this member. The + * integer can be analyzed with org.eclipse.jdt.core.Flags + * @param implementsList - an array of names of the interfaces this type implements + * or extends, or null if this type does not implement or extend + * any interfaces. + * @param isClass - true is the type is a class, false if it is an interface + */ +DOMType(char[] document, int[] sourceRange, String name, int[] nameRange, int flags, String[] implementsList, boolean isClass) { + this(document, sourceRange, name, nameRange, new int[] {-1, -1}, flags, + new int[] {-1, -1}, new int[] {-1, -1}, new int[] {-1, -1}, new int[] {-1, -1}, + implementsList, new int[] {-1, -1}, new int[] {-1, -1}, new int[] {-1, -1}, new int[] {sourceRange[1], sourceRange[1]}, isClass); + setMask(MASK_DETAILED_SOURCE_INDEXES, false); +} +/** + * @see IDOMType#addSuperInterface(String) + */ +public void addSuperInterface(String name) throws IllegalArgumentException { + if (name == null) { + throw new IllegalArgumentException(Util.bind("dom.addNullInterface")); //$NON-NLS-1$ + } + if (fSuperInterfaces == null) { + fSuperInterfaces= new String[1]; + fSuperInterfaces[0]= name; + } else { + fSuperInterfaces= appendString(fSuperInterfaces, name); + } + setSuperInterfaces(fSuperInterfaces); +} +/** + * @see DOMMember#appendMemberBodyContents(CharArrayBuffer) + */ +protected void appendMemberBodyContents(CharArrayBuffer buffer) { + buffer.append(fDocument, fOpenBodyRange[0], fOpenBodyRange[1] + 1 - fOpenBodyRange[0]); + appendContentsOfChildren(buffer); + buffer.append(fDocument, fCloseBodyRange[0], fCloseBodyRange[1] + 1 - fCloseBodyRange[0]); + buffer.append(fDocument, fCloseBodyRange[1] + 1, fSourceRange[1] - fCloseBodyRange[1]); +} +/** + * @see DOMMember#appendMemberDeclarationContents(CharArrayBuffer ) + */ +protected void appendMemberDeclarationContents(CharArrayBuffer buffer) { + + if (fTypeKeyword != null) { + buffer.append(fTypeKeyword); + buffer.append(fDocument, fTypeRange[1], fNameRange[0] - fTypeRange[1] ); + } else { + buffer.append(fDocument, fTypeRange[0], fTypeRange[1] + 1 - fTypeRange[0]); + } + + buffer.append(getName()); + + if (isClass()) { + boolean hasSuperclass = false, hasInterfaces = false; + if (getMask(MASK_TYPE_HAS_SUPERCLASS)) { + hasSuperclass = true; + if (fExtendsRange[0] < 0) { + buffer.append(" extends "); //$NON-NLS-1$ + } else { + buffer.append(fDocument, fExtendsRange[0], fExtendsRange[1] + 1 - fExtendsRange[0]); + } + if (fSuperclass != null) { + buffer.append(fSuperclass); + } else { + buffer.append(fDocument, fSuperclassRange[0], fSuperclassRange[1] + 1 - fSuperclassRange[0]); + } + } + if (getMask(MASK_TYPE_HAS_INTERFACES)) { + hasInterfaces = true; + if (fImplementsRange[0] < 0) { + buffer.append(" implements "); //$NON-NLS-1$ + } else { + buffer.append(fDocument, fImplementsRange[0], fImplementsRange[1] + 1 - fImplementsRange[0]); + } + if (fInterfaces != null) { + buffer.append(fInterfaces); + } else { + buffer.append(fDocument, fInterfacesRange[0], fInterfacesRange[1] + 1 - fInterfacesRange[0]); + } + } + if (hasInterfaces) { + if (fImplementsRange[0] < 0) { + buffer.append(' '); + } else { + buffer.append(fDocument, fInterfacesRange[1] + 1, fOpenBodyRange[0] - fInterfacesRange[1] - 1); + } + } else { + if (hasSuperclass) { + if (fSuperclassRange[0] < 0) { + buffer.append(' '); + } else { + buffer.append(fDocument, fSuperclassRange[1] + 1, fOpenBodyRange[0] - fSuperclassRange[1] - 1); + } + } else { + buffer.append(fDocument, fNameRange[1] + 1, fOpenBodyRange[0] - fNameRange[1] - 1); + } + } + } else { + if (getMask(MASK_TYPE_HAS_INTERFACES)) { + if (fExtendsRange[0] < 0) { + buffer.append(" extends "); //$NON-NLS-1$ + } else { + buffer.append(fDocument, fExtendsRange[0], fExtendsRange[1] + 1 - fExtendsRange[0]); + } + if (fInterfaces != null) { + buffer.append(fInterfaces); + buffer.append(' '); + } else { + buffer.append(fDocument, fInterfacesRange[0], fInterfacesRange[1] + 1 - fInterfacesRange[0]); + } + } else { + buffer.append(fDocument, fNameRange[1] + 1, fOpenBodyRange[0] - fNameRange[1] - 1); + } + } + +} +/** + * @see DOMNode#appendSimpleContents(CharArrayBuffer) + */ +protected void appendSimpleContents(CharArrayBuffer buffer) { + // append eveything before my name + buffer.append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0]); + // append my name + buffer.append(fName); + + + // append everything after my name and before my first child + buffer.append(fDocument, fNameRange[1] + 1, fOpenBodyRange[1] - fNameRange[1]); + // append my children + appendContentsOfChildren(buffer); + // append from my last child to my end + buffer.append(fDocument, fCloseBodyRange[0], fSourceRange[1] - fCloseBodyRange[0] + 1); + + +} +/** + * @see IDOMNode#canHaveChildren() + */ +public boolean canHaveChildren() { + return true; +} +/** + * Returns the position of the closing brace for the body of this type. + * This value this method returns is only valid before the type has + * been normalized and is present only for normalization. + */ +int getCloseBodyPosition() { + return fCloseBodyRange[0]; +} +/** + * @see DOMNode#getDetailedNode() + */ +//protected DOMNode getDetailedNode() { +// return (DOMNode)getFactory().createType(getContents()); +//} +/** + * @see DOMNode#getInsertionPosition() + */ +public int getInsertionPosition() { + // this should return the position of the end of the last line separator before the closing brace of the type + // See PR 1GELSDQ: ITPJUI:WINNT - JDOM: IType.createMethod does not insert nicely for inner types + return fInsertionPosition; +} +/** + * @see IDOMNode#getJavaElement + */ +public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException { + if (parent.getElementType() == IJavaElement.TYPE) { + return ((IType)parent).getType(getName()); + } else if (parent.getElementType() == IJavaElement.COMPILATION_UNIT) { + return ((ICompilationUnit)parent).getType(getName()); + } else { + throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$ + } +} +/** + * @see DOMMember#getMemberDeclarationStartPosition() + */ +protected int getMemberDeclarationStartPosition() { + return fTypeRange[0]; +} +/** + * @see IDOMNode#getNodeType() + */ +public int getNodeType() { + return IDOMNode.TYPE; +} +/** + * Answers the open body range end position. + */ +int getOpenBodyEnd() { + return fOpenBodyRange[1]; +} +/** + * @see IDOMType#getSuperclass() + */ +public String getSuperclass() { + becomeDetailed(); + if (getMask(MASK_TYPE_HAS_SUPERCLASS)) { + if (fSuperclass != null) { + return fSuperclass; + } else { + return CharArrayOps.substring(fDocument, fSuperclassRange[0], fSuperclassRange[1] + 1 - fSuperclassRange[0]); + } + } else { + return null; + } +} +/** + * @see IDOMType#getSuperInterfaces() + */ +public String[] getSuperInterfaces() { + return fSuperInterfaces; +} +/** + * @see IDOMNode + */ +public boolean isAllowableChild(IDOMNode node) { + if (node != null) { + int type= node.getNodeType(); + return type == IDOMNode.TYPE || type == IDOMNode.FIELD|| type == IDOMNode.METHOD || + type == IDOMNode.INITIALIZER; + } else { + return false; + } + +} +/** + * @see IDOMType#isClass() + */ +public boolean isClass() { + return getMask(MASK_TYPE_IS_CLASS); +} +/** + * @see DOMNode + */ +protected DOMNode newDOMNode() { + return new DOMType(); +} +/** + * Normalizes this DOMNode's source positions to include whitespace preceeding + * the node on the line on which the node starts, and all whitespace after the node up to + * the next node's start + */ +void normalize(ILineStartFinder finder) { + // perform final changes to the open and close body ranges + int openBodyEnd, openBodyStart, closeBodyStart, closeBodyEnd; + DOMNode first = (DOMNode) getFirstChild(); + DOMNode lastNode = null; + // look for the open body + Scanner scanner = new Scanner(); + scanner.setSource(fDocument); + scanner.resetTo(fNameRange[1] + 1, fDocument.length); + + try { + int currentToken = scanner.getNextToken(); + while(currentToken != ITerminalSymbols.TokenNameLBRACE && + currentToken != ITerminalSymbols.TokenNameEOF) { + currentToken = scanner.getNextToken(); + } + if(currentToken == ITerminalSymbols.TokenNameLBRACE) { + openBodyEnd = scanner.currentPosition - 1; + openBodyStart = scanner.startPosition; + } else { + openBodyEnd = fDocument.length; + openBodyStart = fDocument.length; + } + } catch(InvalidInputException e) { + openBodyEnd = fDocument.length; + openBodyStart = fDocument.length; + } + if (first != null) { + int lineStart = finder.getLineStart(first.getStartPosition()); + if (lineStart > openBodyEnd) { + openBodyEnd = lineStart - 1; + } else { + openBodyEnd = first.getStartPosition() - 1; + } + lastNode = (DOMNode) first.getNextNode(); + if (lastNode == null) { + lastNode = first; + } else { + while (lastNode.getNextNode() != null) { + lastNode = (DOMNode) lastNode.getNextNode(); + } + } + scanner.setSource(fDocument); + scanner.resetTo(lastNode.getEndPosition() + 1, fDocument.length); + try { + int currentToken = scanner.getNextToken(); + while(currentToken != ITerminalSymbols.TokenNameRBRACE && + currentToken != ITerminalSymbols.TokenNameEOF) { + currentToken = scanner.getNextToken(); + } + if(currentToken == ITerminalSymbols.TokenNameRBRACE) { + closeBodyStart = scanner.startPosition; + closeBodyEnd = scanner.currentPosition - 1; + } else { + closeBodyStart = fDocument.length; + closeBodyEnd = fDocument.length; + } + } catch(InvalidInputException e) { + closeBodyStart = fDocument.length; + closeBodyEnd = fDocument.length; + } + } else { + scanner.resetTo(openBodyEnd, fDocument.length); + try { + int currentToken = scanner.getNextToken(); + while(currentToken != ITerminalSymbols.TokenNameRBRACE && + currentToken != ITerminalSymbols.TokenNameEOF) { + currentToken = scanner.getNextToken(); + } + if(currentToken == ITerminalSymbols.TokenNameRBRACE) { + closeBodyStart = scanner.startPosition; + closeBodyEnd = scanner.currentPosition - 1; + } else { + closeBodyStart = fDocument.length; + closeBodyEnd = fDocument.length; + } + } catch(InvalidInputException e) { + closeBodyStart = fDocument.length; + closeBodyEnd = fDocument.length; + } + openBodyEnd = closeBodyEnd - 1; + } + setOpenBodyRangeEnd(openBodyEnd); + setOpenBodyRangeStart(openBodyStart); + setCloseBodyRangeStart(closeBodyStart); + setCloseBodyRangeEnd(closeBodyEnd); + fInsertionPosition = finder.getLineStart(closeBodyStart); + if (lastNode != null && fInsertionPosition < lastNode.getEndPosition()) { + fInsertionPosition = getCloseBodyPosition(); + } + if (fInsertionPosition <= openBodyEnd) { + fInsertionPosition = getCloseBodyPosition(); + } + super.normalize(finder); +} + +/** + * Normalizes this DOMNode's end position. + */ +void normalizeEndPosition(ILineStartFinder finder, DOMNode next) { + if (next == null) { + // this node's end position includes all of the characters up + // to the end of the enclosing node + DOMNode parent = (DOMNode) getParent(); + if (parent == null || parent instanceof DOMCompilationUnit) { + setSourceRangeEnd(fDocument.length - 1); + } else { + // parent is a type + setSourceRangeEnd(((DOMType)parent).getCloseBodyPosition() - 1); + } + } else { + // this node's end position is just before the start of the next node + next.normalizeStartPosition(getEndPosition(), finder); + setSourceRangeEnd(next.getStartPosition() - 1); + } +} + +/** + * Offsets all the source indexes in this node by the given amount. + */ +protected void offset(int offset) { + super.offset(offset); + offsetRange(fCloseBodyRange, offset); + offsetRange(fExtendsRange, offset); + offsetRange(fImplementsRange, offset); + offsetRange(fInterfacesRange, offset); + offsetRange(fOpenBodyRange, offset); + offsetRange(fSuperclassRange, offset); + offsetRange(fTypeRange, offset); +} +/** + * @see IDOMType#setClass(boolean) + */ +public void setClass(boolean b) { + becomeDetailed(); + fragment(); + setMask(MASK_TYPE_IS_CLASS, b); + if (b) { + fTypeKeyword= "class"; //$NON-NLS-1$ + } else { + fTypeKeyword= "interface"; //$NON-NLS-1$ + setSuperclass(null); + } +} +/** + * Sets the end of the close body range + */ +void setCloseBodyRangeEnd(int end) { + fCloseBodyRange[1] = end; +} +/** + * Sets the start of the close body range + */ +void setCloseBodyRangeStart(int start) { + fCloseBodyRange[0] = start; +} +/** + * Sets the name of this node. + * + *

        When the name of a type is set, all of its constructors must be marked + * as fragmented, since the names of the constructors must reflect the name + * of this type. + * + * @see IDOMNode#setName(char[]) + */ +public void setName(String name) throws IllegalArgumentException { + if (name == null) { + throw new IllegalArgumentException(Util.bind("element.nullName")); //$NON-NLS-1$ + } + super.setName(name); + Enumeration children= getChildren(); + while (children.hasMoreElements()) { + IDOMNode child= (IDOMNode)children.nextElement(); + if (child.getNodeType() == IDOMNode.METHOD && ((IDOMMethod)child).isConstructor()) { + ((DOMNode)child).fragment(); + } + } +} +/** + * Sets the end of the open body range + */ +void setOpenBodyRangeEnd(int end) { + fOpenBodyRange[1] = end; +} +/** + * Sets the start of the open body range + */ +void setOpenBodyRangeStart(int start) { + fOpenBodyRange[0] = start; +} +/** + * @see IDOMType#setSuperclass(char[]) + */ +public void setSuperclass(String superclassName) { + becomeDetailed(); + fragment(); + fSuperclass= superclassName; + setMask(MASK_TYPE_HAS_SUPERCLASS, superclassName != null); +} +/** + * @see IDOMType#setSuperInterfaces(String[]) + */ +public void setSuperInterfaces(String[] names) { + becomeDetailed(); + if (names == null) { + throw new IllegalArgumentException(Util.bind("dom.nullInterfaces")); //$NON-NLS-1$ + } + fragment(); + fSuperInterfaces= names; + if (names == null || names.length == 0) { + fInterfaces= null; + fSuperInterfaces= null; + setMask(MASK_TYPE_HAS_INTERFACES, false); + } else { + setMask(MASK_TYPE_HAS_INTERFACES, true); + CharArrayBuffer buffer = new CharArrayBuffer(); + for (int i = 0; i < names.length; i++) { + if (i > 0) { + buffer.append(", "); //$NON-NLS-1$ + } + buffer.append(names[i]); + } + fInterfaces = buffer.getContents(); + } +} +/** + * Sets the type keyword + */ +void setTypeKeyword(String keyword) { + fTypeKeyword = keyword; +} +/** + * @see DOMNode#shareContents(DOMNode) + */ +protected void shareContents(DOMNode node) { + super.shareContents(node); + DOMType type= (DOMType)node; + fCloseBodyRange= rangeCopy(type.fCloseBodyRange); + fExtendsRange= type.fExtendsRange; + fImplementsRange= rangeCopy(type.fImplementsRange); + fInterfaces= type.fInterfaces; + fInterfacesRange= rangeCopy(type.fInterfacesRange); + fOpenBodyRange= rangeCopy(type.fOpenBodyRange); + fSuperclass= type.fSuperclass; + fSuperclassRange= rangeCopy(type.fSuperclassRange); + fSuperInterfaces= type.fSuperInterfaces; + fTypeKeyword= type.fTypeKeyword; + fTypeRange= rangeCopy(type.fTypeRange); +} +/** + * @see IDOMNode#toString() + */ +public String toString() { + return "TYPE: " + getName(); //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/ILineStartFinder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/ILineStartFinder.java new file mode 100644 index 0000000..8dda4de --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/ILineStartFinder.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +/** + * The ILineSeparatorFinder finds previous and next line separators + * in source. + */ +public interface ILineStartFinder { +/** + * Returns the position of the start of the line at or before the given source position. + * + *

        This defaults to zero if the position corresponds to a position on the first line + * of the source. + */ +public int getLineStart(int position); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/SiblingEnumeration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/SiblingEnumeration.java new file mode 100644 index 0000000..167ce0e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/SiblingEnumeration.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import java.util.Enumeration; + +import net.sourceforge.phpdt.core.jdom.IDOMNode; + +/** + * SiblingEnumeration provides an enumeration on a linked list + * of sibling DOM nodes. + * + * @see java.util.Enumeration + */ + +/* package */ class SiblingEnumeration implements Enumeration { + + /** + * The current location in the linked list + * of DOM nodes. + */ + protected IDOMNode fCurrentElement; +/** + * Creates an enumeration of silbings starting at the given node. + * If the given node is null the enumeration is empty. + */ +SiblingEnumeration(IDOMNode child) { + fCurrentElement= child; +} +/** + * @see java.util.Enumeration#hasMoreElements() + */ +public boolean hasMoreElements() { + return fCurrentElement != null; +} +/** + * @see java.util.Enumeration#nextElement() + */ +public Object nextElement() { + IDOMNode curr= fCurrentElement; + if (curr != null) { + fCurrentElement= fCurrentElement.getNextNode(); + } + return curr; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/SimpleDOMBuilder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/SimpleDOMBuilder.java new file mode 100644 index 0000000..c923015 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/SimpleDOMBuilder.java @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import java.util.Map; + +import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit; +import net.sourceforge.phpdt.internal.compiler.ISourceElementRequestor; +import net.sourceforge.phpdt.internal.compiler.SourceElementParser; +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; +import net.sourceforge.phpdt.internal.compiler.problem.DefaultProblemFactory; +import net.sourceforge.phpdt.internal.core.util.CharArrayOps; +import net.sourceforge.phpeclipse.PHPCore; + +/** + * A DOM builder that uses the SourceElementParser + */ +public class SimpleDOMBuilder extends AbstractDOMBuilder implements ISourceElementRequestor { + +public void acceptImport(int declarationStart, int declarationEnd, char[] name, boolean onDemand) { + int[] sourceRange = {declarationStart, declarationEnd}; + String importName = new String(name); + /** name is set to contain the '*' */ + if (onDemand) { + importName+=".*"; //$NON-NLS-1$ + } + fNode= new DOMImport(fDocument, sourceRange, importName, onDemand); + addChild(fNode); +} +public void acceptPackage(int declarationStart, int declarationEnd, char[] name) { + int[] sourceRange= new int[] {declarationStart, declarationEnd}; + fNode= new DOMPackage(fDocument, sourceRange, CharArrayOps.charToString(name)); + addChild(fNode); +} +/** + * @see IDOMFactory#createCompilationUnit(String, String) + */ +public IDOMCompilationUnit createCompilationUnit(String sourceCode, String name) { + return createCompilationUnit(sourceCode.toCharArray(), name.toCharArray()); +} +/** + * @see IDOMFactory#createCompilationUnit(String, String) + */ +public IDOMCompilationUnit createCompilationUnit(ICompilationUnit compilationUnit) { + initializeBuild(compilationUnit.getContents(), true, true); + getParser(PHPCore.getOptions()).parseCompilationUnit(compilationUnit, false); + return super.createCompilationUnit(compilationUnit); +} +/** + * Creates a new DOMMethod and inizializes. + * + * @param declarationStart - a source position corresponding to the first character + * of this constructor declaration + * @param modifiers - the modifiers for this constructor converted to a flag + * @param returnType - the name of the return type + * @param name - the name of this constructor + * @param nameStart - a source position corresponding to the first character of the name + * @param nameEnd - a source position corresponding to the last character of the name + * @param parameterTypes - a list of parameter type names + * @param parameterNames - a list of the names of the parameters + * @param exceptionTypes - a list of the exception types + */ +protected void enterAbstractMethod(int declarationStart, int modifiers, + char[] returnType, char[] name, int nameStart, int nameEnd, char[][] parameterTypes, + char[][] parameterNames, char[][] exceptionTypes, boolean isConstructor) { + + int[] sourceRange = {declarationStart, -1}; // will be fixed up on exit + int[] nameRange = {nameStart, nameEnd}; + fNode = new DOMMethod(fDocument, sourceRange, CharArrayOps.charToString(name), nameRange, modifiers, + isConstructor, CharArrayOps.charToString(returnType), + CharArrayOps.charcharToString(parameterTypes), + CharArrayOps.charcharToString(parameterNames), + CharArrayOps.charcharToString(exceptionTypes)); + addChild(fNode); + fStack.push(fNode); +} +/** + */ +public void enterClass(int declarationStart, int modifiers, char[] name, int nameStart, int nameEnd, char[] superclass, char[][] superinterfaces) { + enterType(declarationStart, modifiers, name, nameStart, nameEnd, superclass, + superinterfaces, true); +} +/** + */ +public void enterConstructor(int declarationStart, int modifiers, char[] name, int nameStart, int nameEnd, char[][] parameterTypes, char[][] parameterNames, char[][] exceptionTypes) { + /* see 1FVIIQZ */ + String nameString = new String(fDocument, nameStart, nameEnd - nameStart); + int openParenPosition = nameString.indexOf('('); + if (openParenPosition > -1) + nameEnd = nameStart + openParenPosition - 1; + + enterAbstractMethod(declarationStart, modifiers, + null, name, nameStart, nameEnd, parameterTypes, + parameterNames, exceptionTypes,true); +} +/** + */ +public void enterField(int declarationStart, int modifiers, char[] type, char[] name, int nameStart, int nameEnd) { + + int[] sourceRange = {declarationStart, -1}; + int[] nameRange = {nameStart, nameEnd}; + boolean isSecondary= false; + if (fNode instanceof DOMField) { + isSecondary = declarationStart == fNode.fSourceRange[0]; + } + fNode = new DOMField(fDocument, sourceRange, CharArrayOps.charToString(name), nameRange, + modifiers, CharArrayOps.charToString(type), isSecondary); + addChild(fNode); + fStack.push(fNode); +} +/** + + */ +public void enterInitializer(int declarationSourceStart, int modifiers) { + int[] sourceRange = {declarationSourceStart, -1}; + fNode = new DOMInitializer(fDocument, sourceRange, modifiers); + addChild(fNode); + fStack.push(fNode); +} +/** + */ +public void enterInterface(int declarationStart, int modifiers, char[] name, int nameStart, int nameEnd, char[][] superinterfaces) { + enterType(declarationStart, modifiers, name, nameStart, nameEnd, null, + superinterfaces, false); +} +/** + */ +public void enterMethod(int declarationStart, int modifiers, char[] returnType, char[] name, int nameStart, int nameEnd, char[][] parameterTypes, char[][] parameterNames, char[][] exceptionTypes) { + enterAbstractMethod(declarationStart, modifiers, + returnType, name, nameStart, nameEnd, parameterTypes, + parameterNames, exceptionTypes,false); +} +/** + */ +protected void enterType(int declarationStart, int modifiers, char[] name, + int nameStart, int nameEnd, char[] superclass, char[][] superinterfaces, boolean isClass) { + if (fBuildingType) { + int[] sourceRange = {declarationStart, -1}; // will be fixed in the exit + int[] nameRange = new int[] {nameStart, nameEnd}; + fNode = new DOMType(fDocument, sourceRange, new String(name), nameRange, + modifiers, CharArrayOps.charcharToString(superinterfaces), isClass); + addChild(fNode); + fStack.push(fNode); + } +} +/** + * Finishes the configuration of the class DOM object which + * was created by a previous enterClass call. + * + * @see ISourceElementRequestor#exitClass(int) + */ +public void exitClass(int declarationEnd) { + exitType(declarationEnd); +} +/** + * Finishes the configuration of the method DOM object which + * was created by a previous enterConstructor call. + * + * @see ISourceElementRequestor#exitConstructor(int) + */ +public void exitConstructor(int declarationEnd) { + exitMember(declarationEnd); +} +/** + */ +public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) { + exitMember(declarationEnd); +} +/** + */ +public void exitInitializer(int declarationEnd) { + exitMember(declarationEnd); +} +/** + */ +public void exitInterface(int declarationEnd) { + exitType(declarationEnd); +} +/** + * Finishes the configuration of the member. + * + * @param declarationEnd - a source position corresponding to the end of the method + * declaration. This can include whitespace and comments following the closing bracket. + */ +protected void exitMember(int declarationEnd) { + DOMMember m= (DOMMember) fStack.pop(); + m.setSourceRangeEnd(declarationEnd); + fNode = m; +} +/** + */ +public void exitMethod(int declarationEnd) { + exitMember(declarationEnd); +} +/** + * @see AbstractDOMBuilder#exitType + * + * @param declarationEnd - a source position corresponding to the end of the class + * declaration. This can include whitespace and comments following the closing bracket. + */ +protected void exitType(int declarationEnd) { + exitType(declarationEnd, declarationEnd); +} +/** + * Creates a new parser. + */ +protected SourceElementParser getParser(Map settings) { + return new SourceElementParser(this, new DefaultProblemFactory());//, new CompilerOptions(settings)); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/messages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/messages.properties new file mode 100644 index 0000000..347a008 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/messages.properties @@ -0,0 +1,232 @@ +############################################################################### +# Copyright (c) 2000, 2003 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Common Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/cpl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### +### JavaModel messages. + +### hierarchy +hierarchy.nullProject = Project argument cannot be null. +hierarchy.nullRegion = Region cannot be null. +hierarchy.nullFocusType = Type focus cannot be null. +hierarchy.creating = Creating type hierarchy... +hierarchy.creatingOnType = Creating type hierarchy on {0}... + +### java element +element.doesNotExist = {0} does not exist. +element.invalidClassFileName = Class file name must end with .class. +element.cannotReconcile = Must create reconciler on a working copy. +element.reconciling = Reconciling... +element.attachingSource = Attaching source... +element.invalidType = Type is not one of the defined constants. +element.classpathCycle = A cycle was detected in the project''s classpath. +element.onlyOneJavaModel = Cannot instantiate more than one Java Model. +element.projectDoesNotExist = Project {0} not present +element.invalidResourceForProject = Illegal argument - must be one of IProject, IFolder, or IFile +element.nullName = Name cannot be null. +element.nullType = Type cannot be null. +element.illegalParent = Illegal parent argument. +element.notPresent = Not present + +### java model operations +operation.needElements = Operation requires one or more elements. +operation.needName = Operation requires a name. +operation.needPath = Operation requires a path. +operation.needAbsolutePath = Operation requires an absolute path. Relative path specified was: ''{0}'' +operation.needString = Operation requires a String. +operation.notSupported = Operation not supported for specified element type(s): +operation.cancelled = Operation cancelled. +operation.nullContainer = Container cannot be null. +operation.nullName = Name cannot be null. +operation.copyElementProgress = Copying elements... +operation.moveElementProgress = Moving elements... +operation.renameElementProgress = Renaming elements... +operation.copyResourceProgress = Copying resources... +operation.moveResourceProgress = Moving resources... +operation.renameResourceProgress = Renaming resources... +operation.createUnitProgress = Creating a compilation unit... +operation.createFieldProgress = Creating a field... +operation.createImportsProgress = Creating imports... +operation.createInitializerProgress = Creating an initializer... +operation.createMethodProgress = Creating a method... +operation.createPackageProgress = Creating a package declaration... +operation.createPackageFragmentProgress = Creating package fragment(s)... +operation.createTypeProgress = Creating a type... +operation.deleteElementProgress = Deleting elements... +operation.deleteResourceProgress = Deleting resources... +operation.cannotRenameDefaultPackage = Default package cannot be renamed. +operation.pathOutsideProject = Path ''{0}'' must denote location inside project {1} +operation.sortelements = Sorting elements... + +### working copy +workingCopy.commit = Committing working copy... + +### build status messages +build.preparingBuild = Preparing for build +build.readStateProgress = Reading saved built state for project {0} +build.saveStateProgress = Saving built state for project {0} +build.saveStateComplete = Saved in {0} ms +build.readingDelta = Reading resource change information for {0} +build.analyzingDeltas = Analyzing deltas +build.analyzingSources = Analyzing sources +build.cleaningOutput = Cleaning output folder +build.copyingResources = Copying resources to the output folder +build.compiling = Compiling {0} +build.foundHeader = Found +build.fixedHeader = Fixed +build.oneError = 1 error +build.oneWarning = 1 warning +build.multipleErrors = {0} errors +build.multipleWarnings = {0} warnings +build.done = Build done + +### build errors +build.wrongFileFormat = Wrong file format. +build.cannotSaveState = Error saving last build state for project {0}. +build.cannotSaveStates = Error saving build states. +build.initializationError = Builder initialization error. +build.serializationError = Builder serialization error. + +### build inconsistencies +build.duplicateClassFile = The type {0} is already defined. +build.duplicateResource = The resource is a duplicate and was not copied to the output folder. +build.inconsistentClassFile = A class file was not written. The project may be inconsistent, if so try refreshing this project and rebuilding it. +build.inconsistentProject = The project was not built due to "{0}". Fix the problem, then try refreshing this project and rebuilding it since it may be inconsistent. +build.incompleteClassPath = The project was not built since its classpath is incomplete. Cannot find the class file for {0}. Fix the classpath then try rebuilding this project. +build.missingSourceFile = The project was not built since the source file {0} could not be read. +build.prereqProjectHasClasspathProblems = The project was not built since it depends on {0}, which has classpath problems. +build.prereqProjectMustBeRebuilt = The project cannot be built until {0} is rebuilt. Rebuilding all projects is recommended. +build.abortDueToClasspathProblems = The project was not built due to classpath errors (incomplete or involved in cycle). + +### status +status.cannotUseDeviceOnPath = Operation requires a path with no device. Path specified was: {0} +status.coreException = Core exception. +status.defaultPackeReadOnly = Default package is read-only. +status.evaluationError = Evaluation error: {0}. +status.JDOMError = JDOM error. +status.IOException = I/O exception. +status.indexOutOfBounds = Index out of bounds. +status.invalidContents = Invalid contents specified. +status.invalidDestination = Invalid destination: ''{0}''. +status.invalidName = Invalid name specified: {0}. +status.invalidPackage = Invalid package: {0}. +status.invalidPath = Invalid path: ''{0}''. +status.invalidProject = Invalid project: {0}. +status.invalidResource = Invalid resource: {0}. +status.invalidResourceType = Invalid resource type for {0}. +status.invalidSibling = Invalid sibling: {0}. +status.nameCollision = {0} already exists in target. +status.noLocalContents = Cannot find local contents for resource: {0} +status.OK = OK +status.readOnly = {0} is read-only. +status.targetException = Target exception. +status.updateConflict = Update conflict. + +### classpath +classpath.buildPath = Build path +classpath.cannotNestEntryInEntry = Cannot nest ''{0}'' inside ''{1}''. To enable the nesting exclude ''{2}'' from ''{1}''. +classpath.cannotNestEntryInLibrary = Cannot nest ''{0}'' inside library ''{1}''. +classpath.cannotNestEntryInOutput = Cannot nest ''{0}'' inside output folder ''{1}''. +classpath.cannotNestOutputInEntry = Cannot nest output folder ''{0}'' inside ''{1}''. +classpath.cannotNestOutputInOutput = Cannot nest output folder ''{0}'' inside output folder ''{1}''. +classpath.cannotReadClasspathFile = Unable to read ''{0}/.classpath'' file. +classpath.cannotReferToItself = Project cannot reference itself: {0} +classpath.cannotUseDistinctSourceFolderAsOutput = Source folder ''{0}'' cannot output to distinct source folder ''{1}''. +classpath.cannotUseLibraryAsOutput = Source folder ''{0}'' cannot output to library ''{1}''. +classpath.closedProject = Required project: {0} needs to be open. +classpath.couldNotWriteClasspathFile = Could not write ''{0}/.classpath'': {1} +classpath.cycle = A cycle was detected in the classpath of project: {0} +classpath.duplicateEntryPath = Classpath contains duplicate entry: {0} +classpath.illegalContainerPath = Illegal classpath container path: ''{0}'', must have at least one segment (containerID+hints). +classpath.illegalEntryInClasspathFile = Illegal entry in ''{0}/.classpath'' file: {1} +classpath.illegalLibraryPath = Illegal path for required library: ''{0}''. +classpath.illegalProjectPath = Illegal path for required project: ''{0}''. +classpath.illegalSourceFolderPath = Illegal path for required source folder: ''{0}''. +classpath.illegalVariablePath = Illegal classpath variable path: ''{0}'', must have at least one segment. +classpath.invalidClasspathInClasspathFile = Invalid classpath in ''{0}/.classpath'' file: {1} +classpath.invalidContainer = Invalid classpath container: {0} +classpath.mustEndWithSlash = End exclusion filter ''{0}'' with / to fully exclude ''{1}''. +classpath.unboundContainerPath = Unbound classpath container: ''{0}''. +classpath.unboundLibrary = Missing required library: ''{0}''. +classpath.unboundProject = Missing required Java project: {0}. +classpath.settingOutputLocationProgress = Setting output location for: ''{0}'' +classpath.settingProgress = Setting classpath for: {0} +classpath.unboundSourceAttachment = Invalid source attachment: ''{0}'' for required library ''{1}''. +classpath.unboundSourceFolder = Missing required source folder: ''{0}''. +classpath.unboundVariablePath = Unbound classpath variable: ''{0}''. +classpath.unknownKind = Unknown kind: {0} +classpath.xmlFormatError = XML format error in ''{0}/.classpath'' file: {1} +classpath.disabledExclusionPatterns = Exclusion patterns are disabled, cannot exclude from entry: ''{0}''. +classpath.disabledMultipleOutputLocations = Multiple output locations are disabled, cannot associate entry: ''{0}'' with a specific output. + +### miscellaneous +file.notFound = File not found: ''{0}''. +file.badFormat = Bad format. +variable.badFormat = Bad format for variables. +option.badFormat = Bad format for options. +path.nullPath = Path cannot be null. +path.mustBeAbsolute = Path must be absolute. +cache.invalidLoadFactor = Incorrect load factor + +### code assist +codeAssist.nullRequestor = Requestor cannot be null. + +### java conventions +convention.unit.nullName = Compilation unit name must not be null. +convention.unit.notJavaName = Compilation unit name must end with .java. +convention.classFile.nullName = .class file name must not be null. +convention.classFile.notJavaName = .class file name must end with .class. +convention.illegalIdentifier = ''{0}'' is not a valid Java identifier. +convention.import.nullImport = An import declaration must not be null. +convention.import.unqualifiedImport = An import declaration must not end with an unqualified *. +convention.type.nullName = A Java type name must not be null. +convention.type.nameWithBlanks = A Java type name must not start or end with a blank. +convention.type.dollarName = By convention, Java type names usually don''t contain the $ character. +convention.type.lowercaseName = By convention, Java type names usually start with an uppercase letter. +convention.type.invalidName = The type name ''{0}'' is not a valid identifier. +convention.package.nullName = A package name must not be null. +convention.package.emptyName = A package name must not be empty. +convention.package.dotName = A package name cannot start or end with a dot. +convention.package.nameWithBlanks = A package name must not start or end with a blank. +convention.package.consecutiveDotsName = A package name must not contain two consecutive dots. +convention.package.uppercaseName = By convention, package names usually start with a lowercase letter. + +### DOM +dom.cannotDetail = Unable to generate detailed source indexes. +dom.nullTypeParameter = Cannot add parameter with null type +dom.nullNameParameter = Cannot add parameter with null name +dom.nullReturnType = Return type cannot be null +dom.nullExceptionType = Cannot add null exception +dom.mismatchArgNamesAndTypes = Types and names must have identical length +dom.addNullChild = Attempt to add null child +dom.addIncompatibleChild = Attempt to add child of incompatible type +dom.addChildWithParent = Attempt to add child that is already parented +dom.unableAddChild = Attempt to add child to node that cannot have children +dom.addAncestorAsChild = Attempt to add ancestor as child +dom.addNullSibling = Attempt to insert null sibling +dom.addSiblingBeforeRoot = Attempt to insert sibling before root node +dom.addIncompatibleSibling = Attempt to insert sibling of incompatible type +dom.addSiblingWithParent = Attempt to insert sibling that is already parented +dom.addAncestorAsSibling = Attempt to insert ancestor as sibling +dom.addNullInterface = Cannot add null interface +dom.nullInterfaces = Illegal to set super interfaces to null + +### eval +eval.needBuiltState = Cannot evaluate if the project has not been built once + +### correction +correction.nullRequestor = Requestor cannot be null. +correction.nullUnit = Compilation unit cannot be null. + +### JDT Adapter +ant.jdtadapter.info.usingJdtCompiler = Using JDT compiler +ant.jdtadapter.error.missingJDTCompiler = Cannot find the JDT compiler +ant.jdtadapter.error.missingJRELIB = Cannot bind the JRE_LIB variable. To solve this problem, you can either set the JRE_LIB variable or use the bootclasspath parameter in your ant javac task +ant.jdtadapter.error.ignoringMemoryInitialSize= Since fork is false, ignoring memoryInitialSize setting +ant.jdtadapter.error.ignoringMemoryMaximumSize= Since fork is false, ignoring memoryMaximumSize setting +ant.jdtadapter.error.compilationFailed = Compilation failed. Compiler errors are available in {0} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/CharArrayOps.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/CharArrayOps.java new file mode 100644 index 0000000..7041eb4 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/CharArrayOps.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.util; + +/** + * A class to do characters operations so that we can use + * char arrays more effectively. + */ +public class CharArrayOps { // TODO: should promote to CharOperation +/** + * Returns the char arrays as an array of Strings + */ +public static String[] charcharToString(char[][] charchar) { + if (charchar == null) { + return null; + } + String[] strings= new String[charchar.length]; + for (int i= 0; i < charchar.length; i++) { + strings[i]= new String(charchar[i]); + } + return strings; +} +/** + * Returns the char array as a String + */ +public static String charToString(char[] chars) { + if (chars == null) { + return null; + } else { + return new String(chars); + } +} +/** + * Concatinates the two arrays into one big array. + * If the first array is null, returns the second array. + * If the second array is null, returns the first array. + * + * @param first - the array which the other array is concatinated onto + * @param second - the array which is to be concatinated onto the first array + */ +public static char[] concat(char[] first, char[] second) { + if (first == null) + return second; + if (second == null) + return first; + + int length1 = first.length; + int length2 = second.length; + char[] result = new char[length1 + length2]; + System.arraycopy(first, 0, result, 0, length1); + System.arraycopy(second, 0, result, length1, length2); + return result; +} +/** + * Checks the two character arrays for equality. + * + * @param first - one of the arrays to be compared + * @param second - the other array which is to be compared + */ +public static boolean equals(char[] first, char[] second) { + if (first == second) + return true; + if (first == null || second == null) + return false; + if (first.length != second.length) + return false; + + for (int i = 0, length = first.length; i < length; i++) + if (first[i] != second[i]) + return false; + return true; +} +/** + * Returns the index of the first occurrence of character in buffer, + * starting from offset, or -1 if not found. + */ +public static int indexOf(char character, char[] buffer, int offset) { + for (int i= offset; i < buffer.length; i++) { + if (buffer[i] == character) { + return i; + } + } + return -1; +} +/** + * Extracts a sub-array from the given array, starting + * at the given startIndex and proceeding for length characters. + * Returns null if: + * 1. the src array is null + * 2. the start index is out of bounds + * 3. the length parameter specifies a end point which is out of bounds + * Does not return a copy of the array if possible, in other words, if start is zero + * and length equals the length of the src array. + * + * @param src - the array from which elements need to be copied + * @param start - the start index in the src array + * @param length - the number of characters to copy + */ +public static char[] subarray(char[] src, int start, int length) { + if (src == null) + return null; + int srcLength = src.length; + if (start < 0 || start >= srcLength) + return null; + if (length < 0 || start + length > srcLength) + return null; + if (srcLength == length && start == 0) + return src; + + char[] result = new char[length]; + if (length > 0) + System.arraycopy(src, start, result, 0, length); + return result; +} +/** + * Extracts a substring from the given array, starting + * at the given startIndex and proceeding for length characters. + * Returns null if: + * 1. the src array is null + * 2. the start index is out of bounds + * 3. the length parameter specifies a end point which is out of bounds + * Does not return a copy of the array if possible (if start is zero + * and length equals the length of the src array). + * + * @param src - the array from which elements need to be copied + * @param start - the start index in the src array + * @param length - the number of characters to copy + */ +public static String substring(char[] src, int start, int length) { + char[] chars= subarray(src, start, length); + if (chars != null) { + return new String(chars); + } else { + return null; + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/ICacheEnumeration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/ICacheEnumeration.java new file mode 100644 index 0000000..1c77c5e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/ICacheEnumeration.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.util; + +import java.util.Enumeration; + +/** + * The ICacheEnumeration is used to iterate over both the keys + * and values in an LRUCache. The getValue() method returns the + * value of the last key to be retrieved using nextElement(). + * The nextElement() method must be called before the + * getValue() method. + * + *

        The iteration can be made efficient by making use of the fact that values in + * the cache (instances of LRUCacheEntry), know their key. For this reason, + * Hashtable lookups don't have to be made at each step of the iteration. + * + *

        Modifications to the cache must not be performed while using the + * enumeration. Doing so will lead to an illegal state. + * + * @see LRUCache + */ +public interface ICacheEnumeration extends Enumeration { + /** + * Returns the value of the previously accessed key in the enumeration. + * Must be called after a call to nextElement(). + * + * @return Value of current cache entry + */ + public Object getValue(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/ILRUCacheable.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/ILRUCacheable.java new file mode 100644 index 0000000..6c5662f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/ILRUCacheable.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.util; + +/** + * Types implementing this interface can occupy a variable amount of space + * in an LRUCache. Cached items that do not implement this interface are + * considered to occupy one unit of space. + * + * @see LRUCache + */ +public interface ILRUCacheable { + /** + * Returns the space the receiver consumes in an LRU Cache. The default space + * value is 1. + * + * @return int Amount of cache space taken by the receiver + */ + public int getCacheFootprint(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/LRUCache.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/LRUCache.java new file mode 100644 index 0000000..e1a933a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/LRUCache.java @@ -0,0 +1,498 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.util; + +import java.util.Enumeration; +import java.util.Hashtable; + +/** + * The LRUCache is a hashtable that stores a finite number of elements. + * When an attempt is made to add values to a full cache, the least recently used values + * in the cache are discarded to make room for the new values as necessary. + * + *

        The data structure is based on the LRU virtual memory paging scheme. + * + *

        Objects can take up a variable amount of cache space by implementing + * the ILRUCacheable interface. + * + *

        This implementation is NOT thread-safe. Synchronization wrappers would + * have to be added to ensure atomic insertions and deletions from the cache. + * + * @see org.eclipse.jdt.internal.core.util.ILRUCacheable + */ +public class LRUCache implements Cloneable { + + /** + * This type is used internally by the LRUCache to represent entries + * stored in the cache. + * It is static because it does not require a pointer to the cache + * which contains it. + * + * @see LRUCache + */ + protected static class LRUCacheEntry { + + /** + * Hash table key + */ + public Object _fKey; + + /** + * Hash table value (an LRUCacheEntry object) + */ + public Object _fValue; + + /** + * Time value for queue sorting + */ + public int _fTimestamp; + + /** + * Cache footprint of this entry + */ + public int _fSpace; + + /** + * Previous entry in queue + */ + public LRUCacheEntry _fPrevious; + + /** + * Next entry in queue + */ + public LRUCacheEntry _fNext; + + /** + * Creates a new instance of the receiver with the provided values + * for key, value, and space. + */ + public LRUCacheEntry (Object key, Object value, int space) { + _fKey = key; + _fValue = value; + _fSpace = space; + } + + /** + * Returns a String that represents the value of this object. + */ + public String toString() { + + return "LRUCacheEntry [" + _fKey + "-->" + _fValue + "]"; //$NON-NLS-3$ //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + /** + * Amount of cache space used so far + */ + protected int fCurrentSpace; + + /** + * Maximum space allowed in cache + */ + protected int fSpaceLimit; + + /** + * Counter for handing out sequential timestamps + */ + protected int fTimestampCounter; + + /** + * Hash table for fast random access to cache entries + */ + protected Hashtable fEntryTable; + + /** + * Start of queue (most recently used entry) + */ + protected LRUCacheEntry fEntryQueue; + + /** + * End of queue (least recently used entry) + */ + protected LRUCacheEntry fEntryQueueTail; + + /** + * Default amount of space in the cache + */ + protected static final int DEFAULT_SPACELIMIT = 100; + /** + * Creates a new cache. Size of cache is defined by + * DEFAULT_SPACELIMIT. + */ + public LRUCache() { + + this(DEFAULT_SPACELIMIT); + } + /** + * Creates a new cache. + * @param size Size of Cache + */ + public LRUCache(int size) { + + fTimestampCounter = fCurrentSpace = 0; + fEntryQueue = fEntryQueueTail = null; + fEntryTable = new Hashtable(size); + fSpaceLimit = size; + } + /** + * Returns a new cache containing the same contents. + * + * @return New copy of object. + */ + public Object clone() { + + LRUCache newCache = newInstance(fSpaceLimit); + LRUCacheEntry qEntry; + + /* Preserve order of entries by copying from oldest to newest */ + qEntry = this.fEntryQueueTail; + while (qEntry != null) { + newCache.privateAdd (qEntry._fKey, qEntry._fValue, qEntry._fSpace); + qEntry = qEntry._fPrevious; + } + return newCache; + } + /** + * Flushes all entries from the cache. + */ + public void flush() { + + fCurrentSpace = 0; + LRUCacheEntry entry = fEntryQueueTail; // Remember last entry + fEntryTable = new Hashtable(); // Clear it out + fEntryQueue = fEntryQueueTail = null; + while (entry != null) { // send deletion notifications in LRU order + privateNotifyDeletionFromCache(entry); + entry = entry._fPrevious; + } + } + /** + * Flushes the given entry from the cache. Does nothing if entry does not + * exist in cache. + * + * @param key Key of object to flush + */ + public void flush (Object key) { + + LRUCacheEntry entry; + + entry = (LRUCacheEntry) fEntryTable.get(key); + + /* If entry does not exist, return */ + if (entry == null) return; + + this.privateRemoveEntry (entry, false); + } + /** + * Answers the value in the cache at the given key. + * If the value is not in the cache, returns null + * + * @param key Hash table key of object to retrieve + * @return Retreived object, or null if object does not exist + */ + public Object get(Object key) { + + LRUCacheEntry entry = (LRUCacheEntry) fEntryTable.get(key); + if (entry == null) { + return null; + } + + this.updateTimestamp (entry); + return entry._fValue; + } + /** + * Returns the amount of space that is current used in the cache. + */ + public int getCurrentSpace() { + return fCurrentSpace; + } + /** + * Returns the maximum amount of space available in the cache. + */ + public int getSpaceLimit() { + return fSpaceLimit; + } + /** + * Returns an Enumeration of the keys currently in the cache. + */ + public Enumeration keys() { + + return fEntryTable.keys(); + } + /** + * Returns an enumeration that iterates over all the keys and values + * currently in the cache. + */ + public ICacheEnumeration keysAndValues() { + return new ICacheEnumeration() { + + Enumeration fValues = fEntryTable.elements(); + LRUCacheEntry fEntry; + + public boolean hasMoreElements() { + return fValues.hasMoreElements(); + } + + public Object nextElement() { + fEntry = (LRUCacheEntry) fValues.nextElement(); + return fEntry._fKey; + } + + public Object getValue() { + if (fEntry == null) { + throw new java.util.NoSuchElementException(); + } + return fEntry._fValue; + } + }; + } + /** + * Ensures there is the specified amount of free space in the receiver, + * by removing old entries if necessary. Returns true if the requested space was + * made available, false otherwise. + * + * @param space Amount of space to free up + */ + protected boolean makeSpace (int space) { + + int limit; + + limit = this.getSpaceLimit(); + + /* if space is already available */ + if (fCurrentSpace + space <= limit) { + return true; + } + + /* if entry is too big for cache */ + if (space > limit) { + return false; + } + + /* Free up space by removing oldest entries */ + while (fCurrentSpace + space > limit && fEntryQueueTail != null) { + this.privateRemoveEntry (fEntryQueueTail, false); + } + return true; + } + /** + * Returns a new LRUCache instance + */ + protected LRUCache newInstance(int size) { + return new LRUCache(size); + } + /** + * Adds an entry for the given key/value/space. + */ + protected void privateAdd (Object key, Object value, int space) { + + LRUCacheEntry entry; + + entry = new LRUCacheEntry(key, value, space); + this.privateAddEntry (entry, false); + } + /** + * Adds the given entry from the receiver. + * @param shuffle Indicates whether we are just shuffling the queue + * (in which case, the entry table is not modified). + */ + protected void privateAddEntry (LRUCacheEntry entry, boolean shuffle) { + + if (!shuffle) { + fEntryTable.put (entry._fKey, entry); + fCurrentSpace += entry._fSpace; + } + + entry._fTimestamp = fTimestampCounter++; + entry._fNext = this.fEntryQueue; + entry._fPrevious = null; + + if (fEntryQueue == null) { + /* this is the first and last entry */ + fEntryQueueTail = entry; + } else { + fEntryQueue._fPrevious = entry; + } + + fEntryQueue = entry; + } + /** + * An entry has been removed from the cache, for example because it has + * fallen off the bottom of the LRU queue. + * Subclasses could over-ride this to implement a persistent cache below the LRU cache. + */ + protected void privateNotifyDeletionFromCache(LRUCacheEntry entry) { + // Default is NOP. + } + /** + * Removes the entry from the entry queue. + * @param shuffle indicates whether we are just shuffling the queue + * (in which case, the entry table is not modified). + */ + protected void privateRemoveEntry (LRUCacheEntry entry, boolean shuffle) { + + LRUCacheEntry previous, next; + + previous = entry._fPrevious; + next = entry._fNext; + + if (!shuffle) { + fEntryTable.remove(entry._fKey); + fCurrentSpace -= entry._fSpace; + privateNotifyDeletionFromCache(entry); + } + + /* if this was the first entry */ + if (previous == null) { + fEntryQueue = next; + } else { + previous._fNext = next; + } + + /* if this was the last entry */ + if (next == null) { + fEntryQueueTail = previous; + } else { + next._fPrevious = previous; + } + } + /** + * Sets the value in the cache at the given key. Returns the value. + * + * @param key Key of object to add. + * @param value Value of object to add. + * @return added value. + */ + public Object put(Object key, Object value) { + + int newSpace, oldSpace, newTotal; + LRUCacheEntry entry; + + /* Check whether there's an entry in the cache */ + newSpace = spaceFor (key, value); + entry = (LRUCacheEntry) fEntryTable.get (key); + + if (entry != null) { + + /** + * Replace the entry in the cache if it would not overflow + * the cache. Otherwise flush the entry and re-add it so as + * to keep cache within budget + */ + oldSpace = entry._fSpace; + newTotal = getCurrentSpace() - oldSpace + newSpace; + if (newTotal <= getSpaceLimit()) { + updateTimestamp (entry); + entry._fValue = value; + entry._fSpace = newSpace; + this.fCurrentSpace = newTotal; + return value; + } else { + privateRemoveEntry (entry, false); + } + } + if (makeSpace(newSpace)) { + privateAdd (key, value, newSpace); + } + return value; + } + /** + * Removes and returns the value in the cache for the given key. + * If the key is not in the cache, returns null. + * + * @param key Key of object to remove from cache. + * @return Value removed from cache. + */ + public Object removeKey (Object key) { + + LRUCacheEntry entry = (LRUCacheEntry) fEntryTable.get(key); + if (entry == null) { + return null; + } + Object value = entry._fValue; + this.privateRemoveEntry (entry, false); + return value; + } + /** + * Sets the maximum amount of space that the cache can store + * + * @param limit Number of units of cache space + */ + public void setSpaceLimit(int limit) { + if (limit < fSpaceLimit) { + makeSpace(fSpaceLimit - limit); + } + fSpaceLimit = limit; + } + /** + * Returns the space taken by the given key and value. + */ + protected int spaceFor (Object key, Object value) { + + if (value instanceof ILRUCacheable) { + return ((ILRUCacheable) value).getCacheFootprint(); + } else { + return 1; + } + } +/** + * Returns a String that represents the value of this object. This method + * is for debugging purposes only. + */ +public String toString() { + return + "LRUCache " + (fCurrentSpace * 100.0 / fSpaceLimit) + "% full\n" + //$NON-NLS-1$ //$NON-NLS-2$ + this.toStringContents(); +} +/** + * Returns a String that represents the contents of this object. This method + * is for debugging purposes only. + */ +protected String toStringContents() { + StringBuffer result = new StringBuffer(); + int length = fEntryTable.size(); + Object[] unsortedKeys = new Object[length]; + String[] unsortedToStrings = new String[length]; + Enumeration e = this.keys(); + for (int i = 0; i < length; i++) { + Object key = e.nextElement(); + unsortedKeys[i] = key; + unsortedToStrings[i] = + (key instanceof net.sourceforge.phpdt.internal.core.JavaElement) ? + ((net.sourceforge.phpdt.internal.core.JavaElement)key).getElementName() : + key.toString(); + } + ToStringSorter sorter = new ToStringSorter(); + sorter.sort(unsortedKeys, unsortedToStrings); + for (int i = 0; i < length; i++) { + String toString = sorter.sortedStrings[i]; + Object value = this.get(sorter.sortedObjects[i]); + result.append(toString); + result.append(" -> "); //$NON-NLS-1$ + result.append(value); + result.append("\n"); //$NON-NLS-1$ + } + return result.toString(); +} + /** + * Updates the timestamp for the given entry, ensuring that the queue is + * kept in correct order. The entry must exist + */ + protected void updateTimestamp (LRUCacheEntry entry) { + + entry._fTimestamp = fTimestampCounter++; + if (fEntryQueue != entry) { + this.privateRemoveEntry (entry, true); + this.privateAddEntry (entry, true); + } + return; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/ReferenceInfoAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/ReferenceInfoAdapter.java new file mode 100644 index 0000000..a53bebd --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/ReferenceInfoAdapter.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.util; + +/** + * An adapter which implements the methods for handling + * reference information from the parser. + */ +public abstract class ReferenceInfoAdapter { +/** + * Does nothing. + */ +public void acceptConstructorReference(char[] typeName, int argCount, int sourcePosition) {} +/** + * Does nothing. + */ +public void acceptFieldReference(char[] fieldName, int sourcePosition) {} +/** + * Does nothing. + */ +public void acceptMethodReference(char[] methodName, int argCount, int sourcePosition) {} +/** + * Does nothing. + */ +public void acceptTypeReference(char[][] typeName, int sourceStart, int sourceEnd) {} +/** + * Does nothing. + */ +public void acceptTypeReference(char[] typeName, int sourcePosition) {} +/** + * Does nothing. + */ +public void acceptUnknownReference(char[][] name, int sourceStart, int sourceEnd) {} +/** + * Does nothing. + */ +public void acceptUnknownReference(char[] name, int sourcePosition) {} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/SimpleLookupTable.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/SimpleLookupTable.java new file mode 100644 index 0000000..01c61a6 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/SimpleLookupTable.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.util; + +/** + * A simple lookup table is a non-synchronized Hashtable, whose keys + * and values are Objects. It also uses linear probing to resolve collisions + * rather than a linked list of hash table entries. + */ +public final class SimpleLookupTable implements Cloneable { + +// to avoid using Enumerations, walk the individual tables skipping nulls +public Object[] keyTable; +public Object[] valueTable; +public int elementSize; // number of elements in the table +public int threshold; + +public SimpleLookupTable() { + this(13); +} + +public SimpleLookupTable(int size) { + if (size < 3) size = 3; + this.elementSize = 0; + this.threshold = size + 1; // size is the expected number of elements + int tableLength = 2 * size + 1; + this.keyTable = new Object[tableLength]; + this.valueTable = new Object[tableLength]; +} + +public Object clone() throws CloneNotSupportedException { + SimpleLookupTable result = (SimpleLookupTable) super.clone(); + result.elementSize = this.elementSize; + result.threshold = this.threshold; + + int length = this.keyTable.length; + result.keyTable = new Object[length]; + System.arraycopy(this.keyTable, 0, result.keyTable, 0, length); + + length = this.valueTable.length; + result.valueTable = new Object[length]; + System.arraycopy(this.valueTable, 0, result.valueTable, 0, length); + return result; +} + +public boolean containsKey(Object key) { + int length = keyTable.length; + int index = (key.hashCode() & 0x7FFFFFFF) % length; + Object currentKey; + while ((currentKey = keyTable[index]) != null) { + if (currentKey.equals(key)) return true; + if (++index == length) index = 0; + } + return false; +} + +public Object get(Object key) { + int length = keyTable.length; + int index = (key.hashCode() & 0x7FFFFFFF) % length; + Object currentKey; + while ((currentKey = keyTable[index]) != null) { + if (currentKey.equals(key)) return valueTable[index]; + if (++index == length) index = 0; + } + return null; +} + +public Object keyForValue(Object valueToMatch) { + if (valueToMatch != null) + for (int i = 0, l = valueTable.length; i < l; i++) + if (valueToMatch.equals(valueTable[i])) + return keyTable[i]; + return null; +} + +public Object put(Object key, Object value) { + int length = keyTable.length; + int index = (key.hashCode() & 0x7FFFFFFF) % length; + Object currentKey; + while ((currentKey = keyTable[index]) != null) { + if (currentKey.equals(key)) return valueTable[index] = value; + if (++index == length) index = 0; + } + keyTable[index] = key; + valueTable[index] = value; + + // assumes the threshold is never equal to the size of the table + if (++elementSize > threshold) rehash(); + return value; +} + +public void removeKey(Object key) { + int length = keyTable.length; + int index = (key.hashCode() & 0x7FFFFFFF) % length; + Object currentKey; + while ((currentKey = keyTable[index]) != null) { + if (currentKey.equals(key)) { + elementSize--; + keyTable[index] = null; + valueTable[index] = null; + if (keyTable[index + 1 == length ? 0 : index + 1] != null) + rehash(); // only needed if a possible collision existed + return; + } + if (++index == length) index = 0; + } +} + +public void removeValue(Object valueToRemove) { + boolean rehash = false; + for (int i = 0, l = valueTable.length; i < l; i++) { + Object value = valueTable[i]; + if (value != null && value.equals(valueToRemove)) { + elementSize--; + keyTable[i] = null; + valueTable[i] = null; + if (!rehash && keyTable[i + 1 == l ? 0 : i + 1] != null) + rehash = true; // only needed if a possible collision existed + } + } + if (rehash) rehash(); +} + +private void rehash() { + SimpleLookupTable newLookupTable = new SimpleLookupTable(elementSize * 2); // double the number of expected elements + Object currentKey; + for (int i = keyTable.length; --i >= 0;) + if ((currentKey = keyTable[i]) != null) + newLookupTable.put(currentKey, valueTable[i]); + + this.keyTable = newLookupTable.keyTable; + this.valueTable = newLookupTable.valueTable; + this.elementSize = newLookupTable.elementSize; + this.threshold = newLookupTable.threshold; +} + +public String toString() { + String s = ""; //$NON-NLS-1$ + Object object; + for (int i = 0, l = valueTable.length; i < l; i++) + if ((object = valueTable[i]) != null) + s += keyTable[i].toString() + " -> " + object.toString() + "\n"; //$NON-NLS-2$ //$NON-NLS-1$ + return s; +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/ToStringSorter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/ToStringSorter.java new file mode 100644 index 0000000..e2632f3 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/ToStringSorter.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.util; + +/** + * The SortOperation takes a collection of objects and returns + * a sorted collection of these objects. The sorting of these + * objects is based on their toString(). They are sorted in + * alphabetical order. + */ +public class ToStringSorter { + Object[] sortedObjects; + String[] sortedStrings; +/** + * Returns true if stringTwo is 'greater than' stringOne + * This is the 'ordering' method of the sort operation. + */ +public boolean compare(String stringOne, String stringTwo) { + return stringOne.compareTo(stringTwo) < 0; +} +/** + * Sort the objects in sorted collection and return that collection. + */ +private void quickSort(int left, int right) { + int originalLeft = left; + int originalRight = right; + int midIndex = (left + right) / 2; + String midToString = this.sortedStrings[midIndex]; + + do { + while (compare(this.sortedStrings[left], midToString)) + left++; + while (compare(midToString, this.sortedStrings[right])) + right--; + if (left <= right) { + Object tmp = this.sortedObjects[left]; + this.sortedObjects[left] = this.sortedObjects[right]; + this.sortedObjects[right] = tmp; + String tmpToString = this.sortedStrings[left]; + this.sortedStrings[left] = this.sortedStrings[right]; + this.sortedStrings[right] = tmpToString; + left++; + right--; + } + } while (left <= right); + + if (originalLeft < right) + quickSort(originalLeft, right); + if (left < originalRight) + quickSort(left, originalRight); +} +/** + * Return a new sorted collection from this unsorted collection. + * Sort using quick sort. + */ +public void sort(Object[] unSortedObjects, String[] unsortedStrings) { + int size = unSortedObjects.length; + this.sortedObjects = new Object[size]; + this.sortedStrings = new String[size]; + + //copy the array so can return a new sorted collection + System.arraycopy(unSortedObjects, 0, this.sortedObjects, 0, size); + System.arraycopy(unsortedStrings, 0, this.sortedStrings, 0, size); + if (size > 1) + quickSort(0, size - 1); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/Assert.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/Assert.java index c6f4e5c..8b3356a 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/Assert.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/Assert.java @@ -34,7 +34,7 @@ public final class Assert { * breakage when assertions in the code are added or removed. *

        */ - private static class AssertionFailedException extends RuntimeException { + public static class AssertionFailedException extends RuntimeException { /** * Constructs a new exception. diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextManipulationMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextManipulationMessages.java index eb8b44a..3857db1 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextManipulationMessages.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextManipulationMessages.java @@ -16,7 +16,7 @@ import java.util.ResourceBundle; public class TextManipulationMessages { - private static final String BUNDLE_NAME= "org.eclipse.jdt.internal.corext.textmanipulation.Messages"; //$NON-NLS-1$ + private static final String BUNDLE_NAME= "net.sourceforge.phpdt.internal.corext.textmanipulation.Messages"; //$NON-NLS-1$ private static final ResourceBundle RESOURCE_BUNDLE= ResourceBundle.getBundle(BUNDLE_NAME); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/JavaModelUtil.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/JavaModelUtil.java new file mode 100644 index 0000000..5fc7858 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/JavaModelUtil.java @@ -0,0 +1,699 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.corext.util; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import net.sourceforge.phpdt.core.Flags; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IField; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IMember; +import net.sourceforge.phpdt.core.IMethod; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.Signature; +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpeclipse.phpeditor.EditorUtility; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.SubProgressMonitor; + + + +/** + * Utility methods for the Java Model. + */ +public class JavaModelUtil { + + /** + * Finds a type by its qualified type name (dot separated). + * @param jproject The java project to search in + * @param str The fully qualified name (type name with enclosing type names and package (all separated by dots)) + * @return The type found, or null if not existing + */ +// public static IType findType(IJavaProject jproject, String fullyQualifiedName) throws JavaModelException { +// //workaround for bug 22883 +// IType type= jproject.findType(fullyQualifiedName); +// if (type != null) +// return type; +// IPackageFragmentRoot[] roots= jproject.getPackageFragmentRoots(); +// for (int i= 0; i < roots.length; i++) { +// IPackageFragmentRoot root= roots[i]; +// type= findType(root, fullyQualifiedName); +// if (type != null && type.exists()) +// return type; +// } +// return null; +// } + + /** + * Returns true if the given package fragment root is + * referenced. This means it is own by a different project but is referenced + * by the root's parent. Returns false if the given root + * doesn't have an underlying resource. + */ + public static boolean isReferenced(IPackageFragmentRoot root) { +// IResource resource= root.getResource(); +// if (resource != null) { +// IProject jarProject= resource.getProject(); +// IProject container= root.getJavaProject().getProject(); +// return !container.equals(jarProject); +// } + return false; + } + +// private static IType findType(IPackageFragmentRoot root, String fullyQualifiedName) throws JavaModelException{ +// IJavaElement[] children= root.getChildren(); +// for (int i= 0; i < children.length; i++) { +// IJavaElement element= children[i]; +// if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT){ +// IPackageFragment pack= (IPackageFragment)element; +// if (! fullyQualifiedName.startsWith(pack.getElementName())) +// continue; +// IType type= findType(pack, fullyQualifiedName); +// if (type != null && type.exists()) +// return type; +// } +// } +// return null; +// } + +// private static IType findType(IPackageFragment pack, String fullyQualifiedName) throws JavaModelException{ +// ICompilationUnit[] cus= pack.getCompilationUnits(); +// for (int i= 0; i < cus.length; i++) { +// ICompilationUnit unit= cus[i]; +// ICompilationUnit wc= WorkingCopyUtil.getWorkingCopyIfExists(unit); +// IType type= findType(wc, fullyQualifiedName); +// if (type != null && type.exists()) +// return type; +// } +// return null; +// } + +// private static IType findType(ICompilationUnit cu, String fullyQualifiedName) throws JavaModelException{ +// IType[] types= cu.getAllTypes(); +// for (int i= 0; i < types.length; i++) { +// IType type= types[i]; +// if (getFullyQualifiedName(type).equals(fullyQualifiedName)) +// return type; +// } +// return null; +// } + + /** + * Finds a type by package and type name. + * @param jproject the java project to search in + * @param pack The package name + * @param typeQualifiedName the type qualified name (type name with enclosing type names (separated by dots)) + * @return the type found, or null if not existing + * @deprecated Use IJavaProject.findType(String, String) instead + */ +// public static IType findType(IJavaProject jproject, String pack, String typeQualifiedName) throws JavaModelException { +// return jproject.findType(pack, typeQualifiedName); +// } + + /** + * Finds a type container by container name. + * The returned element will be of type IType or a IPackageFragment. + * null is returned if the type container could not be found. + * @param jproject The Java project defining the context to search + * @param typeContainerName A dot separarted name of the type container + * @see #getTypeContainerName(IType) + */ +// public static IJavaElement findTypeContainer(IJavaProject jproject, String typeContainerName) throws JavaModelException { +// // try to find it as type +// IJavaElement result= jproject.findType(typeContainerName); +// if (result == null) { +// // find it as package +// IPath path= new Path(typeContainerName.replace('.', '/')); +// result= jproject.findElement(path); +// if (!(result instanceof IPackageFragment)) { +// result= null; +// } +// +// } +// return result; +// } + + /** + * Finds a type in a compilation unit. Typical usage is to find the corresponding + * type in a working copy. + * @param cu the compilation unit to search in + * @param typeQualifiedName the type qualified name (type name with enclosing type names (separated by dots)) + * @return the type found, or null if not existing + */ + public static IType findTypeInCompilationUnit(ICompilationUnit cu, String typeQualifiedName) throws JavaModelException { + IType[] types= cu.getAllTypes(); + for (int i= 0; i < types.length; i++) { + String currName= getTypeQualifiedName(types[i]); + if (typeQualifiedName.equals(currName)) { + return types[i]; + } + } + return null; + } + + /** + * Finds a a member in a compilation unit. Typical usage is to find the corresponding + * member in a working copy. + * @param cu the compilation unit (eg. working copy) to search in + * @param member the member (eg. from the original) + * @return the member found, or null if not existing + */ + public static IMember findMemberInCompilationUnit(ICompilationUnit cu, IMember member) throws JavaModelException { + IJavaElement[] elements= cu.findElements(member); + if (elements != null && elements.length > 0) { + return (IMember) elements[0]; + } + return null; + } + + + /** + * Returns the element of the given compilation unit which is "equal" to the + * given element. Note that the given element usually has a parent different + * from the given compilation unit. + * + * @param cu the cu to search in + * @param element the element to look for + * @return an element of the given cu "equal" to the given element + */ + public static IJavaElement findInCompilationUnit(ICompilationUnit cu, IJavaElement element) throws JavaModelException { + IJavaElement[] elements= cu.findElements(element); + if (elements != null && elements.length > 0) { + return elements[0]; + } + return null; + } + + /** + * Returns the qualified type name of the given type using '.' as separators. + * This is a replace for IType.getTypeQualifiedName() + * which uses '$' as separators. As '$' is also a valid character in an id + * this is ambiguous. JavaCore PR: 1GCFUNT + */ + public static String getTypeQualifiedName(IType type) { + return type.getTypeQualifiedName('.'); + } + + private static void getTypeQualifiedName(IType type, StringBuffer buf) { + IType outerType= type.getDeclaringType(); + if (outerType != null) { + getTypeQualifiedName(outerType, buf); + buf.append('.'); + } + buf.append(type.getElementName()); + } + + /** + * Returns the fully qualified name of the given type using '.' as separators. + * This is a replace for IType.getFullyQualifiedTypeName + * which uses '$' as separators. As '$' is also a valid character in an id + * this is ambiguous. JavaCore PR: 1GCFUNT + */ + public static String getFullyQualifiedName(IType type) { + return type.getFullyQualifiedName('.'); + } + + /** + * Returns the fully qualified name of a type's container. (package name or enclosing type name) + */ + public static String getTypeContainerName(IType type) { + IType outerType= type.getDeclaringType(); + if (outerType != null) { + return outerType.getFullyQualifiedName('.'); + } else { + return type.getPackageFragment().getElementName(); + } + } + + + /** + * Concatenates two names. Uses a dot for separation. + * Both strings can be empty or null. + */ + public static String concatenateName(String name1, String name2) { + StringBuffer buf= new StringBuffer(); + if (name1 != null && name1.length() > 0) { + buf.append(name1); + } + if (name2 != null && name2.length() > 0) { + if (buf.length() > 0) { + buf.append('.'); + } + buf.append(name2); + } + return buf.toString(); + } + + /** + * Concatenates two names. Uses a dot for separation. + * Both strings can be empty or null. + */ + public static String concatenateName(char[] name1, char[] name2) { + StringBuffer buf= new StringBuffer(); + if (name1 != null && name1.length > 0) { + buf.append(name1); + } + if (name2 != null && name2.length > 0) { + if (buf.length() > 0) { + buf.append('.'); + } + buf.append(name2); + } + return buf.toString(); + } + + /** + * Evaluates if a member (possible from another package) is visible from + * elements in a package. + * @param member The member to test the visibility for + * @param pack The package in focus + */ + public static boolean isVisible(IMember member, IPackageFragment pack) throws JavaModelException { + int otherflags= member.getFlags(); + + if (Flags.isPublic(otherflags)) { + return true; + } else if (Flags.isPrivate(otherflags)) { + return false; + } + + IPackageFragment otherpack= (IPackageFragment) findParentOfKind(member, IJavaElement.PACKAGE_FRAGMENT); + return (pack != null && pack.equals(otherpack)); + } + + /** + * Returns the package fragment root of IJavaElement. If the given + * element is already a package fragment root, the element itself is returned. + */ + public static IPackageFragmentRoot getPackageFragmentRoot(IJavaElement element) { + return (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); + } + + /** + * Returns the parent of the supplied java element that conforms to the given + * parent type or null, if such a parent doesn't exit. + * @deprecated Use element.getParent().getAncestor(kind); + */ + public static IJavaElement findParentOfKind(IJavaElement element, int kind) { + if (element != null && element.getParent() != null) { + return element.getParent().getAncestor(kind); + } + return null; + } + + /** + * Finds a method in a type. + * This searches for a method with the same name and signature. Parameter types are only + * compared by the simple name, no resolving for the fully qualified type name is done. + * Constructors are only compared by parameters, not the name. + * @param name The name of the method to find + * @param paramTypes The type signatures of the parameters e.g. {"QString;","I"} + * @param isConstructor If the method is a constructor + * @return The first found method or null, if nothing found + */ + public static IMethod findMethod(String name, String[] paramTypes, boolean isConstructor, IType type) throws JavaModelException { + return findMethod(name, paramTypes, isConstructor, type.getMethods()); + } + + /** + * Finds a method by name. + * This searches for a method with a name and signature. Parameter types are only + * compared by the simple name, no resolving for the fully qualified type name is done. + * Constructors are only compared by parameters, not the name. + * @param name The name of the method to find + * @param paramTypes The type signatures of the parameters e.g. {"QString;","I"} + * @param isConstructor If the method is a constructor + * @param methods The methods to search in + * @return The found method or null, if nothing found + */ + public static IMethod findMethod(String name, String[] paramTypes, boolean isConstructor, IMethod[] methods) throws JavaModelException { + for (int i= methods.length - 1; i >= 0; i--) { + if (isSameMethodSignature(name, paramTypes, isConstructor, methods[i])) { + return methods[i]; + } + } + return null; + } + + + /** + * Finds a method declararion in a type's hierarchy. The search is top down, so this + * returns the first declaration of the method in the hierarchy. + * This searches for a method with a name and signature. Parameter types are only + * compared by the simple name, no resolving for the fully qualified type name is done. + * Constructors are only compared by parameters, not the name. + * @param type Searches in this type's supertypes. + * @param name The name of the method to find + * @param paramTypes The type signatures of the parameters e.g. {"QString;","I"} + * @param isConstructor If the method is a constructor + * @return The first method found or null, if nothing found + */ +// public static IMethod findMethodDeclarationInHierarchy(ITypeHierarchy hierarchy, IType type, String name, String[] paramTypes, boolean isConstructor) throws JavaModelException { +// IType[] superTypes= hierarchy.getAllSupertypes(type); +// for (int i= superTypes.length - 1; i >= 0; i--) { +// IMethod first= findMethod(name, paramTypes, isConstructor, superTypes[i]); +// if (first != null && !Flags.isPrivate(first.getFlags())) { +// // the order getAllSupertypes does make assumptions of the order of inner elements -> search recursivly +// IMethod res= findMethodDeclarationInHierarchy(hierarchy, first.getDeclaringType(), name, paramTypes, isConstructor); +// if (res != null) { +// return res; +// } +// return first; +// } +// } +// return null; +// } + + /** + * Finds a method implementation in a type's classhierarchy. The search is bottom-up, so this + * returns the nearest overridden method. Does not find methods in interfaces or abstract methods. + * This searches for a method with a name and signature. Parameter types are only + * compared by the simple name, no resolving for the fully qualified type name is done. + * Constructors are only compared by parameters, not the name. + * @param type Type to search the superclasses + * @param name The name of the method to find + * @param paramTypes The type signatures of the parameters e.g. {"QString;","I"} + * @param isConstructor If the method is a constructor + * @return The first method found or null, if nothing found + */ +// public static IMethod findMethodImplementationInHierarchy(ITypeHierarchy hierarchy, IType type, String name, String[] paramTypes, boolean isConstructor) throws JavaModelException { +// IType[] superTypes= hierarchy.getAllSuperclasses(type); +// for (int i= 0; i < superTypes.length; i++) { +// IMethod found= findMethod(name, paramTypes, isConstructor, superTypes[i]); +// if (found != null) { +// if (Flags.isAbstract(found.getFlags())) { +// return null; +// } +// return found; +// } +// } +// return null; +// } + + /** + * Tests if a method equals to the given signature. + * Parameter types are only compared by the simple name, no resolving for + * the fully qualified type name is done. Constructors are only compared by + * parameters, not the name. + * @param Name of the method + * @param The type signatures of the parameters e.g. {"QString;","I"} + * @param Specifies if the method is a constructor + * @return Returns true if the method has the given name and parameter types and constructor state. + */ + public static boolean isSameMethodSignature(String name, String[] paramTypes, boolean isConstructor, IMethod curr) throws JavaModelException { + if (isConstructor || name.equals(curr.getElementName())) { + if (isConstructor == curr.isConstructor()) { + String[] currParamTypes= curr.getParameterTypes(); + if (paramTypes.length == currParamTypes.length) { + for (int i= 0; i < paramTypes.length; i++) { + String t1= Signature.getSimpleName(Signature.toString(paramTypes[i])); + String t2= Signature.getSimpleName(Signature.toString(currParamTypes[i])); + if (!t1.equals(t2)) { + return false; + } + } + return true; + } + } + } + return false; + } + + /** + * Checks whether the given type has a valid main method or not. + */ + public static boolean hasMainMethod(IType type) throws JavaModelException { + IMethod[] methods= type.getMethods(); + for (int i= 0; i < methods.length; i++) { + if (methods[i].isMainMethod()) { + return true; + } + } + return false; + } + + /** + * Checks if the field is boolean. + */ + public static boolean isBoolean(IField field) throws JavaModelException{ + return field.getTypeSignature().equals(Signature.SIG_BOOLEAN); + } + + /** + * Returns true if the element is on the build path of the given project + * @deprecated Use jproject.isOnClasspath(element); + */ +// public static boolean isOnBuildPath(IJavaProject jproject, IJavaElement element) throws JavaModelException { +// return jproject.isOnClasspath(element); +// } + + /** + * Tests if the given element is on the class path of its containing project. Handles the case + * that the containing project isn't a Java project. + */ +// public static boolean isOnClasspath(IJavaElement element) { +// IJavaProject project= element.getJavaProject(); +// if (!project.exists()) +// return false; +// return project.isOnClasspath(element); +// } + + /** + * Resolves a type name in the context of the declaring type. + * @param refTypeSig the type name in signature notation (for example 'QVector') + * this can also be an array type, but dimensions will be ignored. + * @param declaringType the context for resolving (type where the reference was made in) + * @return returns the fully qualified type name or build-in-type name. + * if a unresoved type couldn't be resolved null is returned + */ + public static String getResolvedTypeName(String refTypeSig, IType declaringType) throws JavaModelException { + int arrayCount= Signature.getArrayCount(refTypeSig); + char type= refTypeSig.charAt(arrayCount); + if (type == Signature.C_UNRESOLVED) { + int semi= refTypeSig.indexOf(Signature.C_SEMICOLON, arrayCount + 1); + if (semi == -1) { + throw new IllegalArgumentException(); + } + String name= refTypeSig.substring(arrayCount + 1, semi); + +// String[][] resolvedNames= declaringType.resolveType(name); +// if (resolvedNames != null && resolvedNames.length > 0) { +// return JavaModelUtil.concatenateName(resolvedNames[0][0], resolvedNames[0][1]); +// } + return null; + } else { + return Signature.toString(refTypeSig.substring(arrayCount)); + } + } + + /** + * Returns if a CU can be edited. + */ + public static boolean isEditable(ICompilationUnit cu) { + if (cu.isWorkingCopy()) { + cu= (ICompilationUnit) cu.getOriginalElement(); + } + IResource resource= cu.getResource(); + return (resource.exists() && !resource.isReadOnly()); + } + + /** + * Finds a qualified import for a type name. + */ +// public static IImportDeclaration findImport(ICompilationUnit cu, String simpleName) throws JavaModelException { +// IImportDeclaration[] existing= cu.getImports(); +// for (int i= 0; i < existing.length; i++) { +// String curr= existing[i].getElementName(); +// if (curr.endsWith(simpleName)) { +// int dotPos= curr.length() - simpleName.length() - 1; +// if ((dotPos == -1) || (dotPos > 0 && curr.charAt(dotPos) == '.')) { +// return existing[i]; +// } +// } +// } +// return null; +// } + + /** + * Returns the original if the given member. If the member is already + * an original the input is returned. The returned member must not exist + */ + public static IMember toOriginal(IMember member) { + if (member instanceof IMethod) + return toOriginalMethod((IMethod)member); + ICompilationUnit cu= member.getCompilationUnit(); + if (cu != null && cu.isWorkingCopy()) + return (IMember)cu.getOriginal(member); + return member; + } + + /* + * XXX workaround for bug 18568 + * http://bugs.eclipse.org/bugs/show_bug.cgi?id=18568 + * to be removed once the bug is fixed + */ + private static IMethod toOriginalMethod(IMethod method) { + try{ + ICompilationUnit cu= method.getCompilationUnit(); + if (cu == null || ! cu.isWorkingCopy()) + return method; + //use the workaround only if needed + if (! method.getElementName().equals(method.getDeclaringType().getElementName())) + return (IMethod)cu.getOriginal(method); + + IType originalType = (IType)toOriginal(method.getDeclaringType()); + IMethod[] methods = originalType.findMethods(method); + boolean isConstructor = method.isConstructor(); + for (int i=0; i < methods.length; i++) { + if (methods[i].isConstructor() == isConstructor) + return methods[i]; + } + return null; + } catch(JavaModelException e){ + return null; + } + } + + /** + * Returns the original cu if the given cu. If the cu is already + * an original the input cu is returned. The returned cu must not exist + */ + public static ICompilationUnit toOriginal(ICompilationUnit cu) { + if (cu != null && cu.isWorkingCopy()) + return (ICompilationUnit) cu.getOriginal(cu); + return cu; + } + + /** + * Returns the working copy of the given member. If the member is already in a + * working copy or the member does not exist in the working copy the input is returned. + */ + public static IMember toWorkingCopy(IMember member) { + ICompilationUnit cu= member.getCompilationUnit(); + if (cu != null && !cu.isWorkingCopy()) { + ICompilationUnit workingCopy= EditorUtility.getWorkingCopy(cu); + if (workingCopy != null) { + IJavaElement[] members= workingCopy.findElements(member); + if (members != null && members.length > 0) { + return (IMember) members[0]; + } + } + } + return member; + } + + + /** + * Returns the working copy CU of the given CU. If the CU is already a + * working copy or the CU has no working copy the input CU is returned. + */ + public static ICompilationUnit toWorkingCopy(ICompilationUnit cu) { + if (!cu.isWorkingCopy()) { + ICompilationUnit workingCopy= EditorUtility.getWorkingCopy(cu); + if (workingCopy != null) { + return workingCopy; + } + } + return cu; + } + + /* + * http://bugs.eclipse.org/bugs/show_bug.cgi?id=19253 + * + * Reconciling happens in a separate thread. This can cause a situation where the + * Java element gets disposed after an exists test has been done. So we should not + * log not present exceptions when they happen in working copies. + */ + public static boolean filterNotPresentException(CoreException exception) { + if (!(exception instanceof JavaModelException)) + return true; + JavaModelException je= (JavaModelException)exception; + if (!je.isDoesNotExist()) + return true; + IJavaElement[] elements= je.getJavaModelStatus().getElements(); + for (int i= 0; i < elements.length; i++) { + IJavaElement element= elements[i]; + ICompilationUnit unit= (ICompilationUnit)element.getAncestor(IJavaElement.COMPILATION_UNIT); + if (unit == null) + return true; + if (!unit.isWorkingCopy()) + return true; + } + return false; + } + +// public static IType[] getAllSuperTypes(IType type, IProgressMonitor pm) throws JavaModelException { +// //workaround for bugs 23644 and 23656 +// try{ +// pm.beginTask("", 3); //$NON-NLS-1$ +// ITypeHierarchy hierarchy= type.newSupertypeHierarchy(new SubProgressMonitor(pm, 1)); +// +// IProgressMonitor subPm= new SubProgressMonitor(pm, 2); +// List typeList= Arrays.asList(hierarchy.getAllSupertypes(type)); +// subPm.beginTask("", typeList.size()); //$NON-NLS-1$ +// Set types= new HashSet(typeList); +// for (Iterator iter= typeList.iterator(); iter.hasNext();) { +// IType superType= (IType)iter.next(); +// IType[] superTypes= getAllSuperTypes(superType, new SubProgressMonitor(subPm, 1)); +// types.addAll(Arrays.asList(superTypes)); +// } +// types.add(type.getJavaProject().findType("java.lang.Object"));//$NON-NLS-1$ +// subPm.done(); +// return (IType[]) types.toArray(new IType[types.size()]); +// } finally { +// pm.done(); +// } +// } + + + public static boolean isExcludedPath(IPath resourcePath, IPath[] exclusionPatterns) { + char[] path = resourcePath.toString().toCharArray(); + for (int i = 0, length = exclusionPatterns.length; i < length; i++) { + char[] pattern= exclusionPatterns[i].toString().toCharArray(); + if (CharOperation.pathMatch(pattern, path, true, '/')) { + return true; + } + } + return false; + } + + + /* + * Returns whether the given resource path matches one of the exclusion + * patterns. + * + * @see IClasspathEntry#getExclusionPatterns + */ + public final static boolean isExcluded(IPath resourcePath, char[][] exclusionPatterns) { + if (exclusionPatterns == null) return false; + char[] path = resourcePath.toString().toCharArray(); + for (int i = 0, length = exclusionPatterns.length; i < length; i++) + if (CharOperation.pathMatch(exclusionPatterns[i], path, true, '/')) + return true; + return false; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/IJavaHelpContextIds.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/IJavaHelpContextIds.java new file mode 100644 index 0000000..cc130f4 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/IJavaHelpContextIds.java @@ -0,0 +1,304 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui; + +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + + + +/** + * Help context ids for the Java UI. + *

        + * This interface contains constants only; it is not intended to be implemented + * or extended. + *

        + * + */ +public interface IJavaHelpContextIds { + public static final String PREFIX= PHPeclipsePlugin.PLUGIN_ID + '.'; + + // Actions + public static final String GETTERSETTER_ACTION= PREFIX + "getter_setter_action_context"; //$NON-NLS-1$ + public static final String ADD_METHODSTUB_ACTION= PREFIX + "add_methodstub_action_context"; //$NON-NLS-1$ + public static final String ADD_UNIMPLEMENTED_METHODS_ACTION= PREFIX + "add_unimplemented_methods_action_context"; //$NON-NLS-1$ + public static final String ADD_UNIMPLEMENTED_CONSTRUCTORS_ACTION= PREFIX + "add_unimplemented_constructors_action_context"; //$NON-NLS-1$ + public static final String SHOW_IN_PACKAGEVIEW_ACTION= PREFIX + "show_in_packageview_action_context"; //$NON-NLS-1$ + public static final String SHOW_IN_HIERARCHYVIEW_ACTION= PREFIX + "show_in_hierarchyview_action_context"; //$NON-NLS-1$ + public static final String FOCUS_ON_SELECTION_ACTION= PREFIX + "focus_on_selection_action"; //$NON-NLS-1$ + public static final String FOCUS_ON_TYPE_ACTION= PREFIX + "focus_on_type_action"; //$NON-NLS-1$ + + public static final String TYPEHIERARCHY_HISTORY_ACTION= PREFIX + "typehierarchy_history_action"; //$NON-NLS-1$ + public static final String FILTER_PUBLIC_ACTION= PREFIX + "filter_public_action"; //$NON-NLS-1$ + public static final String FILTER_FIELDS_ACTION= PREFIX + "filter_fields_action"; //$NON-NLS-1$ + public static final String FILTER_STATIC_ACTION= PREFIX + "filter_static_action"; //$NON-NLS-1$ + public static final String SHOW_INHERITED_ACTION= PREFIX + "show_inherited_action"; //$NON-NLS-1$ + public static final String SHOW_SUPERTYPES= PREFIX + "show_supertypes_action"; //$NON-NLS-1$ + public static final String SHOW_SUBTYPES= PREFIX + "show_subtypes_action"; //$NON-NLS-1$ + public static final String SHOW_HIERARCHY= PREFIX + "show_hierarchy_action"; //$NON-NLS-1$ + public static final String ENABLE_METHODFILTER_ACTION= PREFIX + "enable_methodfilter_action"; //$NON-NLS-1$ + public static final String ADD_IMPORT_ON_SELECTION_ACTION= PREFIX + "add_imports_on_selection_action_context"; //$NON-NLS-1$ + public static final String ORGANIZE_IMPORTS_ACTION= PREFIX + "organize_imports_action_context"; //$NON-NLS-1$ + public static final String ADD_TO_CLASSPATH_ACTION= PREFIX + "addjtoclasspath_action_context"; //$NON-NLS-1$ + public static final String REMOVE_FROM_CLASSPATH_ACTION= PREFIX + "removefromclasspath_action_context"; //$NON-NLS-1$ + + public static final String TOGGLE_PRESENTATION_ACTION= PREFIX + "toggle_presentation_action_context"; //$NON-NLS-1$ + public static final String TOGGLE_TEXTHOVER_ACTION= PREFIX + "toggle_texthover_action_context"; //$NON-NLS-1$ + + public static final String OPEN_CLASS_WIZARD_ACTION= PREFIX + "open_class_wizard_action"; //$NON-NLS-1$ + public static final String OPEN_INTERFACE_WIZARD_ACTION= PREFIX + "open_interface_wizard_action"; //$NON-NLS-1$ + public static final String SORT_MEMBERS_ACTION= PREFIX + "sort_members_action"; //$NON-NLS-1$ + + public static final String OPEN_PACKAGE_WIZARD_ACTION= PREFIX + "open_package_wizard_action"; //$NON-NLS-1$ + public static final String OPEN_PROJECT_WIZARD_ACTION= PREFIX + "open_project_wizard_action"; //$NON-NLS-1$ + public static final String OPEN_SNIPPET_WIZARD_ACTION= PREFIX + "open_snippet_wizard_action"; //$NON-NLS-1$ + public static final String EDIT_WORKING_SET_ACTION= PREFIX + "edit_working_set_action"; //$NON-NLS-1$ + public static final String CLEAR_WORKING_SET_ACTION= PREFIX + "clear_working_set_action"; //$NON-NLS-1$ + public static final String GOTO_MARKER_ACTION= PREFIX + "goto_marker_action"; //$NON-NLS-1$ + public static final String GOTO_PACKAGE_ACTION= PREFIX + "goto_package_action"; //$NON-NLS-1$ + public static final String GOTO_TYPE_ACTION= PREFIX + "goto_type_action"; //$NON-NLS-1$ + public static final String GOTO_MATCHING_BRACKET_ACTION= PREFIX + "goto_matching_bracket_action"; //$NON-NLS-1$ + public static final String GOTO_NEXT_MEMBER_ACTION= PREFIX + "goto_next_member_action"; //$NON-NLS-1$ + public static final String GOTO_PREVIOUS_MEMBER_ACTION= PREFIX + "goto_previous_member_action"; //$NON-NLS-1$ + public static final String HISTORY_ACTION= PREFIX + "history_action"; //$NON-NLS-1$ + public static final String HISTORY_LIST_ACTION= PREFIX + "history_list_action"; //$NON-NLS-1$ + public static final String LEXICAL_SORTING_OUTLINE_ACTION= PREFIX + "lexical_sorting_outline_action"; //$NON-NLS-1$ + public static final String LEXICAL_SORTING_BROWSING_ACTION= PREFIX + "lexical_sorting_browsing_action"; //$NON-NLS-1$ + public static final String OPEN_JAVA_PERSPECTIVE_ACTION= PREFIX + "open_java_perspective_action"; //$NON-NLS-1$ + public static final String ADD_DELEGATE_METHODS_ACTION= PREFIX + "add_delegate_methods_action"; //$NON-NLS-1$ + + public static final String OPEN_JAVA_BROWSING_PERSPECTIVE_ACTION= PREFIX + "open_java_browsing_perspective_action"; //$NON-NLS-1$ + public static final String OPEN_PROJECT_ACTION= PREFIX + "open_project_action"; //$NON-NLS-1$ + public static final String OPEN_TYPE_ACTION= PREFIX + "open_type_action"; //$NON-NLS-1$ + public static final String OPEN_TYPE_IN_HIERARCHY_ACTION= PREFIX + "open_type_in_hierarchy_action"; //$NON-NLS-1$ + public static final String ADD_JAVADOC_STUB_ACTION= PREFIX + "add_javadoc_stub_action"; //$NON-NLS-1$ + public static final String ADD_TASK_ACTION= PREFIX + "add_task_action"; //$NON-NLS-1$ + public static final String EXTERNALIZE_STRINGS_ACTION= PREFIX + "externalize_strings_action"; //$NON-NLS-1$ + public static final String EXTRACT_METHOD_ACTION= PREFIX + "extract_method_action"; //$NON-NLS-1$ + public static final String EXTRACT_TEMP_ACTION= PREFIX + "extract_temp_action"; //$NON-NLS-1$ + public static final String PROMOTE_TEMP_TO_FIELD_ACTION= PREFIX + "promote_temp_to_field_action"; //$NON-NLS-1$ + public static final String CONVERT_ANONYMOUS_TO_NESTED_ACTION= PREFIX + "convert_anonymous_to_nested_action"; //$NON-NLS-1$ + public static final String EXTRACT_CONSTANT_ACTION= PREFIX + "extract_constant_action"; //$NON-NLS-1$ + public static final String EXTRACT_INTERFACE_ACTION= PREFIX + "extract_interface_action"; //$NON-NLS-1$ + public static final String MOVE_INNER_TO_TOP_ACTION= PREFIX + "move_inner_to_top_level_action"; //$NON-NLS-1$ + public static final String USE_SUPERTYPE_ACTION= PREFIX + "use_supertype_action"; //$NON-NLS-1$ + public static final String FIND_DECLARATIONS_IN_WORKSPACE_ACTION= PREFIX + "find_declarations_in_workspace_action"; //$NON-NLS-1$ + public static final String FIND_DECLARATIONS_IN_HIERARCHY_ACTION= PREFIX + "find_declarations_in_hierarchy_action"; //$NON-NLS-1$ + public static final String FIND_DECLARATIONS_IN_WORKING_SET_ACTION= PREFIX + "find_declarations_in_working_set_action"; //$NON-NLS-1$ + public static final String FIND_IMPLEMENTORS_IN_WORKSPACE_ACTION= PREFIX + "find_implementors_in_workspace_action"; //$NON-NLS-1$ + public static final String FIND_IMPLEMENTORS_IN_WORKING_SET_ACTION= PREFIX + "find_implementors_in_working_set_action"; //$NON-NLS-1$ + public static final String FIND_REFERENCES_IN_WORKSPACE_ACTION= PREFIX + "find_references_in_workspace_action"; //$NON-NLS-1$ + public static final String FIND_REFERENCES_IN_HIERARCHY_ACTION= PREFIX + "find_references_in_hierarchy_action"; //$NON-NLS-1$ + public static final String FIND_REFERENCES_IN_WORKING_SET_ACTION= PREFIX + "find_references_in_working_set_action"; //$NON-NLS-1$ + public static final String FIND_READ_REFERENCES_IN_WORKSPACE_ACTION= PREFIX + "find_read_references_in_workspace_action"; //$NON-NLS-1$ + public static final String FIND_READ_REFERENCES_IN_HIERARCHY_ACTION= PREFIX + "find_read_references_in_hierarchy_action"; //$NON-NLS-1$ + public static final String FIND_READ_REFERENCES_IN_WORKING_SET_ACTION= PREFIX + "find_read_references_in_working_set_action"; //$NON-NLS-1$ + public static final String FIND_WRITE_REFERENCES_IN_HIERARCHY_ACTION= PREFIX + "find_write_references_in_hierarchy_action"; //$NON-NLS-1$ + public static final String FIND_WRITE_REFERENCES_IN_WORKING_SET_ACTION= PREFIX + "find_write_references_in_working_set_action"; //$NON-NLS-1$ + public static final String FIND_WRITE_REFERENCES_IN_WORKSPACE_ACTION= PREFIX + "find_write_references_in_workspace_action"; //$NON-NLS-1$ + public static final String FIND_OCCURRENCES_IN_FILE_ACTION= PREFIX + "find_occurrences_in_file_action"; //$NON-NLS-1$ + public static final String WORKING_SET_FIND_ACTION= PREFIX + "working_set_find_action"; //$NON-NLS-1$ + public static final String FIND_STRINGS_TO_EXTERNALIZE_ACTION= PREFIX + "find_strings_to_externalize_action"; //$NON-NLS-1$ + public static final String INLINE_ACTION= PREFIX + "inline_action"; //$NON-NLS-1$ + public static final String MODIFY_PARAMETERS_ACTION= PREFIX + "modify_parameters_action"; //$NON-NLS-1$ + public static final String MOVE_ACTION= PREFIX + "move_action"; //$NON-NLS-1$ + public static final String OPEN_ACTION= PREFIX + "open_action"; //$NON-NLS-1$ + public static final String OPEN_EXTERNAL_JAVADOC_ACTION= PREFIX + "open_external_javadoc_action"; //$NON-NLS-1$ + public static final String OPEN_SUPER_IMPLEMENTATION_ACTION= PREFIX + "open_super_implementation_action"; //$NON-NLS-1$ + public static final String PULL_UP_ACTION= PREFIX + "pull_up_action"; //$NON-NLS-1$ + public static final String PUSH_DOWN_ACTION= PREFIX + "push_down_action"; //$NON-NLS-1$ + public static final String REFRESH_ACTION= PREFIX + "refresh_action"; //$NON-NLS-1$ + public static final String RENAME_ACTION= PREFIX + "rename_action"; //$NON-NLS-1$ + public static final String SELF_ENCAPSULATE_ACTION= PREFIX + "self_encapsulate_action"; //$NON-NLS-1$ + public static final String SHOW_IN_NAVIGATOR_VIEW_ACTION= PREFIX + "show_in_navigator_action"; //$NON-NLS-1$ + public static final String SURROUND_WITH_TRY_CATCH_ACTION= PREFIX + "surround_with_try_catch_action"; //$NON-NLS-1$ + public static final String OPEN_RESOURCE_ACTION= PREFIX + "open_resource_action"; //$NON-NLS-1$ + public static final String SELECT_WORKING_SET_ACTION= PREFIX + "select_working_set_action"; //$NON-NLS-1$ + public static final String STRUCTURED_SELECTION_HISTORY_ACTION= PREFIX + "structured_selection_history_action"; //$NON-NLS-1$ + public static final String STRUCTURED_SELECT_ENCLOSING_ACTION= PREFIX + "structured_select_enclosing_action"; //$NON-NLS-1$ + public static final String STRUCTURED_SELECT_NEXT_ACTION= PREFIX + "structured_select_next_action"; //$NON-NLS-1$ + public static final String STRUCTURED_SELECT_PREVIOUS_ACTION= PREFIX + "structured_select_previous_action"; //$NON-NLS-1$ + public static final String TOGGLE_ORIENTATION_ACTION= PREFIX + "toggle_orientations_action"; //$NON-NLS-1$ + public static final String CUT_ACTION= PREFIX + "cut_action"; //$NON-NLS-1$ + public static final String COPY_ACTION= PREFIX + "copy_action"; //$NON-NLS-1$ + public static final String PASTE_ACTION= PREFIX + "paste_action"; //$NON-NLS-1$ + public static final String DELETE_ACTION= PREFIX + "delete_action"; //$NON-NLS-1$ + public static final String SELECT_ALL_ACTION= PREFIX + "select_all_action"; //$NON-NLS-1$ + public static final String OPEN_TYPE_HIERARCHY_ACTION= PREFIX + "open_type_hierarchy_action"; //$NON-NLS-1$ + public static final String COLLAPSE_ALL_ACTION= PREFIX + "open_type_hierarchy_action"; //$NON-NLS-1$ + public static final String GOTO_RESOURCE_ACTION= PREFIX + "goto_resource_action"; //$NON-NLS-1$ + public static final String LINK_EDITOR_ACTION= PREFIX + "link_editor_action"; //$NON-NLS-1$ + public static final String GO_INTO_TOP_LEVEL_TYPE_ACTION= PREFIX + "go_into_top_level_type_action"; //$NON-NLS-1$ + public static final String COMPARE_WITH_HISTORY_ACTION= PREFIX + "compare_with_history_action"; //$NON-NLS-1$ + public static final String REPLACE_WITH_PREVIOUS_FROM_HISTORY_ACTION= PREFIX + "replace_with_previous_from_history_action"; //$NON-NLS-1$ + public static final String REPLACE_WITH_HISTORY_ACTION= PREFIX + "replace_with_history_action"; //$NON-NLS-1$ + public static final String ADD_FROM_HISTORY_ACTION= PREFIX + "add_from_history_action"; //$NON-NLS-1$ + public static final String LAYOUT_FLAT_ACTION= PREFIX + "layout_flat_action"; //$NON-NLS-1$ + public static final String LAYOUT_HIERARCHICAL_ACTION= PREFIX + "layout_hierarchical_action"; //$NON-NLS-1$ + public static final String NEXT_CHANGE_ACTION= PREFIX + "next_change_action"; //$NON-NLS-1$ + public static final String PREVIOUS_CHANGE_ACTION= PREFIX + "previous_change_action"; //$NON-NLS-1$ + public static final String NEXT_PROBLEM_ACTION= PREFIX + "next_problem_action"; //$NON-NLS-1$ + public static final String PREVIOUS_PROBLEM_ACTION= PREFIX + "previous_problem_action"; //$NON-NLS-1$ + public static final String JAVA_SELECT_MARKER_RULER_ACTION= PREFIX + "java_select_marker_ruler_action"; //$NON-NLS-1$ + public static final String GOTO_NEXT_ERROR_ACTION= PREFIX + "goto_next_error_action"; //$NON-NLS-1$ + public static final String GOTO_PREVIOUS_ERROR_ACTION= PREFIX + "goto_previous_error_action"; //$NON-NLS-1$ + public static final String SHOW_QUALIFIED_NAMES_ACTION= PREFIX + "show_qualified_names_action"; //$NON-NLS-1$ + public static final String SORT_BY_DEFINING_TYPE_ACTION= PREFIX + "sort_by_defining_type_action"; //$NON-NLS-1$ + public static final String FORMAT_ACTION= PREFIX + "format_action"; //$NON-NLS-1$ + public static final String COMMENT_ACTION= PREFIX + "comment_action"; //$NON-NLS-1$ + public static final String UNCOMMENT_ACTION= PREFIX + "uncomment_action"; //$NON-NLS-1$ + public static final String QUICK_FIX_ACTION= PREFIX + "quick_fix_action"; //$NON-NLS-1$ + public static final String CONTENT_ASSIST_ACTION= PREFIX + "content_assist_action"; //$NON-NLS-1$ + public static final String PARAMETER_HINTS_ACTION= PREFIX + "parameter_hints_action"; //$NON-NLS-1$ + public static final String SHOW_JAVADOC_ACTION= PREFIX + "show_javadoc_action"; //$NON-NLS-1$ + public static final String SHOW_OUTLINE_ACTION= PREFIX + "show_outline_action"; //$NON-NLS-1$ + public static final String OPEN_STRUCTURE_ACTION= PREFIX + "open_structure_action"; //$NON-NLS-1$ + + // Dialogs + public static final String MAINTYPE_SELECTION_DIALOG= PREFIX + "maintype_selection_dialog_context"; //$NON-NLS-1$ + public static final String OPEN_TYPE_DIALOG= PREFIX + "open_type_dialog_context"; //$NON-NLS-1$ + public static final String SOURCE_ATTACHMENT_DIALOG= PREFIX + "source_attachment_dialog_context"; //$NON-NLS-1$ + public static final String LIBRARIES_WORKBOOK_PAGE_ADVANCED_DIALOG= PREFIX + "advanced_dialog_context"; //$NON-NLS-1$ + public static final String CONFIRM_SAVE_MODIFIED_RESOURCES_DIALOG= PREFIX + "confirm_save_modified_resources_dialog_context"; //$NON-NLS-1$ + public static final String NEW_VARIABLE_ENTRY_DIALOG= PREFIX + "new_variable_dialog_context"; //$NON-NLS-1$ + public static final String NONNLS_DIALOG= PREFIX + "nonnls_dialog_context"; //$NON-NLS-1$ + public static final String MULTI_MAIN_TYPE_SELECTION_DIALOG= PREFIX + "multi_main_type_selection_dialog_context"; //$NON-NLS-1$ + public static final String MULTI_TYPE_SELECTION_DIALOG= PREFIX + "multi_type_selection_dialog_context"; //$NON-NLS-1$ + public static final String SUPER_INTERFACE_SELECTION_DIALOG= PREFIX + "super_interface_selection_dialog_context"; //$NON-NLS-1$ + public static final String OVERRIDE_TREE_SELECTION_DIALOG= PREFIX + "override_tree_selection_dialog_context"; //$NON-NLS-1$ + public static final String MOVE_DESTINATION_DIALOG= PREFIX + "move_destination_dialog_context"; //$NON-NLS-1$ + public static final String CHOOSE_VARIABLE_DIALOG= PREFIX + "choose_variable_dialog_context"; //$NON-NLS-1$ + public static final String EDIT_TEMPLATE_DIALOG= PREFIX + "edit_template_dialog_context"; //$NON-NLS-1$ + public static final String HISTORY_LIST_DIALOG= PREFIX + "history_list_dialog_context"; //$NON-NLS-1$ + public static final String IMPORT_ORGANIZE_INPUT_DIALOG= PREFIX + "import_organize_input_dialog_context"; //$NON-NLS-1$ + public static final String TODO_TASK_INPUT_DIALOG= PREFIX + "todo_task_input_dialog_context"; //$NON-NLS-1$ + public static final String JAVADOC_PROPERTY_DIALOG= PREFIX + "javadoc_property_dialog_context"; //$NON-NLS-1$ + public static final String NEW_CONTAINER_DIALOG= PREFIX + "new_container_dialog_context"; //$NON-NLS-1$ + public static final String EXCLUSION_PATTERN_DIALOG= PREFIX + "exclusion_pattern_dialog_context"; //$NON-NLS-1$ + public static final String OUTPUT_LOCATION_DIALOG= PREFIX + "output_location_dialog_context"; //$NON-NLS-1$ + public static final String VARIABLE_CREATION_DIALOG= PREFIX + "variable_creation_dialog_context"; //$NON-NLS-1$ + public static final String JAVA_SEARCH_PAGE= PREFIX + "java_search_page_context"; //$NON-NLS-1$ + public static final String NLS_SEARCH_PAGE= PREFIX + "nls_search_page_context"; //$NON-NLS-1$ + public static final String JAVA_EDITOR= PREFIX + "java_editor_context"; //$NON-NLS-1$ + public static final String GOTO_RESOURCE_DIALOG= PREFIX + "goto_resource_dialog"; //$NON-NLS-1$ + + public static final String COMPARE_DIALOG= PREFIX + "compare_dialog_context"; //$NON-NLS-1$ + public static final String ADD_ELEMENT_FROM_HISTORY_DIALOG= PREFIX + "add_element_from_history_dialog_context"; //$NON-NLS-1$ + public static final String COMPARE_ELEMENT_WITH_HISTORY_DIALOG= PREFIX + "compare_element_with_history_dialog_context"; //$NON-NLS-1$ + public static final String REPLACE_ELEMENT_WITH_HISTORY_DIALOG= PREFIX + "replace_element_with_history_dialog_context"; //$NON-NLS-1$ + + // view parts + public static final String TYPE_HIERARCHY_VIEW= PREFIX + "type_hierarchy_view_context"; //$NON-NLS-1$ + public static final String PACKAGES_VIEW= PREFIX + "package_view_context"; //$NON-NLS-1$ + public static final String PROJECTS_VIEW= PREFIX + "projects_view_context"; //$NON-NLS-1$ + public static final String PACKAGES_BROWSING_VIEW= PREFIX + "packages_browsing_view_context"; //$NON-NLS-1$ + public static final String TYPES_VIEW= PREFIX + "types_view_context"; //$NON-NLS-1$ + public static final String MEMBERS_VIEW= PREFIX + "members_view_context"; //$NON-NLS-1$ + + // Preference/Property pages + public static final String APPEARANCE_PREFERENCE_PAGE= PREFIX + "appearance_preference_page_context"; //$NON-NLS-1$ + public static final String SORT_ORDER_PREFERENCE_PAGE= PREFIX + "sort_order_preference_page_context"; //$NON-NLS-1$ + public static final String BUILD_PATH_PROPERTY_PAGE= PREFIX + "build_path_property_page_context"; //$NON-NLS-1$ + public static final String CP_VARIABLES_PREFERENCE_PAGE= PREFIX + "cp_variables_preference_page_context"; //$NON-NLS-1$ + public static final String CODEFORMATTER_PREFERENCE_PAGE= PREFIX + "codeformatter_preference_page_context"; //$NON-NLS-1$ + public static final String SOURCE_ATTACHMENT_PROPERTY_PAGE= PREFIX + "source_attachment_property_page_context"; //$NON-NLS-1$ + public static final String COMPILER_PROPERTY_PAGE= PREFIX + "compiler_property_page_context"; //$NON-NLS-1$ + public static final String TODOTASK_PROPERTY_PAGE= PREFIX + "tasktags_property_page_context"; //$NON-NLS-1$ + + public static final String CODE_MANIPULATION_PREFERENCE_PAGE= PREFIX + "code_manipulation_preference_context"; //$NON-NLS-1$ + public static final String ORGANIZE_IMPORTS_PREFERENCE_PAGE= PREFIX + "organizeimports_preference_page_context"; //$NON-NLS-1$ + public static final String JAVA_BASE_PREFERENCE_PAGE= PREFIX + "java_base_preference_page_context"; //$NON-NLS-1$ + public static final String REFACTORING_PREFERENCE_PAGE= PREFIX + "refactoring_preference_page_context"; //$NON-NLS-1$ + public static final String JAVA_EDITOR_PREFERENCE_PAGE= PREFIX + "java_editor_preference_page_context"; //$NON-NLS-1$ + public static final String COMPILER_PREFERENCE_PAGE= PREFIX + "compiler_preference_page_context"; //$NON-NLS-1$ + public static final String TODOTASK_PREFERENCE_PAGE= PREFIX + "tasktags_preference_page_context"; //$NON-NLS-1$ + + public static final String TEMPLATE_PREFERENCE_PAGE= PREFIX + "template_preference_page_context"; //$NON-NLS-1$ + public static final String JAVADOC_PREFERENCE_PAGE= PREFIX + "javadoc_preference_page_context"; //$NON-NLS-1$ + public static final String NEW_JAVA_PROJECT_PREFERENCE_PAGE= PREFIX + "new_java_project_preference_page_context"; //$NON-NLS-1$ + public static final String JAVADOC_CONFIGURATION_PROPERTY_PAGE= PREFIX + "new_java_project_preference_page_context"; //$NON-NLS-1$ + public static final String JAVA_ELEMENT_INFO_PAGE= PREFIX + "java_element_info_page_context"; //$NON-NLS-1$ + + // Wizard pages + public static final String NEW_JAVAPROJECT_WIZARD_PAGE= PREFIX + "new_javaproject_wizard_page_context"; //$NON-NLS-1$ + public static final String NEW_SNIPPET_WIZARD_PAGE= PREFIX + "new_snippet_wizard_page_context"; //$NON-NLS-1$ + public static final String NEW_PACKAGE_WIZARD_PAGE= PREFIX + "new_package_wizard_page_context"; //$NON-NLS-1$ + public static final String NEW_CLASS_WIZARD_PAGE= PREFIX + "new_class_wizard_page_context"; //$NON-NLS-1$ + public static final String NEW_INTERFACE_WIZARD_PAGE= PREFIX + "new_interface_wizard_page_context"; //$NON-NLS-1$ + public static final String NEW_PACKAGEROOT_WIZARD_PAGE= PREFIX + "new_packageroot_wizard_page_context"; //$NON-NLS-1$ + public static final String JARPACKAGER_WIZARD_PAGE= PREFIX + "jar_packager_wizard_page_context"; //$NON-NLS-1$ + public static final String JARMANIFEST_WIZARD_PAGE= PREFIX + "jar_manifest_wizard_page_context"; //$NON-NLS-1$ + public static final String JAROPTIONS_WIZARD_PAGE= PREFIX + "jar_options_wizard_page_context"; //$NON-NLS-1$ + public static final String JAVA_WORKING_SET_PAGE= PREFIX + "java_working_set_page_context"; //$NON-NLS-1$ + public static final String CLASSPATH_CONTAINER_DEFAULT_PAGE= PREFIX + "classpath_container_default_page_context"; //$NON-NLS-1$ + public static final String JAVADOC_STANDARD_PAGE= PREFIX + "javadoc_standard_page_context"; //$NON-NLS-1$ + public static final String JAVADOC_SPECIFICS_PAGE= PREFIX + "javadoc_specifics_page_context"; //$NON-NLS-1$ + public static final String JAVADOC_TREE_PAGE= PREFIX + "javadoc_tree_page_context"; //$NON-NLS-1$ + + // same help for all refactoring preview pages + public static final String REFACTORING_PREVIEW_WIZARD_PAGE= PREFIX + "refactoring_preview_wizard_page_context"; //$NON-NLS-1$ + + public static final String MOVE_CU_ERROR_WIZARD_PAGE= PREFIX + "move_cu_error_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_PARAMS_WIZARD_PAGE= PREFIX + "rename_params_wizard_page"; //$NON-NLS-1$ + public static final String RENAME_PARAMS_ERROR_WIZARD_PAGE= PREFIX + "rename_params_error_wizard_page"; //$NON-NLS-1$ + public static final String EXTERNALIZE_WIZARD_KEYVALUE_PAGE= PREFIX + "externalize_wizard_keyvalue_page_context"; //$NON-NLS-1$ + public static final String EXTERNALIZE_WIZARD_PROPERTIES_FILE_PAGE= PREFIX + "externalize_wizard_properties_file_page_context"; //$NON-NLS-1$ + public static final String EXTERNALIZE_ERROR_WIZARD_PAGE= PREFIX + "externalize_error_wizard_page_context"; //$NON-NLS-1$ + public static final String EXTRACT_INTERFACE_WIZARD_PAGE= PREFIX + "extract_interface_temp_page_context"; //$NON-NLS-1$ + public static final String EXTRACT_INTERFACE_ERROR_WIZARD_PAGE= PREFIX + "extract_interface_error_wizard_page_context"; //$NON-NLS-1$ + public static final String EXTRACT_METHOD_WIZARD_PAGE= PREFIX + "extract_method_wizard_page_context"; //$NON-NLS-1$ + public static final String EXTRACT_METHOD_ERROR_WIZARD_PAGE= PREFIX + "extract_method_error_wizard_page_context"; //$NON-NLS-1$ + public static final String EXTRACT_TEMP_WIZARD_PAGE= PREFIX + "extract_temp_page_context"; //$NON-NLS-1$ + public static final String EXTRACT_TEMP_ERROR_WIZARD_PAGE= PREFIX + "extract_temp_error_wizard_page_context"; //$NON-NLS-1$ + public static final String EXTRACT_CONSTANT_WIZARD_PAGE= PREFIX + "extract_constant_page_context"; //$NON-NLS-1$ + public static final String EXTRACT_CONSTANT_ERROR_WIZARD_PAGE= PREFIX + "extract_constant_error_wizard_page_context"; //$NON-NLS-1$ + public static final String PROMOTE_TEMP_TO_FIELD_WIZARD_PAGE= PREFIX + "promote_temp_to_field_page_context"; //$NON-NLS-1$ + public static final String PROMOTE_TEMP_TO_FIELD_ERROR_WIZARD_PAGE= PREFIX + "promote_temp_to_field_error_wizard_page_context"; //$NON-NLS-1$ + public static final String CONVERT_ANONYMOUS_TO_NESTED_WIZARD_PAGE= PREFIX + "convert_anonymous_to_nested_page_context"; //$NON-NLS-1$ + public static final String CONVERT_ANONYMOUS_TO_NESTED_ERROR_WIZARD_PAGE= PREFIX + "convert_anonymous_to_nested_error_wizard_page_context"; //$NON-NLS-1$ + public static final String MODIFY_PARAMETERS_WIZARD_PAGE= PREFIX + "modify_parameters_wizard_page_context"; //$NON-NLS-1$ + public static final String MODIFY_PARAMETERS_ERROR_WIZARD_PAGE= PREFIX + "modify_parameters_error_wizard_page_context"; //$NON-NLS-1$ + public static final String MOVE_MEMBERS_WIZARD_PAGE= PREFIX + "move_members_wizard_page_context"; //$NON-NLS-1$ + public static final String MOVE_MEMBERS_ERROR_WIZARD_PAGE= PREFIX + "move_members_error_error_wizard_page_context"; //$NON-NLS-1$ + public static final String MOVE_INNER_TO_TOP_WIZARD_PAGE= PREFIX + "move_inner_to_top_wizard_page_context"; //$NON-NLS-1$ + public static final String MOVE_INNER_TO_TOP_ERROR_WIZARD_PAGE= PREFIX + "move_inner_to_top_error_error_wizard_page_context"; //$NON-NLS-1$ + public static final String PULL_UP_WIZARD_PAGE= PREFIX + "pull_up_wizard_page_context"; //$NON-NLS-1$ + public static final String PULL_UP_ERROR_WIZARD_PAGE= PREFIX + "pull_up_error_error_wizard_page_context"; //$NON-NLS-1$ + public static final String PUSH_DOWN_WIZARD_PAGE= PREFIX + "push_down_wizard_page_context"; //$NON-NLS-1$ + public static final String PUSH_DOWN_ERROR_WIZARD_PAGE= PREFIX + "push_down_error_error_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_PACKAGE_WIZARD_PAGE= PREFIX + "rename_package_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_PACKAGE_ERROR_WIZARD_PAGE= PREFIX + "rename_package_error_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_TEMP_WIZARD_PAGE= PREFIX + "rename_local_variable_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_TEMP_ERROR_WIZARD_PAGE= PREFIX + "rename_local_variable_error_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_CU_WIZARD_PAGE= PREFIX + "rename_cu_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_CU_ERROR_WIZARD_PAGE= PREFIX + "rename_cu_error_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_METHOD_WIZARD_PAGE= PREFIX + "rename_method_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_METHOD_ERROR_WIZARD_PAGE= PREFIX + "rename_method_error_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_TYPE_WIZARD_PAGE= PREFIX + "rename_type_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_TYPE_ERROR_WIZARD_PAGE= PREFIX + "rename_type_error_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_FIELD_WIZARD_PAGE= PREFIX + "rename_field_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_FIELD_ERROR_WIZARD_PAGE= PREFIX + "rename_field_error_wizard_page_context"; //$NON-NLS-1$ + public static final String SEF_WIZARD_PAGE= PREFIX + "self_encapsulate_field_wizard_page_context"; //$NON-NLS-1$ + public static final String SEF_ERROR_WIZARD_PAGE= PREFIX + "self_encapsulate_field_error_wizard_page_context"; //$NON-NLS-1$ + public static final String USE_SUPERTYPE_WIZARD_PAGE= PREFIX + "use_supertype_wizard_page_context"; //$NON-NLS-1$ + public static final String USE_SUPERTYPE_ERROR_WIZARD_PAGE= PREFIX + "use_supertype_error_wizard_page_context"; //$NON-NLS-1$ + public static final String INLINE_METHOD_WIZARD_PAGE= PREFIX + "inline_method_wizard_page_context"; //$NON-NLS-1$ + public static final String INLINE_METHOD_ERROR_WIZARD_PAGE= PREFIX + "inline_method_error_wizard_page_context"; //$NON-NLS-1$ + public static final String INLINE_CONSTANT_WIZARD_PAGE= PREFIX + "inline_constant_wizard_page_context"; //$NON-NLS-1$ + public static final String INLINE_CONSTANT_ERROR_WIZARD_PAGE= PREFIX + "inline_constant_error_wizard_page_context"; //$NON-NLS-1$ + public static final String INLINE_TEMP_ERROR_WIZARD_PAGE= PREFIX + "inline_temp_error_wizard_page_context"; //$NON-NLS-1$ + + // reused ui-blocks + public static final String BUILD_PATH_BLOCK= PREFIX + "build_paths_context"; //$NON-NLS-1$ + public static final String SOURCE_ATTACHMENT_BLOCK= PREFIX + "source_attachment_context"; //$NON-NLS-1$ + + // Custom Filters + public static final String CUSTOM_FILTERS_DIALOG= PREFIX + "open_custom_filters_dialog_context"; //$NON-NLS-1$ +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/IJavaStatusConstants.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/IJavaStatusConstants.java new file mode 100644 index 0000000..157fff5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/IJavaStatusConstants.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui; + +/** + * Defines status codes relevant to the Java UI plug-in. When a + * Core exception is thrown, it contain a status object describing + * the cause of the exception. The status objects originating from the + * Java UI plug-in use the codes defined in this interface. + */ +public interface IJavaStatusConstants { + + // Java UI status constants start at 10000 to make sure that we don't + // collide with resource and java model constants. + + public static final int INTERNAL_ERROR= 10001; + + /** + * Status constant indicating that an exception occurred on + * storing or loading templates. + */ + public static final int TEMPLATE_IO_EXCEPTION = 10002; + + /** + * Status constant indicating that an validateEdit call has changed the + * content of a file on disk. + */ + public static final int VALIDATE_EDIT_CHANGED_CONTENT= 10003; + + /** + * Status constant indicating that a ChangeAbortException has been + * caught. + */ + public static final int CHANGE_ABORTED= 10004; + + /** + * Status constant indicating that an exception occurred while + * parsing template file. + */ + public static final int TEMPLATE_PARSE_EXCEPTION = 10005; + } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaPluginImages_DeleteIt.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaPluginImages_DeleteIt.java new file mode 100644 index 0000000..04543bb --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaPluginImages_DeleteIt.java @@ -0,0 +1,424 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; + +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; + + +/** + * Bundle of most images used by the Java plugin. + */ +public class JavaPluginImages_DeleteIt { + + private static final String NAME_PREFIX= "net.sourceforge.phpdt.internal.ui."; //$NON-NLS-1$ + private static final int NAME_PREFIX_LENGTH= NAME_PREFIX.length(); + + private static URL fgIconBaseURL= null; + + // Determine display depth. If depth > 4 then we use high color images. Otherwise low color + // images are used + static { +// String pathSuffix= "icons/full/"; //$NON-NLS-1$ + String pathSuffix= "icons/"; //$NON-NLS-1$ + try { + fgIconBaseURL= new URL(PHPeclipsePlugin.getDefault().getDescriptor().getInstallURL(), pathSuffix); + } catch (MalformedURLException e) { + // do nothing + } + } + + // The plugin registry + private static ImageRegistry fgImageRegistry= null; + private static HashMap fgAvoidSWTErrorMap= null; + + /* + * Available cached Images in the Java plugin image registry. + */ + public static final String IMG_MISC_PUBLIC= NAME_PREFIX + "methpub_obj.gif"; //$NON-NLS-1$ + public static final String IMG_MISC_PROTECTED= NAME_PREFIX + "methpro_obj.gif"; //$NON-NLS-1$ + public static final String IMG_MISC_PRIVATE= NAME_PREFIX + "methpri_obj.gif"; //$NON-NLS-1$ + public static final String IMG_MISC_DEFAULT= NAME_PREFIX + "methdef_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_FIELD_PUBLIC= NAME_PREFIX + "field_public_obj.gif"; //$NON-NLS-1$ + public static final String IMG_FIELD_PROTECTED= NAME_PREFIX + "field_protected_obj.gif"; //$NON-NLS-1$ + public static final String IMG_FIELD_PRIVATE= NAME_PREFIX + "field_private_obj.gif"; //$NON-NLS-1$ + public static final String IMG_FIELD_DEFAULT= NAME_PREFIX + "field_default_obj.gif"; //$NON-NLS-1$ + + + public static final String IMG_OBJS_GHOST= NAME_PREFIX + "ghost.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_SEARCH_TSK= NAME_PREFIX + "search_tsk.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_PACKDECL= NAME_PREFIX + "packd_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_IMPDECL= NAME_PREFIX + "imp_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_IMPCONT= NAME_PREFIX + "impc_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_JSEARCH= NAME_PREFIX + "jsearch_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_SEARCH_DECL= NAME_PREFIX + "search_decl_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_SEARCH_REF= NAME_PREFIX + "search_ref_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CLASS= NAME_PREFIX + "class_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CLASSALT= NAME_PREFIX + "classfo_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CLASS_DEFAULT= NAME_PREFIX + "class_default_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_INTERFACE= NAME_PREFIX + "int_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_INTERFACEALT= NAME_PREFIX + "intf_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_INTERFACE_DEFAULT= NAME_PREFIX + "int_default_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CUNIT= NAME_PREFIX + "jcu_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CUNIT_RESOURCE= NAME_PREFIX + "jcu_resource_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CFILE= NAME_PREFIX + "classf_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CFILECLASS= NAME_PREFIX + "class_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CFILEINT= NAME_PREFIX + "int_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_LOGICAL_PACKAGE= NAME_PREFIX + "logical_package_obj.gif";//$NON-NLS-1$ + public static final String IMG_OJS_EMPTY_LOGICAL_PACKAGE= NAME_PREFIX + "empty_logical_package_obj.gif";//$NON-NLS-1$ + public static final String IMG_OBJS_PACKAGE= NAME_PREFIX + "package_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_EMPTY_PACK_RESOURCE= NAME_PREFIX + "empty_pack_fldr_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_EMPTY_PACKAGE= NAME_PREFIX + "empty_pack_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_PACKFRAG_ROOT= NAME_PREFIX + "packagefolder_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_MISSING_PACKFRAG_ROOT= NAME_PREFIX + "packagefolder_nonexist_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_MISSING_JAR= NAME_PREFIX + "jar_nonexist_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_JAR= NAME_PREFIX + "jar_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_EXTJAR= NAME_PREFIX + "jar_l_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_JAR_WSRC= NAME_PREFIX + "jar_src_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_EXTJAR_WSRC= NAME_PREFIX + "jar_lsrc_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_ENV_VAR= NAME_PREFIX + "envvar_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_MISSING_ENV_VAR= NAME_PREFIX + "envvar_nonexist_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_JAVA_MODEL= NAME_PREFIX + "java_model_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_UNKNOWN= NAME_PREFIX + "unknown_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_LIBRARY= NAME_PREFIX + "library_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_JAVADOCTAG= NAME_PREFIX + "jdoc_tag_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_HTMLTAG= NAME_PREFIX + "html_tag_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_TEMPLATE= NAME_PREFIX + "template_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_EXCEPTION= NAME_PREFIX + "jexception_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_ERROR= NAME_PREFIX + "jrtexception_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_BREAKPOINT_INSTALLED= NAME_PREFIX + "brkpi_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_FIXABLE_PROBLEM= NAME_PREFIX + "quickfix_warning_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_FIXABLE_ERROR= NAME_PREFIX + "quickfix_error_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_SNIPPET_EVALUATING= NAME_PREFIX + "jsbook_run_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_REFACTORING_FATAL= NAME_PREFIX + "fatalerror_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_REFACTORING_ERROR= NAME_PREFIX + "error_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_REFACTORING_WARNING= NAME_PREFIX + "warning_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_REFACTORING_INFO= NAME_PREFIX + "info_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_NLS_TRANSLATE= NAME_PREFIX + "translate.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_NLS_NEVER_TRANSLATE= NAME_PREFIX + "never_translate.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_NLS_SKIP= NAME_PREFIX + "skip.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_SEARCH_READACCESS= NAME_PREFIX + "occ_read.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_SEARCH_WRITEACCESS= NAME_PREFIX + "occ_write.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_SEARCH_OCCURRENCE= NAME_PREFIX + "occ_match.gif"; //$NON-NLS-1$ + /* + * Set of predefined Image Descriptors. + */ + private static final String T_OBJ= "obj16"; //$NON-NLS-1$ + private static final String T_OVR= "ovr16"; //$NON-NLS-1$ + private static final String T_WIZBAN= "wizban"; //$NON-NLS-1$ + private static final String T_CLCL= "clcl16"; //$NON-NLS-1$ + private static final String T_DLCL= "dlcl16"; //$NON-NLS-1$ + private static final String T_CTOOL= "ctool16"; //$NON-NLS-1$ + private static final String T_CVIEW= "cview16"; //$NON-NLS-1$ + + public static final ImageDescriptor DESC_VIEW_ERRORWARNING_TAB= create(T_CVIEW, "errorwarning_tab.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_VIEW_CLASSFILEGENERATION_TAB= create(T_CVIEW, "classfilegeneration_tab.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_VIEW_JDKCOMPLIANCE_TAB= create(T_CVIEW, "jdkcompliance_tab.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_CLCL_FILTER= create(T_CLCL, "filter_ps.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_CLCL_CODE_ASSIST= create(T_CLCL, "metharg_obj.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_DLCL_CODE_ASSIST= create(T_DLCL, "metharg_obj.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_MISC_PUBLIC= createManaged(T_OBJ, IMG_MISC_PUBLIC); + public static final ImageDescriptor DESC_MISC_PROTECTED= createManaged(T_OBJ, IMG_MISC_PROTECTED); + public static final ImageDescriptor DESC_MISC_PRIVATE= createManaged(T_OBJ, IMG_MISC_PRIVATE); + public static final ImageDescriptor DESC_MISC_DEFAULT= createManaged(T_OBJ, IMG_MISC_DEFAULT); + + public static final ImageDescriptor DESC_FIELD_PUBLIC= createManaged(T_OBJ, IMG_FIELD_PUBLIC); //$NON-NLS-1$ + public static final ImageDescriptor DESC_FIELD_PROTECTED= createManaged(T_OBJ, IMG_FIELD_PROTECTED); //$NON-NLS-1$ + public static final ImageDescriptor DESC_FIELD_PRIVATE= createManaged(T_OBJ, IMG_FIELD_PRIVATE); //$NON-NLS-1$ + public static final ImageDescriptor DESC_FIELD_DEFAULT= createManaged(T_OBJ, IMG_FIELD_DEFAULT); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_MENU_SHIFT_RIGHT= create(T_CTOOL, "shift_r_edit.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_MENU_SHIFT_LEFT= create(T_CTOOL, "shift_l_edit.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_OBJS_GHOST= createManaged(T_OBJ, IMG_OBJS_GHOST); + public static final ImageDescriptor DESC_OBJS_PACKDECL= createManaged(T_OBJ, IMG_OBJS_PACKDECL); + public static final ImageDescriptor DESC_OBJS_IMPDECL= createManaged(T_OBJ, IMG_OBJS_IMPDECL); + public static final ImageDescriptor DESC_OBJS_IMPCONT= createManaged(T_OBJ, IMG_OBJS_IMPCONT); + public static final ImageDescriptor DESC_OBJS_JSEARCH= createManaged(T_OBJ, IMG_OBJS_JSEARCH); + public static final ImageDescriptor DESC_OBJS_SEARCH_DECL= createManaged(T_OBJ, IMG_OBJS_SEARCH_DECL); + public static final ImageDescriptor DESC_OBJS_SEARCH_REF= createManaged(T_OBJ, IMG_OBJS_SEARCH_REF); + public static final ImageDescriptor DESC_OBJS_CUNIT= createManaged(T_OBJ, IMG_OBJS_CUNIT); + public static final ImageDescriptor DESC_OBJS_CUNIT_RESOURCE= createManaged(T_OBJ, IMG_OBJS_CUNIT_RESOURCE); + public static final ImageDescriptor DESC_OBJS_CFILE= createManaged(T_OBJ, IMG_OBJS_CFILE); + public static final ImageDescriptor DESC_OBJS_CFILECLASS= createManaged(T_OBJ, IMG_OBJS_CFILECLASS); + public static final ImageDescriptor DESC_OBJS_CFILEINT= createManaged(T_OBJ, IMG_OBJS_CFILEINT); + public static final ImageDescriptor DESC_OBJS_PACKAGE= createManaged(T_OBJ, IMG_OBJS_PACKAGE); + public static final ImageDescriptor DESC_OBJS_EMPTY_LOGICAL_PACKAGE= createManaged(T_OBJ, IMG_OJS_EMPTY_LOGICAL_PACKAGE); + public static final ImageDescriptor DESC_OBJS_LOGICAL_PACKAGE= createManaged(T_OBJ, IMG_OBJS_LOGICAL_PACKAGE); + public static final ImageDescriptor DESC_OBJS_EMPTY_PACKAGE_RESOURCES= createManaged(T_OBJ, IMG_OBJS_EMPTY_PACK_RESOURCE); + public static final ImageDescriptor DESC_OBJS_EMPTY_PACKAGE= createManaged(T_OBJ, IMG_OBJS_EMPTY_PACKAGE); + public static final ImageDescriptor DESC_OBJS_PACKFRAG_ROOT= createManaged(T_OBJ, IMG_OBJS_PACKFRAG_ROOT); + public static final ImageDescriptor DESC_OBJS_MISSING_PACKFRAG_ROOT= createManaged(T_OBJ, IMG_OBJS_MISSING_PACKFRAG_ROOT); + public static final ImageDescriptor DESC_OBJS_JAVA_MODEL= createManaged(T_OBJ, IMG_OBJS_JAVA_MODEL); + + public static final ImageDescriptor DESC_OBJS_CLASS= createManaged(T_OBJ, IMG_OBJS_CLASS); + public static final ImageDescriptor DESC_OBJS_CLASS_DEFAULT= createManaged(T_OBJ, IMG_OBJS_CLASS_DEFAULT); + + public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PUBLIC= create(T_OBJ, "innerclass_public_obj.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_INNER_CLASS_DEFAULT= create(T_OBJ, "innerclass_default_obj.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PROTECTED= create(T_OBJ, "innerclass_protected_obj.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PRIVATE= create(T_OBJ, "innerclass_private_obj.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_OBJS_CLASSALT= createManaged(T_OBJ, IMG_OBJS_CLASSALT); + + public static final ImageDescriptor DESC_OBJS_INTERFACE= createManaged(T_OBJ, IMG_OBJS_INTERFACE); + public static final ImageDescriptor DESC_OBJS_INTERFACE_DEFAULT= createManaged(T_OBJ, IMG_OBJS_INTERFACE_DEFAULT); + + public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PUBLIC= create(T_OBJ, "innerinterface_public_obj.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_DEFAULT= create(T_OBJ, "innerinterface_default_obj.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PROTECTED= create(T_OBJ, "innerinterface_protected_obj.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PRIVATE= create(T_OBJ, "innerinterface_private_obj.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_OBJS_INTERFACEALT= createManaged(T_OBJ, IMG_OBJS_INTERFACEALT); + + public static final ImageDescriptor DESC_OBJS_JAR= createManaged(T_OBJ, IMG_OBJS_JAR); + public static final ImageDescriptor DESC_OBJS_MISSING_JAR= createManaged(T_OBJ, IMG_OBJS_MISSING_JAR); + public static final ImageDescriptor DESC_OBJS_EXTJAR= createManaged(T_OBJ, IMG_OBJS_EXTJAR); + public static final ImageDescriptor DESC_OBJS_JAR_WSRC= createManaged(T_OBJ, IMG_OBJS_JAR_WSRC); + public static final ImageDescriptor DESC_OBJS_EXTJAR_WSRC= createManaged(T_OBJ, IMG_OBJS_EXTJAR_WSRC); + public static final ImageDescriptor DESC_OBJS_ENV_VAR= createManaged(T_OBJ, IMG_OBJS_ENV_VAR); + public static final ImageDescriptor DESC_OBJS_MISSING_ENV_VAR= createManaged(T_OBJ, IMG_OBJS_MISSING_ENV_VAR); + + public static final ImageDescriptor DESC_OBJS_LIBRARY= createManaged(T_OBJ, IMG_OBJS_LIBRARY); + + public static final ImageDescriptor DESC_OBJS_JAVADOCTAG= createManaged(T_OBJ, IMG_OBJS_JAVADOCTAG); + public static final ImageDescriptor DESC_OBJS_HTMLTAG= createManaged(T_OBJ, IMG_OBJS_HTMLTAG); + + public static final ImageDescriptor DESC_OBJS_TEMPLATE= createManaged(T_OBJ, IMG_OBJS_TEMPLATE); + + public static final ImageDescriptor DESC_OBJS_EXCEPTION= createManaged(T_OBJ, IMG_OBJS_EXCEPTION); + public static final ImageDescriptor DESC_OBJS_BREAKPOINT_INSTALLED= createManaged(T_OBJ, IMG_OBJS_BREAKPOINT_INSTALLED); + public static final ImageDescriptor DESC_OBJS_ERROR= createManaged(T_OBJ, IMG_OBJS_ERROR); + public static final ImageDescriptor DESC_OBJS_FIXABLE_PROBLEM= createManaged(T_OBJ, IMG_OBJS_FIXABLE_PROBLEM); + public static final ImageDescriptor DESC_OBJS_FIXABLE_ERROR= createManaged(T_OBJ, IMG_OBJS_FIXABLE_ERROR); + + public static final ImageDescriptor DESC_OBJS_SNIPPET_EVALUATING= createManaged(T_OBJ, IMG_OBJS_SNIPPET_EVALUATING); + + public static final ImageDescriptor DESC_OBJS_DEFAULT_CHANGE= create(T_OBJ, "change.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_COMPOSITE_CHANGE= create(T_OBJ, "composite_change.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_CU_CHANGE= create(T_OBJ, "cu_change.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_FILE_CHANGE= create(T_OBJ, "file_change.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_TEXT_EDIT= create(T_OBJ, "text_edit.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_OBJS_EXCLUSION_FILTER_ATTRIB= create(T_OBJ, "exclusion_filter_attrib.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_OUTPUT_FOLDER_ATTRIB= create(T_OBJ, "output_folder_attrib.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_SOURCE_ATTACH_ATTRIB= create(T_OBJ, "source_attach_attrib.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_JAVADOC_LOCATION_ATTRIB= create(T_OBJ, "javadoc_location_attrib.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_OBJS_REFACTORING_FATAL= createManaged(T_OBJ, IMG_OBJS_REFACTORING_FATAL); + public static final ImageDescriptor DESC_OBJS_REFACTORING_ERROR= createManaged(T_OBJ, IMG_OBJS_REFACTORING_ERROR); + public static final ImageDescriptor DESC_OBJS_REFACTORING_WARNING= createManaged(T_OBJ, IMG_OBJS_REFACTORING_WARNING); + public static final ImageDescriptor DESC_OBJS_REFACTORING_INFO= createManaged(T_OBJ, IMG_OBJS_REFACTORING_INFO); + + public static final ImageDescriptor DESC_OBJS_NLS_TRANSLATE= createManaged(T_OBJ, IMG_OBJS_NLS_TRANSLATE); + public static final ImageDescriptor DESC_OBJS_NLS_NEVER_TRANSLATE= createManaged(T_OBJ, IMG_OBJS_NLS_NEVER_TRANSLATE); + public static final ImageDescriptor DESC_OBJS_NLS_SKIP= createManaged(T_OBJ, IMG_OBJS_NLS_SKIP); + + public static final ImageDescriptor DESC_OBJS_UNKNOWN= createManaged(T_OBJ, IMG_OBJS_UNKNOWN); + + public static final ImageDescriptor DESC_OBJS_SEARCH_READACCESS= createManaged(T_OBJ, IMG_OBJS_SEARCH_READACCESS); + public static final ImageDescriptor DESC_OBJS_SEARCH_WRITEACCESS= createManaged(T_OBJ, IMG_OBJS_SEARCH_WRITEACCESS); + public static final ImageDescriptor DESC_OBJS_SEARCH_OCCURRENCE= createManaged(T_OBJ, IMG_OBJS_SEARCH_OCCURRENCE); + + public static final ImageDescriptor DESC_OBJS_LOCAL_VARIABLE= create(T_OBJ, "localvariable_obj.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_OVR_STATIC= create(T_OVR, "static_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_FINAL= create(T_OVR, "final_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_ABSTRACT= create(T_OVR, "abstract_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_SYNCH= create(T_OVR, "synch_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_RUN= create(T_OVR, "run_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_WARNING= create(T_OVR, "warning_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_ERROR= create(T_OVR, "error_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_OVERRIDES= create(T_OVR, "over_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_IMPLEMENTS= create(T_OVR, "implm_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_CONSTRUCTOR= create(T_OVR, "constr_ovr.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_FOCUS= create(T_OVR, "focus_ovr.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_WIZBAN_NEWCLASS= create(T_WIZBAN, "newclass_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_NEWFIELD= create(T_WIZBAN, "newfield_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_NEWINT= create(T_WIZBAN, "newint_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_NEWJPRJ= create(T_WIZBAN, "newjprj_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_NEWSRCFOLDR= create(T_WIZBAN, "newsrcfldr_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_NEWMETH= create(T_WIZBAN, "newmeth_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_NEWPACK= create(T_WIZBAN, "newpack_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_NEWSCRAPPAGE= create(T_WIZBAN, "newsbook_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_JAVA_LAUNCH= create(T_WIZBAN, "java_app_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_JAVA_ATTACH= create(T_WIZBAN, "java_attach_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR= create(T_WIZBAN, "refactor_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_FIELD= create(T_WIZBAN, "fieldrefact_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_METHOD= create(T_WIZBAN, "methrefact_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_TYPE= create(T_WIZBAN, "typerefact_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_PACKAGE= create(T_WIZBAN, "packrefact_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_CODE= create(T_WIZBAN, "coderefact_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_CU= create(T_WIZBAN, "compunitrefact_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_PULL_UP= create(T_WIZBAN, "pullup_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_JAR_PACKAGER= create(T_WIZBAN, "jar_pack_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_JAVA_WORKINGSET= create(T_WIZBAN, "java_workingset_wiz.gif");//$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_EXPORT_JAVADOC= create(T_WIZBAN, "export_javadoc_wiz.gif");//$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_EXTERNALIZE_STRINGS= create(T_WIZBAN, "extstr_wiz.gif");//$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_ADD_LIBRARY= create(T_WIZBAN, "addlibrary_wiz.gif");//$NON-NLS-1$ + + + public static final ImageDescriptor DESC_TOOL_DISPLAYSNIPPET= create(T_CTOOL, "disp_sbook.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_RUNSNIPPET= create(T_CTOOL, "run_sbook.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_INSPSNIPPET= create(T_CTOOL, "insp_sbook.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_PACKSNIPPET= create(T_CTOOL, "pack_sbook.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_TERMSNIPPET= create(T_CTOOL, "term_sbook.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_SHOW_EMPTY_PKG= create(T_CTOOL, "show_empty_pkg.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_SHOW_SEGMENTS= create(T_CTOOL, "segment_edit.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_GOTO_NEXT_ERROR= create(T_CTOOL, "next_error_nav.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_GOTO_PREV_ERROR= create(T_CTOOL, "prev_error_nav.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_TOOL_OPENTYPE= create(T_CTOOL, "opentype.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_NEWPROJECT= create(T_CTOOL, "newjprj_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_NEWPACKAGE= create(T_CTOOL, "newpack_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_NEWCLASS= create(T_CTOOL, "newclass_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_NEWINTERFACE= create(T_CTOOL, "newint_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_NEWSNIPPET= create(T_CTOOL, "newsbook_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_NEWPACKROOT= create(T_CTOOL, "newpackfolder_wiz.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_TOOL_CLASSPATH_ORDER= create(T_OBJ, "cp_order_obj.gif"); //$NON-NLS-1$ + + // Keys for correction proposal. We have to put the image into the registry since "code assist" doesn't + // have a life cycle. So no change to dispose icons. + + public static final String IMG_CORRECTION_CHANGE= NAME_PREFIX + "correction_change.gif"; //$NON-NLS-1$ + public static final String IMG_CORRECTION_MOVE= NAME_PREFIX + "correction_move.gif"; //$NON-NLS-1$ + public static final String IMG_CORRECTION_RENAME= NAME_PREFIX + "correction_rename.gif"; //$NON-NLS-1$ + public static final String IMG_CORRECTION_DELETE_IMPORT= NAME_PREFIX + "correction_delete_import.gif"; //$NON-NLS-1$ + public static final String IMG_CORRECTION_LOCAL= NAME_PREFIX + "localvariable_obj.gif"; //$NON-NLS-1$ + static { + createManaged(T_OBJ, IMG_CORRECTION_CHANGE); + createManaged(T_OBJ, IMG_CORRECTION_MOVE); + createManaged(T_OBJ, IMG_CORRECTION_RENAME); + createManaged(T_OBJ, IMG_CORRECTION_DELETE_IMPORT); + createManaged(T_OBJ, IMG_CORRECTION_LOCAL); + } + + /** + * Returns the image managed under the given key in this registry. + * + * @param key the image's key + * @return the image managed under the given key + */ + public static Image get(String key) { + return getImageRegistry().get(key); + } + + /** + * Sets the three image descriptors for enabled, disabled, and hovered to an action. The actions + * are retrieved from the *tool16 folders. + */ + public static void setToolImageDescriptors(IAction action, String iconName) { + setImageDescriptors(action, "tool16", iconName); //$NON-NLS-1$ + } + + /** + * Sets the three image descriptors for enabled, disabled, and hovered to an action. The actions + * are retrieved from the *lcl16 folders. + */ + public static void setLocalImageDescriptors(IAction action, String iconName) { + setImageDescriptors(action, "lcl16", iconName); //$NON-NLS-1$ + } + + /* + * Helper method to access the image registry from the JavaPlugin class. + */ + /* package */ static ImageRegistry getImageRegistry() { + if (fgImageRegistry == null) { + fgImageRegistry= new ImageRegistry(); + for (Iterator iter= fgAvoidSWTErrorMap.keySet().iterator(); iter.hasNext();) { + String key= (String) iter.next(); + fgImageRegistry.put(key, (ImageDescriptor) fgAvoidSWTErrorMap.get(key)); + } + fgAvoidSWTErrorMap= null; + } + return fgImageRegistry; + } + + //---- Helper methods to access icons on the file system -------------------------------------- + + private static void setImageDescriptors(IAction action, String type, String relPath) { + + try { + ImageDescriptor id= ImageDescriptor.createFromURL(makeIconFileURL("d" + type, relPath)); //$NON-NLS-1$ + if (id != null) + action.setDisabledImageDescriptor(id); + } catch (MalformedURLException e) { + } + + try { + ImageDescriptor id= ImageDescriptor.createFromURL(makeIconFileURL("c" + type, relPath)); //$NON-NLS-1$ + if (id != null) + action.setHoverImageDescriptor(id); + } catch (MalformedURLException e) { + } + + action.setImageDescriptor(create("e" + type, relPath)); //$NON-NLS-1$ + } + + private static ImageDescriptor createManaged(String prefix, String name) { + try { + ImageDescriptor result= ImageDescriptor.createFromURL(makeIconFileURL(prefix, name.substring(NAME_PREFIX_LENGTH))); + if (fgAvoidSWTErrorMap == null) { + fgAvoidSWTErrorMap= new HashMap(); + } + fgAvoidSWTErrorMap.put(name, result); + if (fgImageRegistry != null) { + PHPeclipsePlugin.log(IStatus.ERROR, "Image registry already defined"); //$NON-NLS-1$ + } + return result; + } catch (MalformedURLException e) { + return ImageDescriptor.getMissingImageDescriptor(); + } + } + + private static ImageDescriptor create(String prefix, String name) { + try { + return ImageDescriptor.createFromURL(makeIconFileURL(prefix, name)); + } catch (MalformedURLException e) { + return ImageDescriptor.getMissingImageDescriptor(); + } + } + + private static URL makeIconFileURL(String prefix, String name) throws MalformedURLException { + if (fgIconBaseURL == null) + throw new MalformedURLException(); + + StringBuffer buffer= new StringBuffer(prefix); + buffer.append('/'); + buffer.append(name); + return new URL(fgIconBaseURL, buffer.toString()); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/PHPUIStatus.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/PHPUIStatus.java index 41a9e2c..91e1537 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/PHPUIStatus.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/PHPUIStatus.java @@ -10,20 +10,35 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; /** - * Convenience class for error exceptions thrown inside PHPUI plugin. + * Convenience class for error exceptions thrown inside PHPeclipse plugin. */ public class PHPUIStatus extends Status { - public PHPUIStatus(int code, String message, Throwable throwable) { - super(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), code, message, throwable); - } + public PHPUIStatus(int code) { + this(code, ""); //$NON-NLS-1$ + } - public PHPUIStatus(int code, String message) { - this(code, message, null); - } + private PHPUIStatus(int severity, int code, String message, Throwable throwable) { + super(severity, PHPeclipsePlugin.getPluginId(), code, message, throwable); + } - public PHPUIStatus(int code) { - this(code, ""); //$NON-NLS-1$ - } -} + public PHPUIStatus(int code, String message) { + this(code, message, null); + } + + public PHPUIStatus(int code, String message, Throwable throwable) { + super(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), code, message, throwable); + } + + public static IStatus createError(int code, String message, Throwable throwable) { + return new PHPUIStatus(IStatus.ERROR, code, message, throwable); + } + public static IStatus createInfo(int code, String message, Throwable throwable) { + return new PHPUIStatus(IStatus.INFO, code, message, throwable); + } + + public static IStatus createWarning(int code, String message, Throwable throwable) { + return new PHPUIStatus(IStatus.WARNING, code, message, throwable); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/PHPUiImages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/PHPUiImages.java index f0d6b23..abdb1f1 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/PHPUiImages.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/PHPUiImages.java @@ -39,29 +39,21 @@ public class PHPUiImages { protected static final String OVR_PREFIX = "ovr16"; protected static final String CTOOL_PREFIX = "ctool16"; - public static final String IMG_OBJS_GHOST= NAME_PREFIX + "ghost.gif"; public static final String IMG_CLASS = NAME_PREFIX + "class_obj.gif"; public static final String IMG_DEFINE = NAME_PREFIX + "define_obj.gif"; public static final String IMG_BUILTIN = NAME_PREFIX + "builtin_obj.gif"; public static final String IMG_FUN = NAME_PREFIX + "fun_obj.gif"; public static final String IMG_INC = NAME_PREFIX + "impc_obj.gif"; public static final String IMG_VAR = NAME_PREFIX + "var_obj.gif"; - public static final String IMG_OBJS_ERROR = NAME_PREFIX + "error_obj.gif"; public static final String IMG_OBJS_WARNING = NAME_PREFIX + "warning_obj.gif"; public static final String IMG_OBJS_INFO = NAME_PREFIX + "info_obj.gif"; - public static final String IMG_OBJS_INTERFACE= NAME_PREFIX + "int_obj.gif"; //$NON-NLS-1$ public static final String IMG_CTOOLS_PHP_PAGE = NAME_PREFIX + "php_page.gif"; public static final String IMG_CTOOLS_PHP = NAME_PREFIX + "php.gif"; - public static final String IMG_OBJS_TEMPLATE = - NAME_PREFIX + "template_obj.gif"; - public static final String IMG_CLEAR = NAME_PREFIX + "clear.gif"; - - public static final ImageDescriptor DESC_OBJS_GHOST= createManaged(OBJ_PREFIX, IMG_OBJS_GHOST); - + public static final ImageDescriptor DESC_CLASS = createManaged(OBJ_PREFIX, IMG_CLASS); public static final ImageDescriptor DESC_DEFINE = @@ -74,8 +66,6 @@ public class PHPUiImages { createManaged(OBJ_PREFIX, IMG_INC); public static final ImageDescriptor DESC_VAR = createManaged(OBJ_PREFIX, IMG_VAR); - public static final ImageDescriptor DESC_OBJS_ERROR = - createManaged(OBJ_PREFIX, IMG_OBJS_ERROR); public static final ImageDescriptor DESC_OBJS_WARNING = createManaged(OBJ_PREFIX, IMG_OBJS_WARNING); public static final ImageDescriptor DESC_OBJS_INFO = @@ -85,18 +75,287 @@ public class PHPUiImages { public static final ImageDescriptor DESC_CTOOL_PHP = createManaged(CTOOL_PREFIX, IMG_CTOOLS_PHP); - public static final ImageDescriptor DESC_OBJS_TEMPLATE = - createManaged(OBJ_PREFIX, IMG_OBJS_TEMPLATE); public static final ImageDescriptor DESC_CLEAR = createManaged(OBJ_PREFIX, IMG_CLEAR); - private static final String T_OBJ= "obj16"; //$NON-NLS-1$ - private static final String T_WIZBAN= "wizban"; //$NON-NLS-1$ + /* + * Set of predefined Image Descriptors. + */ + private static final String T_OBJ= "obj16"; //$NON-NLS-1$ + private static final String T_OVR= "ovr16"; //$NON-NLS-1$ + private static final String T_WIZBAN= "wizban"; //$NON-NLS-1$ + private static final String T_CLCL= "clcl16"; //$NON-NLS-1$ + private static final String T_DLCL= "dlcl16"; //$NON-NLS-1$ + private static final String T_CTOOL= "ctool16"; //$NON-NLS-1$ + private static final String T_CVIEW= "cview16"; //$NON-NLS-1$ public static final ImageDescriptor DESC_WIZBAN_NEWCLASS= create(T_WIZBAN, "newclass_wiz.gif"); //$NON-NLS-1$ + + /* + * Available cached Images in the Java plugin image registry. + */ + public static final String IMG_MISC_PUBLIC= NAME_PREFIX + "methpub_obj.gif"; //$NON-NLS-1$ + public static final String IMG_MISC_PROTECTED= NAME_PREFIX + "methpro_obj.gif"; //$NON-NLS-1$ + public static final String IMG_MISC_PRIVATE= NAME_PREFIX + "methpri_obj.gif"; //$NON-NLS-1$ + public static final String IMG_MISC_DEFAULT= NAME_PREFIX + "methdef_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_FIELD_PUBLIC= NAME_PREFIX + "field_public_obj.gif"; //$NON-NLS-1$ + public static final String IMG_FIELD_PROTECTED= NAME_PREFIX + "field_protected_obj.gif"; //$NON-NLS-1$ + public static final String IMG_FIELD_PRIVATE= NAME_PREFIX + "field_private_obj.gif"; //$NON-NLS-1$ + public static final String IMG_FIELD_DEFAULT= NAME_PREFIX + "field_default_obj.gif"; //$NON-NLS-1$ + + + public static final String IMG_OBJS_GHOST= NAME_PREFIX + "ghost.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_SEARCH_TSK= NAME_PREFIX + "search_tsk.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_PACKDECL= NAME_PREFIX + "packd_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_IMPDECL= NAME_PREFIX + "imp_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_IMPCONT= NAME_PREFIX + "impc_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_JSEARCH= NAME_PREFIX + "jsearch_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_SEARCH_DECL= NAME_PREFIX + "search_decl_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_SEARCH_REF= NAME_PREFIX + "search_ref_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CLASS= NAME_PREFIX + "class_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CLASSALT= NAME_PREFIX + "classfo_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CLASS_DEFAULT= NAME_PREFIX + "class_default_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_INTERFACE= NAME_PREFIX + "int_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_INTERFACEALT= NAME_PREFIX + "intf_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_INTERFACE_DEFAULT= NAME_PREFIX + "int_default_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CUNIT= NAME_PREFIX + "jcu_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CUNIT_RESOURCE= NAME_PREFIX + "jcu_resource_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CFILE= NAME_PREFIX + "classf_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CFILECLASS= NAME_PREFIX + "class_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CFILEINT= NAME_PREFIX + "int_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_LOGICAL_PACKAGE= NAME_PREFIX + "logical_package_obj.gif";//$NON-NLS-1$ + public static final String IMG_OJS_EMPTY_LOGICAL_PACKAGE= NAME_PREFIX + "empty_logical_package_obj.gif";//$NON-NLS-1$ + public static final String IMG_OBJS_PACKAGE= NAME_PREFIX + "package_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_EMPTY_PACK_RESOURCE= NAME_PREFIX + "empty_pack_fldr_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_EMPTY_PACKAGE= NAME_PREFIX + "empty_pack_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_PACKFRAG_ROOT= NAME_PREFIX + "packagefolder_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_MISSING_PACKFRAG_ROOT= NAME_PREFIX + "packagefolder_nonexist_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_MISSING_JAR= NAME_PREFIX + "jar_nonexist_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_JAR= NAME_PREFIX + "jar_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_EXTJAR= NAME_PREFIX + "jar_l_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_JAR_WSRC= NAME_PREFIX + "jar_src_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_EXTJAR_WSRC= NAME_PREFIX + "jar_lsrc_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_ENV_VAR= NAME_PREFIX + "envvar_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_MISSING_ENV_VAR= NAME_PREFIX + "envvar_nonexist_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_JAVA_MODEL= NAME_PREFIX + "java_model_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_UNKNOWN= NAME_PREFIX + "unknown_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_LIBRARY= NAME_PREFIX + "library_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_JAVADOCTAG= NAME_PREFIX + "jdoc_tag_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_HTMLTAG= NAME_PREFIX + "html_tag_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_TEMPLATE= NAME_PREFIX + "template_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_EXCEPTION= NAME_PREFIX + "jexception_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_ERROR= NAME_PREFIX + "jrtexception_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_BREAKPOINT_INSTALLED= NAME_PREFIX + "brkpi_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_FIXABLE_PROBLEM= NAME_PREFIX + "quickfix_warning_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_FIXABLE_ERROR= NAME_PREFIX + "quickfix_error_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_SNIPPET_EVALUATING= NAME_PREFIX + "jsbook_run_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_REFACTORING_FATAL= NAME_PREFIX + "fatalerror_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_REFACTORING_ERROR= NAME_PREFIX + "error_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_REFACTORING_WARNING= NAME_PREFIX + "warning_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_REFACTORING_INFO= NAME_PREFIX + "info_obj.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_NLS_TRANSLATE= NAME_PREFIX + "translate.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_NLS_NEVER_TRANSLATE= NAME_PREFIX + "never_translate.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_NLS_SKIP= NAME_PREFIX + "skip.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_SEARCH_READACCESS= NAME_PREFIX + "occ_read.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_SEARCH_WRITEACCESS= NAME_PREFIX + "occ_write.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_SEARCH_OCCURRENCE= NAME_PREFIX + "occ_match.gif"; //$NON-NLS-1$ + + public static final ImageDescriptor DESC_VIEW_ERRORWARNING_TAB= create(T_CVIEW, "errorwarning_tab.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_VIEW_CLASSFILEGENERATION_TAB= create(T_CVIEW, "classfilegeneration_tab.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_VIEW_JDKCOMPLIANCE_TAB= create(T_CVIEW, "jdkcompliance_tab.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_CLCL_FILTER= create(T_CLCL, "filter_ps.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_CLCL_CODE_ASSIST= create(T_CLCL, "metharg_obj.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_DLCL_CODE_ASSIST= create(T_DLCL, "metharg_obj.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_MISC_PUBLIC= createManaged(T_OBJ, IMG_MISC_PUBLIC); + public static final ImageDescriptor DESC_MISC_PROTECTED= createManaged(T_OBJ, IMG_MISC_PROTECTED); + public static final ImageDescriptor DESC_MISC_PRIVATE= createManaged(T_OBJ, IMG_MISC_PRIVATE); + public static final ImageDescriptor DESC_MISC_DEFAULT= createManaged(T_OBJ, IMG_MISC_DEFAULT); + + public static final ImageDescriptor DESC_FIELD_PUBLIC= createManaged(T_OBJ, IMG_FIELD_PUBLIC); //$NON-NLS-1$ + public static final ImageDescriptor DESC_FIELD_PROTECTED= createManaged(T_OBJ, IMG_FIELD_PROTECTED); //$NON-NLS-1$ + public static final ImageDescriptor DESC_FIELD_PRIVATE= createManaged(T_OBJ, IMG_FIELD_PRIVATE); //$NON-NLS-1$ + public static final ImageDescriptor DESC_FIELD_DEFAULT= createManaged(T_OBJ, IMG_FIELD_DEFAULT); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_MENU_SHIFT_RIGHT= create(T_CTOOL, "shift_r_edit.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_MENU_SHIFT_LEFT= create(T_CTOOL, "shift_l_edit.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_OBJS_GHOST= createManaged(T_OBJ, IMG_OBJS_GHOST); + public static final ImageDescriptor DESC_OBJS_PACKDECL= createManaged(T_OBJ, IMG_OBJS_PACKDECL); + public static final ImageDescriptor DESC_OBJS_IMPDECL= createManaged(T_OBJ, IMG_OBJS_IMPDECL); + public static final ImageDescriptor DESC_OBJS_IMPCONT= createManaged(T_OBJ, IMG_OBJS_IMPCONT); + public static final ImageDescriptor DESC_OBJS_JSEARCH= createManaged(T_OBJ, IMG_OBJS_JSEARCH); + public static final ImageDescriptor DESC_OBJS_SEARCH_DECL= createManaged(T_OBJ, IMG_OBJS_SEARCH_DECL); + public static final ImageDescriptor DESC_OBJS_SEARCH_REF= createManaged(T_OBJ, IMG_OBJS_SEARCH_REF); + public static final ImageDescriptor DESC_OBJS_CUNIT= createManaged(T_OBJ, IMG_OBJS_CUNIT); + public static final ImageDescriptor DESC_OBJS_CUNIT_RESOURCE= createManaged(T_OBJ, IMG_OBJS_CUNIT_RESOURCE); + public static final ImageDescriptor DESC_OBJS_CFILE= createManaged(T_OBJ, IMG_OBJS_CFILE); + public static final ImageDescriptor DESC_OBJS_CFILECLASS= createManaged(T_OBJ, IMG_OBJS_CFILECLASS); + public static final ImageDescriptor DESC_OBJS_CFILEINT= createManaged(T_OBJ, IMG_OBJS_CFILEINT); + public static final ImageDescriptor DESC_OBJS_PACKAGE= createManaged(T_OBJ, IMG_OBJS_PACKAGE); + public static final ImageDescriptor DESC_OBJS_EMPTY_LOGICAL_PACKAGE= createManaged(T_OBJ, IMG_OJS_EMPTY_LOGICAL_PACKAGE); + public static final ImageDescriptor DESC_OBJS_LOGICAL_PACKAGE= createManaged(T_OBJ, IMG_OBJS_LOGICAL_PACKAGE); + public static final ImageDescriptor DESC_OBJS_EMPTY_PACKAGE_RESOURCES= createManaged(T_OBJ, IMG_OBJS_EMPTY_PACK_RESOURCE); + public static final ImageDescriptor DESC_OBJS_EMPTY_PACKAGE= createManaged(T_OBJ, IMG_OBJS_EMPTY_PACKAGE); + public static final ImageDescriptor DESC_OBJS_PACKFRAG_ROOT= createManaged(T_OBJ, IMG_OBJS_PACKFRAG_ROOT); + public static final ImageDescriptor DESC_OBJS_MISSING_PACKFRAG_ROOT= createManaged(T_OBJ, IMG_OBJS_MISSING_PACKFRAG_ROOT); + public static final ImageDescriptor DESC_OBJS_JAVA_MODEL= createManaged(T_OBJ, IMG_OBJS_JAVA_MODEL); + + public static final ImageDescriptor DESC_OBJS_CLASS= createManaged(T_OBJ, IMG_OBJS_CLASS); + public static final ImageDescriptor DESC_OBJS_CLASS_DEFAULT= createManaged(T_OBJ, IMG_OBJS_CLASS_DEFAULT); + + public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PUBLIC= create(T_OBJ, "innerclass_public_obj.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_INNER_CLASS_DEFAULT= create(T_OBJ, "innerclass_default_obj.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PROTECTED= create(T_OBJ, "innerclass_protected_obj.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PRIVATE= create(T_OBJ, "innerclass_private_obj.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_OBJS_CLASSALT= createManaged(T_OBJ, IMG_OBJS_CLASSALT); + public static final ImageDescriptor DESC_OBJS_INTERFACE= createManaged(T_OBJ, IMG_OBJS_INTERFACE); + public static final ImageDescriptor DESC_OBJS_INTERFACE_DEFAULT= createManaged(T_OBJ, IMG_OBJS_INTERFACE_DEFAULT); + + public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PUBLIC= create(T_OBJ, "innerinterface_public_obj.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_DEFAULT= create(T_OBJ, "innerinterface_default_obj.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PROTECTED= create(T_OBJ, "innerinterface_protected_obj.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PRIVATE= create(T_OBJ, "innerinterface_private_obj.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_OBJS_INTERFACEALT= createManaged(T_OBJ, IMG_OBJS_INTERFACEALT); + + public static final ImageDescriptor DESC_OBJS_JAR= createManaged(T_OBJ, IMG_OBJS_JAR); + public static final ImageDescriptor DESC_OBJS_MISSING_JAR= createManaged(T_OBJ, IMG_OBJS_MISSING_JAR); + public static final ImageDescriptor DESC_OBJS_EXTJAR= createManaged(T_OBJ, IMG_OBJS_EXTJAR); + public static final ImageDescriptor DESC_OBJS_JAR_WSRC= createManaged(T_OBJ, IMG_OBJS_JAR_WSRC); + public static final ImageDescriptor DESC_OBJS_EXTJAR_WSRC= createManaged(T_OBJ, IMG_OBJS_EXTJAR_WSRC); + public static final ImageDescriptor DESC_OBJS_ENV_VAR= createManaged(T_OBJ, IMG_OBJS_ENV_VAR); + public static final ImageDescriptor DESC_OBJS_MISSING_ENV_VAR= createManaged(T_OBJ, IMG_OBJS_MISSING_ENV_VAR); + + public static final ImageDescriptor DESC_OBJS_LIBRARY= createManaged(T_OBJ, IMG_OBJS_LIBRARY); + + public static final ImageDescriptor DESC_OBJS_JAVADOCTAG= createManaged(T_OBJ, IMG_OBJS_JAVADOCTAG); + public static final ImageDescriptor DESC_OBJS_HTMLTAG= createManaged(T_OBJ, IMG_OBJS_HTMLTAG); + + public static final ImageDescriptor DESC_OBJS_TEMPLATE= createManaged(T_OBJ, IMG_OBJS_TEMPLATE); + + public static final ImageDescriptor DESC_OBJS_EXCEPTION= createManaged(T_OBJ, IMG_OBJS_EXCEPTION); + public static final ImageDescriptor DESC_OBJS_BREAKPOINT_INSTALLED= createManaged(T_OBJ, IMG_OBJS_BREAKPOINT_INSTALLED); + public static final ImageDescriptor DESC_OBJS_ERROR= createManaged(T_OBJ, IMG_OBJS_ERROR); + public static final ImageDescriptor DESC_OBJS_FIXABLE_PROBLEM= createManaged(T_OBJ, IMG_OBJS_FIXABLE_PROBLEM); + public static final ImageDescriptor DESC_OBJS_FIXABLE_ERROR= createManaged(T_OBJ, IMG_OBJS_FIXABLE_ERROR); + + public static final ImageDescriptor DESC_OBJS_SNIPPET_EVALUATING= createManaged(T_OBJ, IMG_OBJS_SNIPPET_EVALUATING); + + public static final ImageDescriptor DESC_OBJS_DEFAULT_CHANGE= create(T_OBJ, "change.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_COMPOSITE_CHANGE= create(T_OBJ, "composite_change.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_CU_CHANGE= create(T_OBJ, "cu_change.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_FILE_CHANGE= create(T_OBJ, "file_change.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_TEXT_EDIT= create(T_OBJ, "text_edit.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_OBJS_EXCLUSION_FILTER_ATTRIB= create(T_OBJ, "exclusion_filter_attrib.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_OUTPUT_FOLDER_ATTRIB= create(T_OBJ, "output_folder_attrib.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_SOURCE_ATTACH_ATTRIB= create(T_OBJ, "source_attach_attrib.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_JAVADOC_LOCATION_ATTRIB= create(T_OBJ, "javadoc_location_attrib.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_OBJS_REFACTORING_FATAL= createManaged(T_OBJ, IMG_OBJS_REFACTORING_FATAL); + public static final ImageDescriptor DESC_OBJS_REFACTORING_ERROR= createManaged(T_OBJ, IMG_OBJS_REFACTORING_ERROR); + public static final ImageDescriptor DESC_OBJS_REFACTORING_WARNING= createManaged(T_OBJ, IMG_OBJS_REFACTORING_WARNING); + public static final ImageDescriptor DESC_OBJS_REFACTORING_INFO= createManaged(T_OBJ, IMG_OBJS_REFACTORING_INFO); + public static final ImageDescriptor DESC_OBJS_NLS_TRANSLATE= createManaged(T_OBJ, IMG_OBJS_NLS_TRANSLATE); + public static final ImageDescriptor DESC_OBJS_NLS_NEVER_TRANSLATE= createManaged(T_OBJ, IMG_OBJS_NLS_NEVER_TRANSLATE); + public static final ImageDescriptor DESC_OBJS_NLS_SKIP= createManaged(T_OBJ, IMG_OBJS_NLS_SKIP); + + public static final ImageDescriptor DESC_OBJS_UNKNOWN= createManaged(T_OBJ, IMG_OBJS_UNKNOWN); + + public static final ImageDescriptor DESC_OBJS_SEARCH_READACCESS= createManaged(T_OBJ, IMG_OBJS_SEARCH_READACCESS); + public static final ImageDescriptor DESC_OBJS_SEARCH_WRITEACCESS= createManaged(T_OBJ, IMG_OBJS_SEARCH_WRITEACCESS); + public static final ImageDescriptor DESC_OBJS_SEARCH_OCCURRENCE= createManaged(T_OBJ, IMG_OBJS_SEARCH_OCCURRENCE); + + public static final ImageDescriptor DESC_OBJS_LOCAL_VARIABLE= create(T_OBJ, "localvariable_obj.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_OVR_STATIC= create(T_OVR, "static_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_FINAL= create(T_OVR, "final_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_ABSTRACT= create(T_OVR, "abstract_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_SYNCH= create(T_OVR, "synch_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_RUN= create(T_OVR, "run_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_WARNING= create(T_OVR, "warning_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_ERROR= create(T_OVR, "error_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_OVERRIDES= create(T_OVR, "over_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_IMPLEMENTS= create(T_OVR, "implm_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_CONSTRUCTOR= create(T_OVR, "constr_ovr.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OVR_FOCUS= create(T_OVR, "focus_ovr.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_WIZBAN_NEWFIELD= create(T_WIZBAN, "newfield_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_NEWINT= create(T_WIZBAN, "newint_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_NEWJPRJ= create(T_WIZBAN, "newjprj_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_NEWSRCFOLDR= create(T_WIZBAN, "newsrcfldr_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_NEWMETH= create(T_WIZBAN, "newmeth_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_NEWPACK= create(T_WIZBAN, "newpack_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_NEWSCRAPPAGE= create(T_WIZBAN, "newsbook_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_JAVA_LAUNCH= create(T_WIZBAN, "java_app_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_JAVA_ATTACH= create(T_WIZBAN, "java_attach_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR= create(T_WIZBAN, "refactor_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_FIELD= create(T_WIZBAN, "fieldrefact_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_METHOD= create(T_WIZBAN, "methrefact_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_TYPE= create(T_WIZBAN, "typerefact_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_PACKAGE= create(T_WIZBAN, "packrefact_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_CODE= create(T_WIZBAN, "coderefact_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_CU= create(T_WIZBAN, "compunitrefact_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_PULL_UP= create(T_WIZBAN, "pullup_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_JAR_PACKAGER= create(T_WIZBAN, "jar_pack_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_JAVA_WORKINGSET= create(T_WIZBAN, "java_workingset_wiz.gif");//$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_EXPORT_JAVADOC= create(T_WIZBAN, "export_javadoc_wiz.gif");//$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_EXTERNALIZE_STRINGS= create(T_WIZBAN, "extstr_wiz.gif");//$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_ADD_LIBRARY= create(T_WIZBAN, "addlibrary_wiz.gif");//$NON-NLS-1$ + + + public static final ImageDescriptor DESC_TOOL_DISPLAYSNIPPET= create(T_CTOOL, "disp_sbook.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_RUNSNIPPET= create(T_CTOOL, "run_sbook.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_INSPSNIPPET= create(T_CTOOL, "insp_sbook.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_PACKSNIPPET= create(T_CTOOL, "pack_sbook.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_TERMSNIPPET= create(T_CTOOL, "term_sbook.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_SHOW_EMPTY_PKG= create(T_CTOOL, "show_empty_pkg.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_SHOW_SEGMENTS= create(T_CTOOL, "segment_edit.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_GOTO_NEXT_ERROR= create(T_CTOOL, "next_error_nav.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_GOTO_PREV_ERROR= create(T_CTOOL, "prev_error_nav.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_TOOL_OPENTYPE= create(T_CTOOL, "opentype.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_NEWPROJECT= create(T_CTOOL, "newjprj_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_NEWPACKAGE= create(T_CTOOL, "newpack_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_NEWCLASS= create(T_CTOOL, "newclass_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_NEWINTERFACE= create(T_CTOOL, "newint_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_NEWSNIPPET= create(T_CTOOL, "newsbook_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_TOOL_NEWPACKROOT= create(T_CTOOL, "newpackfolder_wiz.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_TOOL_CLASSPATH_ORDER= create(T_OBJ, "cp_order_obj.gif"); //$NON-NLS-1$ + + // Keys for correction proposal. We have to put the image into the registry since "code assist" doesn't + // have a life cycle. So no change to dispose icons. + + public static final String IMG_CORRECTION_CHANGE= NAME_PREFIX + "correction_change.gif"; //$NON-NLS-1$ + public static final String IMG_CORRECTION_MOVE= NAME_PREFIX + "correction_move.gif"; //$NON-NLS-1$ + public static final String IMG_CORRECTION_RENAME= NAME_PREFIX + "correction_rename.gif"; //$NON-NLS-1$ + public static final String IMG_CORRECTION_DELETE_IMPORT= NAME_PREFIX + "correction_delete_import.gif"; //$NON-NLS-1$ + public static final String IMG_CORRECTION_LOCAL= NAME_PREFIX + "localvariable_obj.gif"; //$NON-NLS-1$ + static { + createManaged(T_OBJ, IMG_CORRECTION_CHANGE); + createManaged(T_OBJ, IMG_CORRECTION_MOVE); + createManaged(T_OBJ, IMG_CORRECTION_RENAME); + createManaged(T_OBJ, IMG_CORRECTION_DELETE_IMPORT); + createManaged(T_OBJ, IMG_CORRECTION_LOCAL); + } /** * Returns the image managed under the given key in this registry. * diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/OpenActionUtil.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/OpenActionUtil.java new file mode 100644 index 0000000..272cf01 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/OpenActionUtil.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.actions; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.ISourceReference; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.ui.JavaElementLabelProvider; +import net.sourceforge.phpeclipse.phpeditor.EditorUtility; + +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.dialogs.ElementListSelectionDialog; + +public class OpenActionUtil { + + private OpenActionUtil() { + // no instance. + } + + /** + * Opens the editor on the given element and subsequently selects it. + */ + public static void open(Object element) throws JavaModelException, PartInitException { + open(element, true); + } + + /** + * Opens the editor on the given element and subsequently selects it. + */ + public static void open(Object element, boolean activate) throws JavaModelException, PartInitException { + IEditorPart part= EditorUtility.openInEditor(element, activate); + if (element instanceof IJavaElement) + EditorUtility.revealInEditor(part, (IJavaElement)element); + } + + /** + * Filters out source references from the given code resolve results. + * A utility method that can be called by subclassers. + */ + public static List filterResolveResults(IJavaElement[] codeResolveResults) { + int nResults= codeResolveResults.length; + List refs= new ArrayList(nResults); + for (int i= 0; i < nResults; i++) { + if (codeResolveResults[i] instanceof ISourceReference) + refs.add(codeResolveResults[i]); + } + return refs; + } + + /** + * Shows a dialog for resolving an ambigous java element. + * Utility method that can be called by subclassers. + */ + public static IJavaElement selectJavaElement(IJavaElement[] elements, Shell shell, String title, String message) { + + int nResults= elements.length; + + if (nResults == 0) + return null; + + if (nResults == 1) + return elements[0]; + + int flags= JavaElementLabelProvider.SHOW_DEFAULT + | JavaElementLabelProvider.SHOW_QUALIFIED + | JavaElementLabelProvider.SHOW_ROOT; + + ElementListSelectionDialog dialog= new ElementListSelectionDialog(shell, new JavaElementLabelProvider(flags)); + dialog.setTitle(title); + dialog.setMessage(message); + dialog.setElements(elements); + + if (dialog.open() == ElementListSelectionDialog.OK) { + Object[] selection= dialog.getResult(); + if (selection != null && selection.length > 0) { + nResults= selection.length; + for (int i= 0; i < nResults; i++) { + Object current= selection[i]; + if (current instanceof IJavaElement) + return (IJavaElement) current; + } + } + } + return null; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/SelectionConverter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/SelectionConverter.java new file mode 100644 index 0000000..605980e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/SelectionConverter.java @@ -0,0 +1,236 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.actions; + +import java.util.Iterator; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler; +import net.sourceforge.phpdt.ui.IWorkingCopyManager; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.phpeditor.PHPEditor; + +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IWorkbenchPart; + +public class SelectionConverter { + + private static final IJavaElement[] EMPTY_RESULT= new IJavaElement[0]; + + private SelectionConverter() { + // no instance + } + + /** + * Converts the selection provided by the given part into a structured selection. + * The following conversion rules are used: + *
          + *
        • part instanceof PHPEditor: returns a structured selection + * using code resolve to convert the editor's text selection.
        • + *
        • part instanceof IWorkbenchPart: returns the part's selection + * if it is a structured selection.
        • + *
        • default: returns an empty structured selection.
        • + *
        + */ + public static IStructuredSelection getStructuredSelection(IWorkbenchPart part) throws JavaModelException { + if (part instanceof PHPEditor) + return new StructuredSelection(codeResolve((PHPEditor)part)); + ISelectionProvider provider= part.getSite().getSelectionProvider(); + if (provider != null) { + ISelection selection= provider.getSelection(); + if (selection instanceof IStructuredSelection) + return (IStructuredSelection)selection; + } + return StructuredSelection.EMPTY; + } + + + /** + * Converts the given structured selection into an array of Java elements. + * An empty array is returned if one of the elements stored in the structured + * selection is not of tupe IJavaElement + */ + public static IJavaElement[] getElements(IStructuredSelection selection) { + if (!selection.isEmpty()) { + IJavaElement[] result= new IJavaElement[selection.size()]; + int i= 0; + for (Iterator iter= selection.iterator(); iter.hasNext(); i++) { + Object element= (Object) iter.next(); + if (!(element instanceof IJavaElement)) + return EMPTY_RESULT; + result[i]= (IJavaElement)element; + } + return result; + } + return EMPTY_RESULT; + } + + public static boolean canOperateOn(PHPEditor editor) { + if (editor == null) + return false; + return getInput(editor) != null; + + } + + /** + * Converts the text selection provided by the given editor into an array of + * Java elements. If the selection doesn't cover a Java element and the selection's + * length is greater than 0 the methods returns the editor's input element. + */ + public static IJavaElement[] codeResolveOrInput(PHPEditor editor) throws JavaModelException { + IJavaElement input= getInput(editor); + ITextSelection selection= (ITextSelection)editor.getSelectionProvider().getSelection(); + IJavaElement[] result= codeResolve(input, selection); + if (result.length == 0) { + result= new IJavaElement[] {input}; + } + return result; + } + + public static IJavaElement[] codeResolveOrInputHandled(PHPEditor editor, Shell shell, String title) { + try { + return codeResolveOrInput(editor); + } catch(JavaModelException e) { + ExceptionHandler.handle(e, shell, title, ActionMessages.getString("SelectionConverter.codeResolve_failed")); //$NON-NLS-1$ + } + return null; + } + + /** + * Converts the text selection provided by the given editor a Java element by + * asking the user if code reolve returned more than one result. If the selection + * doesn't cover a Java element and the selection's length is greater than 0 the + * methods returns the editor's input element. + */ + public static IJavaElement codeResolveOrInput(PHPEditor editor, Shell shell, String title, String message) throws JavaModelException { + IJavaElement[] elements= codeResolveOrInput(editor); + if (elements == null || elements.length == 0) + return null; + IJavaElement candidate= elements[0]; + if (elements.length > 1) { + candidate= OpenActionUtil.selectJavaElement(elements, shell, title, message); + } + return candidate; + } + + public static IJavaElement codeResolveOrInputHandled(PHPEditor editor, Shell shell, String title, String message) { + try { + return codeResolveOrInput(editor, shell, title, message); + } catch (JavaModelException e) { + ExceptionHandler.handle(e, shell, title, ActionMessages.getString("SelectionConverter.codeResolveOrInput_failed")); //$NON-NLS-1$ + } + return null; + } + + public static IJavaElement[] codeResolve(PHPEditor editor) throws JavaModelException { + return codeResolve(getInput(editor), (ITextSelection)editor.getSelectionProvider().getSelection()); + } + + /** + * Converts the text selection provided by the given editor a Java element by + * asking the user if code reolve returned more than one result. If the selection + * doesn't cover a Java element null is returned. + */ + public static IJavaElement codeResolve(PHPEditor editor, Shell shell, String title, String message) throws JavaModelException { + IJavaElement[] elements= codeResolve(editor); + if (elements == null || elements.length == 0) + return null; + IJavaElement candidate= elements[0]; + if (elements.length > 1) { + candidate= OpenActionUtil.selectJavaElement(elements, shell, title, message); + } + return candidate; + } + + public static IJavaElement[] codeResolveHandled(PHPEditor editor, Shell shell, String title) { + try { + return codeResolve(editor); + } catch (JavaModelException e) { + ExceptionHandler.handle(e, shell, title, ActionMessages.getString("SelectionConverter.codeResolve_failed")); //$NON-NLS-1$ + } + return null; + } + + public static IJavaElement getElementAtOffset(PHPEditor editor) throws JavaModelException { + return getElementAtOffset(getInput(editor), (ITextSelection)editor.getSelectionProvider().getSelection()); + } + + public static IType getTypeAtOffset(PHPEditor editor) throws JavaModelException { + IJavaElement element= SelectionConverter.getElementAtOffset(editor); + IType type= (IType)element.getAncestor(IJavaElement.TYPE); + if (type == null) { + ICompilationUnit unit= SelectionConverter.getInputAsCompilationUnit(editor); + if (unit != null) + type= unit.findPrimaryType(); + } + return type; + } + + public static IJavaElement getInput(PHPEditor editor) { + if (editor == null) + return null; + IEditorInput input= editor.getEditorInput(); +// if (input instanceof IClassFileEditorInput) +// return ((IClassFileEditorInput)input).getClassFile(); + IWorkingCopyManager manager= PHPeclipsePlugin.getDefault().getWorkingCopyManager(); + return manager.getWorkingCopy(input); + } + + public static ICompilationUnit getInputAsCompilationUnit(PHPEditor editor) { + Object editorInput= SelectionConverter.getInput(editor); + if (editorInput instanceof ICompilationUnit) + return (ICompilationUnit)editorInput; + else + return null; + } + + private static IJavaElement[] codeResolve(IJavaElement input, ITextSelection selection) throws JavaModelException { +// if (input instanceof ICodeAssist) { +// IJavaElement[] elements= ((ICodeAssist)input).codeSelect(selection.getOffset(), selection.getLength()); +// if (elements != null && elements.length > 0) +// return elements; +// } + return EMPTY_RESULT; + } + + private static IJavaElement getElementAtOffset(IJavaElement input, ITextSelection selection) throws JavaModelException { + if (input instanceof ICompilationUnit) { + ICompilationUnit cunit= (ICompilationUnit)input; + if (cunit.isWorkingCopy()) { + synchronized (cunit) { + cunit.reconcile(); + } + } + IJavaElement ref= cunit.getElementAt(selection.getOffset()); + if (ref == null) + return input; + else + return ref; + } +// else if (input instanceof IClassFile) { +// IJavaElement ref= ((IClassFile)input).getElementAt(selection.getOffset()); +// if (ref == null) +// return input; +// else +// return ref; +// } + return null; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/BasicSelectionTransferDragAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/BasicSelectionTransferDragAdapter.java new file mode 100644 index 0000000..306796d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/BasicSelectionTransferDragAdapter.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.dnd; + +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSourceAdapter; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.Transfer; + +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; + +public class BasicSelectionTransferDragAdapter extends DragSourceAdapter implements TransferDragSourceListener { + + private ISelectionProvider fProvider; + + public BasicSelectionTransferDragAdapter(ISelectionProvider provider) { + Assert.isNotNull(provider); + fProvider= provider; + } + + /** + * @see TransferDragSourceListener#getTransfer + */ + public Transfer getTransfer() { + return LocalSelectionTransfer.getInstance(); + } + + /* non Java-doc + * @see org.eclipse.swt.dnd.DragSourceListener#dragStart + */ + public void dragStart(DragSourceEvent event) { + ISelection selection= fProvider.getSelection(); + LocalSelectionTransfer.getInstance().setSelection(selection); + LocalSelectionTransfer.getInstance().setSelectionSetTime(event.time); + event.doit= isDragable(selection); + } + + /** + * Checks if the elements contained in the given selection can + * be dragged. + *

        + * Subclasses may override. + * + * @param selection containing the elements to be dragged + */ + protected boolean isDragable(ISelection selection) { + return true; + } + + + /* non Java-doc + * @see org.eclipse.swt.dnd.DragSourceListener#dragSetData + */ + public void dragSetData(DragSourceEvent event) { + // For consistency set the data to the selection even though + // the selection is provided by the LocalSelectionTransfer + // to the drop target adapter. + event.data= LocalSelectionTransfer.getInstance().getSelection(); + } + + + /* non Java-doc + * @see org.eclipse.swt.dnd.DragSourceListener#dragFinished + */ + public void dragFinished(DragSourceEvent event) { + // We assume that the drop target listener has done all + // the work. + Assert.isTrue(event.detail == DND.DROP_NONE); + LocalSelectionTransfer.getInstance().setSelection(null); + LocalSelectionTransfer.getInstance().setSelectionSetTime(0); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/DelegatingDragAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/DelegatingDragAdapter.java new file mode 100644 index 0000000..74ace1c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/DelegatingDragAdapter.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.dnd; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.swt.dnd.DragSource; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.DragSourceListener; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.dnd.TransferData; + +import org.eclipse.jface.util.Assert; + +/** + * A delegating drag adapter negotiates between a set of TransferDragSourceListeners + * On dragStart the adapter determines the listener to be used for any further + * drag* callback. + */ +public class DelegatingDragAdapter implements DragSourceListener { + + private TransferDragSourceListener[] fPossibleListeners; + private List fActiveListeners; + private TransferDragSourceListener fFinishListener; + + public DelegatingDragAdapter(TransferDragSourceListener[] listeners) { + setPossibleListeners(listeners); + } + + protected void setPossibleListeners(TransferDragSourceListener[] listeners) { + Assert.isNotNull(listeners); + Assert.isTrue(fActiveListeners == null, "Can only set possible listeners before drag operation has started"); //$NON-NLS-1$ + fPossibleListeners= listeners; + } + + /* non Java-doc + * @see DragSourceListener + */ + public void dragStart(DragSourceEvent event) { + fFinishListener= null; + boolean saveDoit= event.doit; + Object saveData= event.data; + boolean doIt= false; + List transfers= new ArrayList(fPossibleListeners.length); + fActiveListeners= new ArrayList(fPossibleListeners.length); + + for (int i= 0; i < fPossibleListeners.length; i++) { + TransferDragSourceListener listener= fPossibleListeners[i]; + event.doit= saveDoit; + listener.dragStart(event); + if (event.doit) { + transfers.add(listener.getTransfer()); + fActiveListeners.add(listener); + } + doIt= doIt || event.doit; + } + if (doIt) { + ((DragSource)event.widget).setTransfer((Transfer[])transfers.toArray(new Transfer[transfers.size()])); + } + event.data= saveData; + event.doit= doIt; + } + + /* non Java-doc + * @see DragSourceListener + */ + public void dragSetData(DragSourceEvent event) { + fFinishListener= getListener(event.dataType); + if (fFinishListener != null) + fFinishListener.dragSetData(event); + } + + /* non Java-doc + * @see DragSourceListener + */ + public void dragFinished(DragSourceEvent event) { + try{ + if (fFinishListener != null) { + fFinishListener.dragFinished(event); + } else { + // If the user presses Escape then we get a dragFinished without + // getting a dragSetData before. + fFinishListener= getListener(event.dataType); + if (fFinishListener != null) + fFinishListener.dragFinished(event); + } + } finally{ + fFinishListener= null; + fActiveListeners= null; + } + } + + private TransferDragSourceListener getListener(TransferData type) { + if (type == null) + return null; + + for (Iterator iter= fActiveListeners.iterator(); iter.hasNext();) { + TransferDragSourceListener listener= (TransferDragSourceListener)iter.next(); + if (listener.getTransfer().isSupportedType(type)) { + return listener; + } + } + return null; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/DelegatingDropAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/DelegatingDropAdapter.java new file mode 100644 index 0000000..c3ad84a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/DelegatingDropAdapter.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.dnd; + +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.DropTargetListener; +import org.eclipse.swt.dnd.TransferData; + +import org.eclipse.jface.util.Assert; + +/** + * A delegating drop adapter negotiates between a set of TransferDropTargetListeners + * On dragEnter the adapter determines the listener to be used for any further + * drag* callback. + */ +public class DelegatingDropAdapter implements DropTargetListener { + + private TransferDropTargetListener[] fListeners; + + private TransferDropTargetListener fChosenListener; + + /** + * Creates a new delegating drop adapter. + * + * @param listeners an array of potential listeners + */ + public DelegatingDropAdapter(TransferDropTargetListener[] listeners) { + fListeners= listeners; + Assert.isNotNull(listeners); + } + + /* non Java-doc + * @see DropTargetListener + */ + public void dragEnter(DropTargetEvent event) { + fChosenListener= null; + event.currentDataType= selectPreferredListener(event.dataTypes); + if (fChosenListener != null) + fChosenListener.dragEnter(event); + } + + /* non Java-doc + * @see DropTargetListener + */ + public void dragLeave(DropTargetEvent event){ + if (fChosenListener != null) + fChosenListener.dragLeave(event); + } + + /* non Java-doc + * @see DropTargetListener + */ + public void dragOperationChanged(DropTargetEvent event){ + if (fChosenListener != null) + fChosenListener.dragOperationChanged(event); + } + + /* non Java-doc + * @see DropTargetListener + */ + public void dragOver(DropTargetEvent event){ + if (fChosenListener != null) + fChosenListener.dragOver(event); + } + + /* non Java-doc + * @see DropTargetListener + */ + public void drop(DropTargetEvent event){ + if (fChosenListener != null) + fChosenListener.drop(event); + fChosenListener= null; + } + + /* non Java-doc + * @see DropTargetListener + */ + public void dropAccept(DropTargetEvent event){ + if (fChosenListener != null) + fChosenListener.dropAccept(event); + } + + private TransferData selectPreferredListener(TransferData[] dataTypes) { + for (int i= 0; i < fListeners.length; i++) { + TransferData data= computeTransferData(dataTypes, fListeners[i]); + if (data != null) + return data; + } + return null; + } + + private TransferData computeTransferData(TransferData[] dataTypes, TransferDropTargetListener listener) { + for (int i= 0; i < dataTypes.length; i++) { + if (listener.getTransfer().isSupportedType(dataTypes[i])) { + fChosenListener= listener; + return dataTypes[i]; + } + } + return null; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDragAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDragAdapter.java new file mode 100644 index 0000000..2906be9 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDragAdapter.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.dnd; + +import org.eclipse.swt.dnd.DragSourceEvent; + +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredViewer; + +public class JdtViewerDragAdapter extends DelegatingDragAdapter { + + private StructuredViewer fViewer; + + public JdtViewerDragAdapter(StructuredViewer viewer, TransferDragSourceListener[] listeners) { + super(listeners); + Assert.isNotNull(viewer); + fViewer= viewer; + } + + public void dragStart(DragSourceEvent event) { + IStructuredSelection selection= (IStructuredSelection)fViewer.getSelection(); + if (selection.isEmpty()) { + event.doit= false; + return; + } + super.dragStart(event); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDropAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDropAdapter.java new file mode 100644 index 0000000..805efb3 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDropAdapter.java @@ -0,0 +1,261 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.dnd; + +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.DropTargetListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.TreeItem; + +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.StructuredViewer; + +/** + * A drag and drop adapter to be used together with structured viewers. + * The adapater delegates the dragEnter, dragOperationChanged + * , dragOver and dropAccept method to the + * validateDrop method. Furthermore it adds location feedback. + */ +public class JdtViewerDropAdapter implements DropTargetListener { + + /** + * Constant describing the position of the mouse cursor relative + * to the target object. This means the mouse is positioned + * slightly before the target. + */ + protected static final int LOCATION_BEFORE= 1; + + /** + * Constant describing the position of the mouse cursor relative + * to the target object. This means the mouse is positioned + * slightly after the target. + */ + protected static final int LOCATION_AFTER= 2; + + /** + * Constant describing the position of the mouse cursor relative + * to the target object. This means the mouse is positioned + * directly on the target. + */ + protected static final int LOCATION_ON= 3; + + /** + * Constant describing the position of the mouse cursor relative + * to the target object. This means the mouse is not positioned + * over or near any valid target. + */ + protected static final int LOCATION_NONE= 4; + + /** + * The threshold used to determine if the mouse is before or after + * an item. + */ + private static final int LOCATION_EPSILON= 5; + + /** + * Style to enable location feedback. + */ + public static final int INSERTION_FEEDBACK= 1 << 1; + + private StructuredViewer fViewer; + private int fFeedback; + private boolean fShowInsertionFeedback; + private int fRequestedOperation; + private int fLastOperation; + protected int fLocation; + protected Object fTarget; + + public JdtViewerDropAdapter(StructuredViewer viewer, int feedback) { + fViewer= viewer; + Assert.isNotNull(fViewer); + fFeedback= feedback; + fLastOperation= -1; + } + + /** + * Controls whether the drop adapter shows insertion feedback or not. + * + * @param showInsertionFeedback true if the drop adapter is supposed + * to show insertion feedback. Otherwise false + */ + public void showInsertionFeedback(boolean showInsertionFeedback) { + fShowInsertionFeedback= showInsertionFeedback; + } + + /** + * Returns the viewer this adapter is working on. + */ + protected StructuredViewer getViewer() { + return fViewer; + } + + //---- Hooks to override ----------------------------------------------------- + + /** + * The actual drop has occurred. Calls drop(Object target, DropTargetEvent event) + * . + * @see DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent) + */ + public void drop(DropTargetEvent event) { + drop(fTarget, event); + } + + /** + * The actual drop has occurred. + * @param target the drop target in form of a domain element. + * @param event the drop traget event + */ + public void drop(Object target, DropTargetEvent event) { + } + + /** + * Checks if the drop is valid. The method calls validateDrop + * (Object target, DropTargetEvent event). Implementors can alter the + * currentDataType field and the detail field + * to give feedback about drop acceptence. + */ + public void validateDrop(DropTargetEvent event) { + validateDrop(fTarget, event, fRequestedOperation); + } + + /** + * Checks if the drop on the current target is valid. The method + * can alter the currentDataType field and the + * detail field to give feedback about drop acceptence. + * @param target the drop target in form of a domain element. + * @param event the drop traget event + * @param operation the operation requested by the user. + */ + public void validateDrop(Object target, DropTargetEvent event, int operation) { + } + + public void dragEnter(DropTargetEvent event) { + dragOperationChanged(event); + } + + public void dragLeave(DropTargetEvent event) { + fTarget= null; + fLocation= LOCATION_NONE; + } + + public void dragOperationChanged(DropTargetEvent event) { + fRequestedOperation= event.detail; + fTarget= computeTarget(event); + fLocation= computeLocation(event); + validateDrop(event); + fLastOperation= event.detail; + computeFeedback(event); + } + + public void dragOver(DropTargetEvent event) { + Object oldTarget= fTarget; + fTarget= computeTarget(event); + + //set the location feedback + int oldLocation= fLocation; + fLocation= computeLocation(event); + if (oldLocation != fLocation || oldTarget != fTarget || fLastOperation != event.detail) { + validateDrop(event); + fLastOperation= event.detail; + } else { + event.detail= fLastOperation; + } + computeFeedback(event); + } + + public void dropAccept(DropTargetEvent event) { + fTarget= computeTarget(event); + validateDrop(event); + fLastOperation= event.detail; + } + + /** + * Returns the data held by event.item. Inside a viewer + * this corresponds to the items data model element. + */ + protected Object computeTarget(DropTargetEvent event) { + return event.item == null ? null : event.item.getData(); + } + + /** + * Returns the position of the given coordinates relative to the given target. + * The position is determined to be before, after, or on the item, based on + * some threshold value. The return value is one of the LOCATION_* constants + * defined in this class. + */ + final protected int computeLocation(DropTargetEvent event) { + if (!(event.item instanceof Item)) + return LOCATION_NONE; + + Item item= (Item) event.item; + Point coordinates= fViewer.getControl().toControl(new Point(event.x, event.y)); + Rectangle bounds= getBounds(item); + if (bounds == null) { + return LOCATION_NONE; + } + if ((coordinates.y - bounds.y) < LOCATION_EPSILON) { + return LOCATION_BEFORE; + } + if ((bounds.y + bounds.height - coordinates.y) < LOCATION_EPSILON) { + return LOCATION_AFTER; + } + return LOCATION_ON; + } + + /** + * Returns the bounds of the given item, or null if it is not a + * valid type of item. + */ + private Rectangle getBounds(Item item) { + if (item instanceof TreeItem) + return ((TreeItem) item).getBounds(); + + if (item instanceof TableItem) + return ((TableItem) item).getBounds(0); + + return null; + } + + /** + * Sets the drag under feedback corresponding to the value of fLocation + * and the INSERTION_FEEDBACK style bit. + */ + protected void computeFeedback(DropTargetEvent event) { + if (!fShowInsertionFeedback && fLocation != LOCATION_NONE) { + event.feedback= DND.FEEDBACK_SELECT; + } else { + if (fLocation == LOCATION_BEFORE) { + event.feedback= DND.FEEDBACK_INSERT_BEFORE; + } else if (fLocation == LOCATION_AFTER) { + event.feedback= DND.FEEDBACK_INSERT_AFTER; + } + } + event.feedback|= fFeedback; + } + + /** + * Sets the drop operation to DROP_NODE. + */ + protected void clearDropOperation(DropTargetEvent event) { + event.detail= DND.DROP_NONE; + } + + /** + * Returns the requested drop operation. + */ + protected int getRequestedOperation() { + return fRequestedOperation; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/LocalSelectionTransfer.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/LocalSelectionTransfer.java new file mode 100644 index 0000000..408c2f5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/LocalSelectionTransfer.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.dnd; + +import net.sourceforge.phpdt.internal.ui.PHPUIMessages; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.dnd.ByteArrayTransfer; +import org.eclipse.swt.dnd.TransferData; + + +public class LocalSelectionTransfer extends ByteArrayTransfer { + + // First attempt to create a UUID for the type name to make sure that + // different Eclipse applications use different "types" of + // LocalSelectionTransfer + private static final String TYPE_NAME= "local-selection-transfer-format" + (new Long(System.currentTimeMillis())).toString(); //$NON-NLS-1$; + private static final int TYPEID= registerType(TYPE_NAME); + + private static final LocalSelectionTransfer INSTANCE= new LocalSelectionTransfer(); + + private ISelection fSelection; + private int fSelectionSetTime; + + private LocalSelectionTransfer() { + } + + /** + * Returns the singleton. + */ + public static LocalSelectionTransfer getInstance() { + return INSTANCE; + } + + /** + * Sets the transfer data for local use. + */ + public void setSelection(ISelection s) { + fSelection= s; + } + + /** + * Returns the local transfer data. + */ + public ISelection getSelection() { + return fSelection; + } + + public void javaToNative(Object object, TransferData transferData) { + // No encoding needed since this is a hardcoded string read and written in the same process. + // See nativeToJava below + byte[] check= TYPE_NAME.getBytes(); + super.javaToNative(check, transferData); + } + + public Object nativeToJava(TransferData transferData) { + Object result= super.nativeToJava(transferData); + if (isInvalidNativeType(result)) { + PHPeclipsePlugin.log(IStatus.ERROR, PHPUIMessages.getString("LocalSelectionTransfer.errorMessage")); //$NON-NLS-1$ + } + return fSelection; + } + + private boolean isInvalidNativeType(Object result) { + // No encoding needed since this is a hardcoded string read and written in the same process. + // See javaToNative above + return !(result instanceof byte[]) || !TYPE_NAME.equals(new String((byte[])result)); + } + + /** + * The type id used to identify this transfer. + */ + protected int[] getTypeIds() { + return new int[] {TYPEID}; + } + + protected String[] getTypeNames(){ + return new String[] {TYPE_NAME}; + } + + public int getSelectionSetTime() { + return fSelectionSetTime; + } + + public void setSelectionSetTime(int time) { + fSelectionSetTime= time; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/ResourceTransferDragAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/ResourceTransferDragAdapter.java new file mode 100644 index 0000000..876bb0c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/ResourceTransferDragAdapter.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.dnd; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import net.sourceforge.phpdt.internal.ui.IJavaStatusConstants; +import net.sourceforge.phpdt.internal.ui.PHPUIMessages; +import net.sourceforge.phpdt.internal.ui.util.SWTUtil; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSourceAdapter; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.part.ResourceTransfer; + + +/** + * A drag adapter that transfers the current selection as + * IResource. Only those elements in the selection are part + * of the transfer which can be converted into an IResource + * . + */ +public class ResourceTransferDragAdapter extends DragSourceAdapter implements TransferDragSourceListener { + + private ISelectionProvider fProvider; + + private static final List EMPTY_LIST= new ArrayList(0); + + /** + * Creates a new ResourceTransferDragAdapter for the given selection + * provider. + * + * @param provider the selection provider to access the viewer's selection + */ + public ResourceTransferDragAdapter(ISelectionProvider provider) { + fProvider= provider; + Assert.isNotNull(fProvider); + } + + public Transfer getTransfer() { + return ResourceTransfer.getInstance(); + } + + public void dragStart(DragSourceEvent event) { + event.doit= convertSelection().size() > 0; + } + + public void dragSetData(DragSourceEvent event) { + List resources= convertSelection(); + event.data= (IResource[]) resources.toArray(new IResource[resources.size()]); + } + + public void dragFinished(DragSourceEvent event) { + if (!event.doit) + return; + + if (event.detail == DND.DROP_MOVE) { + handleFinishedDropMove(event); + } + } + + private List convertSelection() { + ISelection s= fProvider.getSelection(); + if (!(s instanceof IStructuredSelection)) + return EMPTY_LIST; + IStructuredSelection selection= (IStructuredSelection)s; + List result= new ArrayList(selection.size()); + for (Iterator iter= selection.iterator(); iter.hasNext();) { + Object element= iter.next(); + if (element instanceof IAdaptable) { + IAdaptable adaptable= (IAdaptable)element; + IResource resource= (IResource)adaptable.getAdapter(IResource.class); + if (resource != null) + result.add(resource); + } + } + return result; + } + + private void handleFinishedDropMove(DragSourceEvent event) { + MultiStatus status= new MultiStatus( + PHPeclipsePlugin.getPluginId(), + IJavaStatusConstants.INTERNAL_ERROR, + PHPUIMessages.getString("ResourceTransferDragAdapter.cannot_delete_resource"), //$NON-NLS-1$ + null); + List resources= convertSelection(); + for (Iterator iter= resources.iterator(); iter.hasNext();) { + IResource resource= (IResource) iter.next(); + try { + resource.delete(true, null); + } catch (CoreException e) { + status.add(e.getStatus()); + } + } + if (status.getChildren().length > 0) { + Shell parent= SWTUtil.getShell(event.widget); + ErrorDialog error= new ErrorDialog(parent, + PHPUIMessages.getString("ResourceTransferDragAdapter.moving_resource"), //$NON-NLS-1$ + PHPUIMessages.getString("ResourceTransferDragAdapter.cannot_delete_files"), //$NON-NLS-1$ + status, IStatus.ERROR); + error.open(); + } + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/TransferDragSourceListener.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/TransferDragSourceListener.java new file mode 100644 index 0000000..b4f7ecb --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/TransferDragSourceListener.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.dnd; + +import org.eclipse.swt.dnd.DragSourceListener; +import org.eclipse.swt.dnd.Transfer; + +/** + * A special drag source listener which is typed with a TransferData. + */ +public interface TransferDragSourceListener extends DragSourceListener { + + /** + * Returns the transfer used by this drag source. + */ + public Transfer getTransfer(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/TransferDropTargetListener.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/TransferDropTargetListener.java new file mode 100644 index 0000000..f642ae8 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/TransferDropTargetListener.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.dnd; + +import org.eclipse.swt.dnd.DropTargetListener; +import org.eclipse.swt.dnd.Transfer; + +/** + * A special drop target listener which is typed with a TransferData. + */ +public interface TransferDropTargetListener extends DropTargetListener { + + /** + * Returns the transfer used by this drop target. + */ + public Transfer getTransfer(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/packageview/PackagesMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/packageview/PackagesMessages.java new file mode 100644 index 0000000..121b683 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/packageview/PackagesMessages.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.packageview; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class PackagesMessages { + + private static final String RESOURCE_BUNDLE= "net.sourceforge.phpdt.internal.ui.packageview.PackagesMessages";//$NON-NLS-1$ + + private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + private PackagesMessages() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + + /** + * Gets a string from the resource bundle and formats it with the argument + * + * @param key the string used to get the bundle value, must not be null + */ + public static String getFormattedString(String key, Object arg) { + String format= null; + try { + format= fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + if (arg == null) + arg= ""; //$NON-NLS-1$ + return MessageFormat.format(format, new Object[] { arg }); + } + + /** + * Gets a string from the resource bundle and formats it with arguments + */ + public static String getFormattedString(String key, String[] args) { + return MessageFormat.format(fgResourceBundle.getString(key), args); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/packageview/PackagesMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/packageview/PackagesMessages.properties new file mode 100644 index 0000000..01bac3f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/packageview/PackagesMessages.properties @@ -0,0 +1,97 @@ +############################################################################### +# Copyright (c) 2000, 2003 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Common Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/cpl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### + +BuildGroup.buildProject=&Build Project +BuildGroup.rebuildProject=Rebuild Pro&ject + +DragAdapter.deleting=Deleting ... +DragAdapter.problem=Problem while moving or copying files. +DragAdapter.problemTitle=Drag & Drop +DragAdapter.refreshing=Refreshing... + +DropAdapter.alreadyExists={0} already exists. Would you like to overwrite it? +DropAdapter.errorMessage=Error while moving or copying files. +DropAdapter.errorSame=Cannot copy {0}: the destination folder is the same as the source folder. +DropAdapter.errorSubfolder=Cannot copy {0}: the destination folder is a subfolder of the source folder. +DropAdapter.errorTitle=Drag & Drop +DropAdapter.question=Question + +FilterSelectionAction.apply.label=Select &filters to apply (matching files will be hidden): +FilterSelectionAction.apply.toolTip=Apply the defined filters +FilterSelectionAction.dialog.title=Package Explorer Filters + +GotoPackage.action.label=&Package... +GotoPackage.dialog.message=&Choose a package (? = any character, * = any string): +GotoPackage.dialog.title=Go to Package +GotoPackage.action.description=Searches for and selects the package entered. + +GotoType.action.label=&Type... +GotoType.action.description=Searches for and selects the type entered. +GotoType.dialog.message=&Choose a type (? = any character, * = any string): +GotoType.dialog.title=Go to Type +GotoType.error.message=An exception occurred while searching for types + +GotoResource.action.label=&Resource... +GotoResource.dialog.title= Go to Resource + +OpenResource.action.description=Open the selected file in an editor. +OpenResource.action.label=&Open +OpenResource.error.message=Cannot open Java editor. +OpenResource.error.messageArgs=Cannot open Java editor on {0}. {1} +OpenResource.error.messageProblems=Problems Opening Editor. +OpenResource.error.title=Open Resource + +Sorter.expectPackage=expects a PackageFragment or PackageFragmentRoot + +ShowLibraries.hideReferencedLibs=Hide referenced libraries +ShowLibraries.showReferencedLibs=Show referenced libraries + +ShowBinaries.hideBinaryProjects=Hide library projects +ShowBinaries.showBinaryProjects=Show library projects + +ShowInNavigator.description=Show the selected object(s) in the navigator +ShowInNavigator.error=Cannot open navigator +ShowInNavigator.label=Show in &Navigator + +PackageExplorer.filters=&Filters... +PackageExplorer.gotoTitle=G&o To +PackageExplorer.openPerspective=Open &Perspective +PackageExplorer.refactoringTitle=&Refactor +PackageExplorer.referencedLibs=Show Referenced &Libraries +PackageExplorer.binaryProjects=Show Library Projects +PackageExplorer.title=Package Explorer +PackageExplorer.argTitle={0}: {1} +PackageExplorer.toolTip= Working Set: {0} +PackageExplorer.toolTip2= {0} - Working Set: {1} +PackageExplorer.openWith=Open Wit&h + +PackageExplorer.element_not_present=Cannot reveal {0} in Package Explorer. The element may be hidden by a filter or an active working set. + +SelectionTransferDropAdapter.error.title=Drag and drop +SelectionTransferDropAdapter.error.message=Unexpected exception. See log for details +SelectionTransferDropAdapter.dialog.title=Move +SelectionTransferDropAdapter.dialog.preview.label=Pre&view +SelectionTransferDropAdapter.dialog.question=Do you want to update references to the moved element(s)? Click 'Preview' to see the preview of the reference updates. + +CollapseAllAction.label=Collapse All +CollapseAllAction.tooltip=Collapse All +CollapseAllAction.description=Collapse All + +ToggleLinkingAction.label=Lin&k With Editor +ToggleLinkingAction.tooltip=Link with Editor +ToggleLinkingAction.description=Link with active editor + +LayoutActionGroup.label= &Layout +LayoutActionGroup.flatLayoutAction.label= &Flat +LayoutActionGroup.hierarchicalLayoutAction.label= &Hierarchical + +ClassPathContainer.error_label=Could not resolve class path entry +PackageExplorerPart.workspace=Workspace diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/packageview/SelectionTransferDragAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/packageview/SelectionTransferDragAdapter.java new file mode 100644 index 0000000..c0fca07 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/packageview/SelectionTransferDragAdapter.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.packageview; + +import java.util.Iterator; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; + +import net.sourceforge.phpdt.internal.ui.dnd.BasicSelectionTransferDragAdapter; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; + +public class SelectionTransferDragAdapter extends BasicSelectionTransferDragAdapter { + + public SelectionTransferDragAdapter(ISelectionProvider provider) { + super(provider); + } + + protected boolean isDragable(ISelection selection) { + if (selection instanceof IStructuredSelection) { + for (Iterator iter= ((IStructuredSelection)selection).iterator(); iter.hasNext();) { + Object element= iter.next(); + if (element instanceof IJavaElement) { + IPackageFragmentRoot root= (IPackageFragmentRoot)((IJavaElement)element).getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); + if (root != null && root.isArchive()) + return false; + } + } + return true; + } + return false; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/MembersOrderPreferenceCache.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/MembersOrderPreferenceCache.java new file mode 100644 index 0000000..af66a6f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/MembersOrderPreferenceCache.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.preferences; + +import java.util.StringTokenizer; + +import net.sourceforge.phpdt.ui.PreferenceConstants; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; + + +/** + */ +public class MembersOrderPreferenceCache implements IPropertyChangeListener { + + public static final int TYPE_INDEX= 0; + public static final int CONSTRUCTORS_INDEX= 1; + public static final int METHOD_INDEX= 2; + public static final int FIELDS_INDEX= 3; + public static final int INIT_INDEX= 4; + public static final int STATIC_FIELDS_INDEX= 5; + public static final int STATIC_INIT_INDEX= 6; + public static final int STATIC_METHODS_INDEX= 7; + public static final int N_ENTRIES= STATIC_METHODS_INDEX + 1; + + private int[] fOffsets= null; + + public void propertyChange(PropertyChangeEvent event) { + if (PreferenceConstants.APPEARANCE_MEMBER_SORT_ORDER.equals(event.getProperty())) { + fOffsets= null; + } + } + + public int getIndex(int kind) { + if (fOffsets == null) { + fOffsets= getOffsets(); + } + return fOffsets[kind]; + } + + private int[] getOffsets() { + int[] offsets= new int[N_ENTRIES]; + IPreferenceStore store= PreferenceConstants.getPreferenceStore(); + String key= PreferenceConstants.APPEARANCE_MEMBER_SORT_ORDER; + boolean success= fillOffsetsFromPreferenceString(store.getString(key), offsets); + if (!success) { + store.setToDefault(key); + fillOffsetsFromPreferenceString(store.getDefaultString(key), offsets); + } + return offsets; + } + + private boolean fillOffsetsFromPreferenceString(String str, int[] offsets) { + StringTokenizer tokenizer= new StringTokenizer(str, ","); //$NON-NLS-1$ + int i= 0; + while (tokenizer.hasMoreTokens()) { + String token= tokenizer.nextToken().trim(); + if ("T".equals(token)) { //$NON-NLS-1$ + offsets[TYPE_INDEX]= i++; + } else if ("M".equals(token)) { //$NON-NLS-1$ + offsets[METHOD_INDEX]= i++; + } else if ("F".equals(token)) { //$NON-NLS-1$ + offsets[FIELDS_INDEX]= i++; + } else if ("I".equals(token)) { //$NON-NLS-1$ + offsets[INIT_INDEX]= i++; + } else if ("SF".equals(token)) { //$NON-NLS-1$ + offsets[STATIC_FIELDS_INDEX]= i++; + } else if ("SI".equals(token)) { //$NON-NLS-1$ + offsets[STATIC_INIT_INDEX]= i++; + } else if ("SM".equals(token)) { //$NON-NLS-1$ + offsets[STATIC_METHODS_INDEX]= i++; + } else if ("C".equals(token)) { //$NON-NLS-1$ + offsets[CONSTRUCTORS_INDEX]= i++; + } + } + return i == N_ENTRIES; + } + + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/MembersOrderPreferencePage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/MembersOrderPreferencePage.java new file mode 100644 index 0000000..a7225ff --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/MembersOrderPreferencePage.java @@ -0,0 +1,262 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package net.sourceforge.phpdt.internal.ui.preferences; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; + +import net.sourceforge.phpdt.core.Flags; +import net.sourceforge.phpdt.internal.ui.util.SWTUtil; +import net.sourceforge.phpdt.internal.ui.viewsupport.ImageDescriptorRegistry; +import net.sourceforge.phpdt.internal.ui.viewsupport.JavaElementImageProvider; +import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.ListDialogField; +import net.sourceforge.phpdt.ui.JavaElementImageDescriptor; +import net.sourceforge.phpdt.ui.PreferenceConstants; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +public class MembersOrderPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + private static final String ALL_ENTRIES= "T,SI,SF,SM,I,F,C,M"; //$NON-NLS-1$ + private static final String PREF_OUTLINE_SORT_OPTION= PreferenceConstants.APPEARANCE_MEMBER_SORT_ORDER; + + public static final String CONSTRUCTORS= "C"; //$NON-NLS-1$ + public static final String FIELDS= "F"; //$NON-NLS-1$ + public static final String METHODS= "M"; //$NON-NLS-1$ + public static final String STATIC_METHODS= "SM"; //$NON-NLS-1$ + public static final String STATIC_FIELDS= "SF"; //$NON-NLS-1$ + public static final String INIT= "I"; //$NON-NLS-1$ + public static final String STATIC_INIT= "SI"; //$NON-NLS-1$ + public static final String TYPES= "T"; //$NON-NLS-1$ + + private ListDialogField fSortOrderList; + + private static List getSortOrderList(String string) { + StringTokenizer tokenizer= new StringTokenizer(string, ","); //$NON-NLS-1$ + List entries= new ArrayList(); + for (int i= 0; tokenizer.hasMoreTokens(); i++) { + String token= tokenizer.nextToken(); + entries.add(token); + } + return entries; + } + + private static boolean isValidEntries(List entries) { + StringTokenizer tokenizer= new StringTokenizer(ALL_ENTRIES, ","); //$NON-NLS-1$ + int i= 0; + for (; tokenizer.hasMoreTokens(); i++) { + String token= tokenizer.nextToken(); + if (!entries.contains(token)) + return false; + } + return i == entries.size(); + } + + public MembersOrderPreferencePage() { + //set the preference store + setPreferenceStore(PHPeclipsePlugin.getDefault().getPreferenceStore()); + + setDescription(PreferencesMessages.getString("MembersOrderPreferencePage.label.description")); //$NON-NLS-1$ + + String string= getPreferenceStore().getString(PREF_OUTLINE_SORT_OPTION); + + String upLabel= PreferencesMessages.getString("MembersOrderPreferencePage.button.up"); //$NON-NLS-1$ + String downLabel= PreferencesMessages.getString("MembersOrderPreferencePage.button.down"); //$NON-NLS-1$ + String[] buttonlabels= new String[] { upLabel, downLabel }; + + fSortOrderList= new ListDialogField(null, buttonlabels, new MemberSortLabelProvider()); + fSortOrderList.setDownButtonIndex(1); + fSortOrderList.setUpButtonIndex(0); + + //validate entries stored in store, false get defaults + List entries= getSortOrderList(string); + if (!isValidEntries(entries)) { + string= PHPeclipsePlugin.getDefault().getPreferenceStore().getDefaultString(PREF_OUTLINE_SORT_OPTION); + entries= getSortOrderList(string); + } + + fSortOrderList.setElements(entries); + } + + /* + * @see PreferencePage#createControl(Composite) + */ + public void createControl(Composite parent) { + super.createControl(parent); +// WorkbenchHelp.setHelp(getControl(), IJavaHelpContextIds.SORT_ORDER_PREFERENCE_PAGE); + } + + /* + * @see org.eclipse.jface.preference.PreferencePage#createContents(Composite) + */ + protected Control createContents(Composite parent) { + + + Composite composite= new Composite(parent, SWT.NONE); + + GridLayout layout= new GridLayout(); + layout.numColumns= 3; + layout.marginWidth= 0; + layout.marginHeight= 0; + composite.setLayout(layout); + + GridData data= new GridData(); + data.verticalAlignment= GridData.FILL; + data.horizontalAlignment= GridData.FILL_HORIZONTAL; + composite.setLayoutData(data); + + createSortOrderListDialogField(composite, 3); + Dialog.applyDialogFont(composite); + return composite; + } + + private void createSortOrderListDialogField(Composite composite, int span) { + fSortOrderList.doFillIntoGrid(composite, span); + + fSortOrderList.getLabelControl(null).dispose(); + + GridData data= (GridData) fSortOrderList.getListControl(null).getLayoutData(); + data.grabExcessHorizontalSpace= true; + data.verticalAlignment= 0; + data.heightHint= SWTUtil.getTableHeightHint(fSortOrderList.getTableViewer().getTable(), 8); + } + + /* + * @see org.eclipse.ui.IWorkbenchPreferencePage#init(IWorkbench) + */ + public void init(IWorkbench workbench) { + } + + /* + * @see org.eclipse.jface.preference.PreferencePage#performDefaults() + */ + protected void performDefaults() { + String string= getPreferenceStore().getDefaultString(PREF_OUTLINE_SORT_OPTION); + fSortOrderList.setElements(getSortOrderList(string)); + } + + /* + * @see org.eclipse.jface.preference.IPreferencePage#performOk() + */ + //reorders elements in the Outline based on selection + public boolean performOk() { + //update outline view + + //save preferences + IPreferenceStore store= getPreferenceStore(); + + StringBuffer buf= new StringBuffer(); + List curr= fSortOrderList.getElements(); + for (Iterator iter= curr.iterator(); iter.hasNext();) { + String s= (String) iter.next(); + buf.append(s); + buf.append(','); + } + store.setValue(PREF_OUTLINE_SORT_OPTION, buf.toString()); + PHPeclipsePlugin.getDefault().savePluginPreferences(); + return true; + } + + private class MemberSortLabelProvider extends LabelProvider { + + public MemberSortLabelProvider() { + } + + /* + * @see org.eclipse.jface.viewers.ILabelProvider#getText(Object) + */ + public String getText(Object element) { + + if (element instanceof String) { + String s= (String) element; + if (s.equals(FIELDS)) { + return PreferencesMessages.getString("MembersOrderPreferencePage.fields.label"); //$NON-NLS-1$ + } else if (s.equals(CONSTRUCTORS)) { + return PreferencesMessages.getString("MembersOrderPreferencePage.constructors.label"); //$NON-NLS-1$ + } else if (s.equals(METHODS)) { + return PreferencesMessages.getString("MembersOrderPreferencePage.methods.label"); //$NON-NLS-1$ + } else if (s.equals(STATIC_FIELDS)) { + return PreferencesMessages.getString("MembersOrderPreferencePage.staticfields.label"); //$NON-NLS-1$ + } else if (s.equals(STATIC_METHODS)) { + return PreferencesMessages.getString("MembersOrderPreferencePage.staticmethods.label"); //$NON-NLS-1$ + } else if (s.equals(INIT)) { + return PreferencesMessages.getString("MembersOrderPreferencePage.initialisers.label"); //$NON-NLS-1$ + } else if (s.equals(STATIC_INIT)) { + return PreferencesMessages.getString("MembersOrderPreferencePage.staticinitialisers.label"); //$NON-NLS-1$ + } else if (s.equals(TYPES)) { + return PreferencesMessages.getString("MembersOrderPreferencePage.types.label"); //$NON-NLS-1$ + } + } + return ""; //$NON-NLS-1$ + } + + /* + * @see org.eclipse.jface.viewers.ILabelProvider#getImage(Object) + */ + public Image getImage(Object element) { + //access to image registry + ImageDescriptorRegistry registry= PHPeclipsePlugin.getImageDescriptorRegistry(); + ImageDescriptor descriptor= null; + + if (element instanceof String) { + int visibility= Flags.AccPublic; + String s= (String) element; + if (s.equals(FIELDS)) { + //0 will give the default field image + descriptor= JavaElementImageProvider.getFieldImageDescriptor(false, visibility); + } else if (s.equals(CONSTRUCTORS)) { + descriptor= JavaElementImageProvider.getMethodImageDescriptor(false, visibility); + //add a constructor adornment to the image descriptor + descriptor= new JavaElementImageDescriptor(descriptor, JavaElementImageDescriptor.CONSTRUCTOR, JavaElementImageProvider.SMALL_SIZE); + } else if (s.equals(METHODS)) { + descriptor= JavaElementImageProvider.getMethodImageDescriptor(false, visibility); + } else if (s.equals(STATIC_FIELDS)) { + descriptor= JavaElementImageProvider.getFieldImageDescriptor(false, visibility); + //add a constructor adornment to the image descriptor + descriptor= new JavaElementImageDescriptor(descriptor, JavaElementImageDescriptor.STATIC, JavaElementImageProvider.SMALL_SIZE); + } else if (s.equals(STATIC_METHODS)) { + descriptor= JavaElementImageProvider.getMethodImageDescriptor(false, visibility); + //add a constructor adornment to the image descriptor + descriptor= new JavaElementImageDescriptor(descriptor, JavaElementImageDescriptor.STATIC, JavaElementImageProvider.SMALL_SIZE); + } else if (s.equals(INIT)) { + descriptor= JavaElementImageProvider.getMethodImageDescriptor(false, visibility); + } else if (s.equals(STATIC_INIT)) { + descriptor= JavaElementImageProvider.getMethodImageDescriptor(false, visibility); + descriptor= new JavaElementImageDescriptor(descriptor, JavaElementImageDescriptor.STATIC, JavaElementImageProvider.SMALL_SIZE); + } else if (s.equals(TYPES)) { + descriptor= JavaElementImageProvider.getTypeImageDescriptor(false, true, Flags.AccPublic); + } else { + descriptor= JavaElementImageProvider.getMethodImageDescriptor(false, Flags.AccPublic); + } + return registry.get(descriptor); + } + return null; + } + + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PHPEditorPreferencePage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PHPEditorPreferencePage.java index 836ca7c..641374d 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PHPEditorPreferencePage.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PHPEditorPreferencePage.java @@ -26,11 +26,13 @@ import net.sourceforge.phpdt.internal.ui.util.TabFolderLayout; import net.sourceforge.phpdt.ui.PreferenceConstants; import net.sourceforge.phpdt.ui.text.JavaTextTools; import net.sourceforge.phpeclipse.IPreferenceConstants; +import net.sourceforge.phpeclipse.PHPCore; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration; import net.sourceforge.phpeclipse.preferences.ColorEditor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Preferences; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; import org.eclipse.jface.preference.PreferencePage; @@ -74,6 +76,7 @@ import org.eclipse.ui.texteditor.WorkbenchChainedTextFontFieldEditor; public class PHPEditorPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { private static final String BOLD = PreferenceConstants.EDITOR_BOLD_SUFFIX; + private static final String COMPILER_TASK_TAGS = PHPCore.COMPILER_TASK_TAGS; public final OverlayPreferenceStore.OverlayKey[] fKeys = new OverlayPreferenceStore.OverlayKey[] { @@ -86,8 +89,8 @@ public class PHPEditorPreferencePage extends PreferencePage implements IWorkbenc new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_BOLD), new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_COLOR), new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_BOLD), - new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_JAVA_TAG_COLOR), - new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_JAVA_TAG_BOLD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_JAVA_TAG_COLOR), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_JAVA_TAG_BOLD), new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_JAVA_KEYWORD_COLOR), new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_JAVA_KEYWORD_BOLD), new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_PHP_FUNCTIONNAME_COLOR), @@ -211,8 +214,8 @@ public class PHPEditorPreferencePage extends PreferencePage implements IWorkbenc { PHPUIMessages.getString("PHPEditorPreferencePage.singleLineComment"), PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_COLOR }, //$NON-NLS-1$ { - PHPUIMessages.getString("PHPEditorPreferencePage.tags"), PreferenceConstants.EDITOR_JAVA_TAG_COLOR }, //$NON-NLS-1$ - { + PHPUIMessages.getString("PHPEditorPreferencePage.tags"), PreferenceConstants.EDITOR_JAVA_TAG_COLOR }, //$NON-NLS-1$ + { PHPUIMessages.getString("PHPEditorPreferencePage.keywords"), PreferenceConstants.EDITOR_JAVA_KEYWORD_COLOR }, //$NON-NLS-1$ { PHPUIMessages.getString("PHPEditorPreferencePage.functionNames"), PreferenceConstants.EDITOR_PHP_FUNCTIONNAME_COLOR }, //$NON-NLS-1$ @@ -539,8 +542,9 @@ public class PHPEditorPreferencePage extends PreferencePage implements IWorkbenc } private Control createPreviewer(Composite parent) { + Preferences coreStore = createTemporaryCorePreferenceStore(); - fJavaTextTools = new JavaTextTools(fOverlayStore); + fJavaTextTools = new JavaTextTools(fOverlayStore, coreStore, false); fPreviewViewer = new SourceViewer(parent, null, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER); fPreviewViewer.configure(new PHPSourceViewerConfiguration(fJavaTextTools, null)); @@ -551,7 +555,7 @@ public class PHPEditorPreferencePage extends PreferencePage implements IWorkbenc String content = loadPreviewContentFromFile("ColorSettingPreviewCode.txt"); //$NON-NLS-1$ IDocument document = new Document(content); - // PHPEditorEnvironment pe; + // PHPEditorEnvironment pe; IDocumentPartitioner partitioner = fJavaTextTools.createDocumentPartitioner(); partitioner.connect(document); document.setDocumentPartitioner(partitioner); @@ -572,7 +576,13 @@ public class PHPEditorPreferencePage extends PreferencePage implements IWorkbenc return fPreviewViewer.getControl(); } + private Preferences createTemporaryCorePreferenceStore() { + Preferences result = new Preferences(); + + result.setValue(COMPILER_TASK_TAGS, "TASK"); //$NON-NLS-1$ + return result; + } /** * Initializes the given viewer's colors. * @@ -741,11 +751,11 @@ public class PHPEditorPreferencePage extends PreferencePage implements IWorkbenc layout.numColumns = 2; composite.setLayout(layout); -// String text = "Analyse &problems while typing"; -// addCheckBox(composite, text, PreferenceConstants.EDITOR_EVALUTE_TEMPORARY_PROBLEMS, 0); -// -// text = PHPUIMessages.getString("PHPEditorPreferencePage.showQuickFixables"); //$NON-NLS-1$ -// addCheckBox(composite, text, PreferenceConstants.EDITOR_CORRECTION_INDICATION, 0); + // String text = "Analyse &problems while typing"; + // addCheckBox(composite, text, PreferenceConstants.EDITOR_EVALUTE_TEMPORARY_PROBLEMS, 0); + // + // text = PHPUIMessages.getString("PHPEditorPreferencePage.showQuickFixables"); //$NON-NLS-1$ + // addCheckBox(composite, text, PreferenceConstants.EDITOR_CORRECTION_INDICATION, 0); Label label = new Label(composite, SWT.LEFT); GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL); @@ -857,49 +867,50 @@ public class PHPEditorPreferencePage extends PreferencePage implements IWorkbenc return composite; } - private Control createBehaviourPage(Composite parent) { - Composite composite= new Composite(parent, SWT.NULL); - GridLayout layout= new GridLayout(); layout.numColumns= 2; - composite.setLayout(layout); - String label; -// String label= PHPUIMessages.getString("PHPEditorPreferencePage.wrapStrings"); //$NON-NLS-1$ -// addCheckBox(composite, label, PreferenceConstants.EDITOR_WRAP_STRINGS, 1); - -// label= PHPUIMessages.getString("PHPEditorPreferencePage.smartHomeEnd"); //$NON-NLS-1$ -// addCheckBox(composite, label, PreferenceConstants.EDITOR_SMART_HOME_END, 1); -// -// label= PHPUIMessages.getString("PHPEditorPreferencePage.smartPaste"); //$NON-NLS-1$ -// addCheckBox(composite, label, PreferenceConstants.EDITOR_SMART_PASTE, 1); - - label= PHPUIMessages.getString("PHPEditorPreferencePage.insertSpaceForTabs"); //$NON-NLS-1$ - addCheckBox(composite, label, PreferenceConstants.EDITOR_SPACES_FOR_TABS, 1); - - label= PHPUIMessages.getString("PHPEditorPreferencePage.closeStringsPHP"); //$NON-NLS-1$ - addCheckBox(composite, label, PreferenceConstants.EDITOR_CLOSE_STRINGS_PHP, 1); - - label= PHPUIMessages.getString("PHPEditorPreferencePage.closeBracketsPHP"); //$NON-NLS-1$ - addCheckBox(composite, label, PreferenceConstants.EDITOR_CLOSE_BRACKETS_PHP, 1); - -// label= PHPUIMessages.getString("PHPEditorPreferencePage.closeBraces"); //$NON-NLS-1$ -// addCheckBox(composite, label, PreferenceConstants.EDITOR_CLOSE_BRACES, 1); -// -// label= PHPUIMessages.getString("PHPEditorPreferencePage.closePHPDocs"); //$NON-NLS-1$ -// Button button= addCheckBox(composite, label, PreferenceConstants.EDITOR_CLOSE_JAVADOCS, 1); -// -// label= PHPUIMessages.getString("PHPEditorPreferencePage.addPHPDocTags"); //$NON-NLS-1$ -// fAddJavaDocTagsButton= addCheckBox(composite, label, PreferenceConstants.EDITOR_ADD_JAVADOC_TAGS, 1); -// createDependency(button, fAddJavaDocTagsButton); - -// label= PHPUIMessages.getString("PHPEditorPreferencePage.formatPHPDocs"); //$NON-NLS-1$ -// addCheckBox(composite, label, PreferenceConstants.EDITOR_FORMAT_JAVADOCS, 1); -// - label= PHPUIMessages.getString("PHPEditorPreferencePage.closeStringsHTML"); //$NON-NLS-1$ - addCheckBox(composite, label, PreferenceConstants.EDITOR_CLOSE_STRINGS_HTML, 1); - - label= PHPUIMessages.getString("PHPEditorPreferencePage.closeBracketsHTML"); //$NON-NLS-1$ - addCheckBox(composite, label, PreferenceConstants.EDITOR_CLOSE_BRACKETS_HTML, 1); - return composite; - } + private Control createBehaviourPage(Composite parent) { + Composite composite = new Composite(parent, SWT.NULL); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + composite.setLayout(layout); + String label; + // String label= PHPUIMessages.getString("PHPEditorPreferencePage.wrapStrings"); //$NON-NLS-1$ + // addCheckBox(composite, label, PreferenceConstants.EDITOR_WRAP_STRINGS, 1); + + // label= PHPUIMessages.getString("PHPEditorPreferencePage.smartHomeEnd"); //$NON-NLS-1$ + // addCheckBox(composite, label, PreferenceConstants.EDITOR_SMART_HOME_END, 1); + // + // label= PHPUIMessages.getString("PHPEditorPreferencePage.smartPaste"); //$NON-NLS-1$ + // addCheckBox(composite, label, PreferenceConstants.EDITOR_SMART_PASTE, 1); + + label = PHPUIMessages.getString("PHPEditorPreferencePage.insertSpaceForTabs"); //$NON-NLS-1$ + addCheckBox(composite, label, PreferenceConstants.EDITOR_SPACES_FOR_TABS, 1); + + label = PHPUIMessages.getString("PHPEditorPreferencePage.closeStringsPHP"); //$NON-NLS-1$ + addCheckBox(composite, label, PreferenceConstants.EDITOR_CLOSE_STRINGS_PHP, 1); + + label = PHPUIMessages.getString("PHPEditorPreferencePage.closeBracketsPHP"); //$NON-NLS-1$ + addCheckBox(composite, label, PreferenceConstants.EDITOR_CLOSE_BRACKETS_PHP, 1); + + // label= PHPUIMessages.getString("PHPEditorPreferencePage.closeBraces"); //$NON-NLS-1$ + // addCheckBox(composite, label, PreferenceConstants.EDITOR_CLOSE_BRACES, 1); + // + // label= PHPUIMessages.getString("PHPEditorPreferencePage.closePHPDocs"); //$NON-NLS-1$ + // Button button= addCheckBox(composite, label, PreferenceConstants.EDITOR_CLOSE_JAVADOCS, 1); + // + // label= PHPUIMessages.getString("PHPEditorPreferencePage.addPHPDocTags"); //$NON-NLS-1$ + // fAddJavaDocTagsButton= addCheckBox(composite, label, PreferenceConstants.EDITOR_ADD_JAVADOC_TAGS, 1); + // createDependency(button, fAddJavaDocTagsButton); + + // label= PHPUIMessages.getString("PHPEditorPreferencePage.formatPHPDocs"); //$NON-NLS-1$ + // addCheckBox(composite, label, PreferenceConstants.EDITOR_FORMAT_JAVADOCS, 1); + // + label = PHPUIMessages.getString("PHPEditorPreferencePage.closeStringsHTML"); //$NON-NLS-1$ + addCheckBox(composite, label, PreferenceConstants.EDITOR_CLOSE_STRINGS_HTML, 1); + + label = PHPUIMessages.getString("PHPEditorPreferencePage.closeBracketsHTML"); //$NON-NLS-1$ + addCheckBox(composite, label, PreferenceConstants.EDITOR_CLOSE_BRACKETS_HTML, 1); + return composite; + } private static void indent(Control control) { GridData gridData = new GridData(); @@ -926,28 +937,28 @@ public class PHPEditorPreferencePage extends PreferencePage implements IWorkbenc layout.numColumns = 2; contentAssistComposite.setLayout(layout); String label; -// String label = PHPUIMessages.getString("PHPEditorPreferencePage.insertSingleProposalsAutomatically"); //$NON-NLS-1$ -// addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_AUTOINSERT, 0); -// -// label = PHPUIMessages.getString("PHPEditorPreferencePage.showOnlyProposalsVisibleInTheInvocationContext"); //$NON-NLS-1$ -// addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_SHOW_VISIBLE_PROPOSALS, 0); -// -// label = PHPUIMessages.getString("PHPEditorPreferencePage.presentProposalsInAlphabeticalOrder"); //$NON-NLS-1$ -// addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_ORDER_PROPOSALS, 0); -// -// label = PHPUIMessages.getString("PHPEditorPreferencePage.automaticallyAddImportInsteadOfQualifiedName"); //$NON-NLS-1$ -// addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_ADDIMPORT, 0); -// -// label = PHPUIMessages.getString("PHPEditorPreferencePage.insertCompletion"); //$NON-NLS-1$ -// addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_INSERT_COMPLETION, 0); -// -// label = PHPUIMessages.getString("PHPEditorPreferencePage.fillArgumentNamesOnMethodCompletion"); //$NON-NLS-1$ -// Button button = addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES, 0); -// -// label = PHPUIMessages.getString("PHPEditorPreferencePage.guessArgumentNamesOnMethodCompletion"); //$NON-NLS-1$ -// fGuessMethodArgumentsButton = -// addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_GUESS_METHOD_ARGUMENTS, 0); -// createDependency(button, fGuessMethodArgumentsButton); + // String label = PHPUIMessages.getString("PHPEditorPreferencePage.insertSingleProposalsAutomatically"); //$NON-NLS-1$ + // addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_AUTOINSERT, 0); + // + // label = PHPUIMessages.getString("PHPEditorPreferencePage.showOnlyProposalsVisibleInTheInvocationContext"); //$NON-NLS-1$ + // addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_SHOW_VISIBLE_PROPOSALS, 0); + // + // label = PHPUIMessages.getString("PHPEditorPreferencePage.presentProposalsInAlphabeticalOrder"); //$NON-NLS-1$ + // addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_ORDER_PROPOSALS, 0); + // + // label = PHPUIMessages.getString("PHPEditorPreferencePage.automaticallyAddImportInsteadOfQualifiedName"); //$NON-NLS-1$ + // addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_ADDIMPORT, 0); + // + // label = PHPUIMessages.getString("PHPEditorPreferencePage.insertCompletion"); //$NON-NLS-1$ + // addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_INSERT_COMPLETION, 0); + // + // label = PHPUIMessages.getString("PHPEditorPreferencePage.fillArgumentNamesOnMethodCompletion"); //$NON-NLS-1$ + // Button button = addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES, 0); + // + // label = PHPUIMessages.getString("PHPEditorPreferencePage.guessArgumentNamesOnMethodCompletion"); //$NON-NLS-1$ + // fGuessMethodArgumentsButton = + // addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_GUESS_METHOD_ARGUMENTS, 0); + // createDependency(button, fGuessMethodArgumentsButton); label = PHPUIMessages.getString("PHPEditorPreferencePage.enableAutoActivation"); //$NON-NLS-1$ final Button autoactivation = addCheckBox(contentAssistComposite, label, PreferenceConstants.CODEASSIST_AUTOACTIVATION, 0); @@ -1022,9 +1033,9 @@ public class PHPEditorPreferencePage extends PreferencePage implements IWorkbenc item.setText(PHPUIMessages.getString("PHPEditorPreferencePage.problemIndicationTab.title")); //$NON-NLS-1$ item.setControl(createProblemIndicationPage(folder)); - item= new TabItem(folder, SWT.NONE); - item.setText(PHPUIMessages.getString("PHPEditorPreferencePage.behaviourTab.title")); //$NON-NLS-1$ - item.setControl(createBehaviourPage(folder)); + item = new TabItem(folder, SWT.NONE); + item.setText(PHPUIMessages.getString("PHPEditorPreferencePage.behaviourTab.title")); //$NON-NLS-1$ + item.setControl(createBehaviourPage(folder)); // item= new TabItem(folder, SWT.NONE); // item.setText(PHPUIMessages.getString("PHPEditorPreferencePage.hoverTab.title")); //$NON-NLS-1$ @@ -1113,11 +1124,11 @@ public class PHPEditorPreferencePage extends PreferencePage implements IWorkbenc fBackgroundCustomRadioButton.setSelection(!default_); fBackgroundColorButton.setEnabled(!default_); -// boolean closeJavaDocs= fOverlayStore.getBoolean(PreferenceConstants.EDITOR_CLOSE_JAVADOCS); -// fAddJavaDocTagsButton.setEnabled(closeJavaDocs); + // boolean closeJavaDocs= fOverlayStore.getBoolean(PreferenceConstants.EDITOR_CLOSE_JAVADOCS); + // fAddJavaDocTagsButton.setEnabled(closeJavaDocs); -// boolean fillMethodArguments = fOverlayStore.getBoolean(PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES); -// fGuessMethodArgumentsButton.setEnabled(fillMethodArguments); + // boolean fillMethodArguments = fOverlayStore.getBoolean(PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES); + // fGuessMethodArgumentsButton.setEnabled(fillMethodArguments); updateAutoactivationControls(); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PreferencesMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PreferencesMessages.java new file mode 100644 index 0000000..5d0fbf6 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PreferencesMessages.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.preferences; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class PreferencesMessages { + + private static final String RESOURCE_BUNDLE= "org.eclipse.jdt.internal.ui.preferences.PreferencesMessages";//$NON-NLS-1$ + + private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + private PreferencesMessages() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } + + public static String getFormattedString(String key, String arg) { + return getFormattedString(key, new String[] { arg }); + } + + public static String getFormattedString(String key, String[] args) { + return MessageFormat.format(getString(key), args); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PreferencesMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PreferencesMessages.properties new file mode 100644 index 0000000..8f19d46 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PreferencesMessages.properties @@ -0,0 +1,500 @@ +############################################################################### +# Copyright (c) 2000, 2003 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Common Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/cpl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### + +BuildPathsPropertyPage.error.message=An error occurred while setting the build path +BuildPathsPropertyPage.error.title=Error Setting Build Path +BuildPathsPropertyPage.no_java_project.message=Not a Java project. +BuildPathsPropertyPage.closed_project.message=Java information is not available for a closed project. + +ClasspathVariablesPreferencePage.title=Classpath Variables +ClasspathVariablesPreferencePage.description=A classpath variable can be added to a project's class path. It can be used to define the location of a JAR file that isn't part of the workspace. The reserved class path variables JRE_LIB, JRE_SRC, JRE_SRCROOT are set internally depending on the JRE setting. + +ImportOrganizePreferencePage.description=Preferences used by the Organize Imports action: + +ImportOrganizePreferencePage.order.label=Define the &sorting order of import statements. A package name prefix (e.g. org.eclipse) is a valid entry. + +ImportOrganizePreferencePage.order.add.button=&New.. +ImportOrganizePreferencePage.order.edit.button=&Edit... +ImportOrganizePreferencePage.order.up.button=&Up +ImportOrganizePreferencePage.order.down.button=Do&wn +ImportOrganizePreferencePage.order.remove.button=&Remove +ImportOrganizePreferencePage.order.load.button=&Load... +ImportOrganizePreferencePage.order.save.button=Sa&ve... +ImportOrganizePreferencePage.ignoreLowerCase.label=Do not create imports for &types starting with a lowercase letter + +ImportOrganizePreferencePage.threshold.label=Number of &imports needed for .* (e.g. org.eclipse.*): +ImportOrganizePreferencePage.error.invalidthreshold=Invalid import number. + +ImportOrganizePreferencePage.loadDialog.title=Load Import Order from File +ImportOrganizePreferencePage.loadDialog.error.title=Load Import Order +ImportOrganizePreferencePage.loadDialog.error.message=Loading failed. Not a valid import order file. + +ImportOrganizePreferencePage.saveDialog.title=Save Import Order to File +ImportOrganizePreferencePage.saveDialog.error.title=Save Import Order +ImportOrganizePreferencePage.saveDialog.error.message=Writing import order file failed. + + +ImportOrganizeInputDialog.title=Import Order Entry +ImportOrganizeInputDialog.message=&Package name or package name prefix: +ImportOrganizeInputDialog.browse.button=&Browse... +ImportOrganizeInputDialog.ChoosePackageDialog.title=Package Selection +ImportOrganizeInputDialog.ChoosePackageDialog.description=Choose package name or package prefix: +ImportOrganizeInputDialog.ChoosePackageDialog.empty=No packages available. +ImportOrganizeInputDialog.error.enterName=Enter a package name. +ImportOrganizeInputDialog.error.invalidName=Not a valid package name. {0} +ImportOrganizeInputDialog.error.entryExists=Package name already exists in list. + +JavaBasePreferencePage.description=General settings for Java development: + +JavaBasePreferencePage.updateJavaViews=Update Java views +JavaBasePreferencePage.onSave=On &save only +JavaBasePreferencePage.whileEditing=While &editing +JavaBasePreferencePage.notice.outliner=Note: This preference is not applied to already opened views (Outline view is always updated while editing) + +JavaBasePreferencePage.openTypeHierarchy=When opening a Type Hierarchy +JavaBasePreferencePage.inPerspective=Open a new Type Hierarchy &Perspective +JavaBasePreferencePage.inView=Show the &Type Hierarchy View in the current perspective +JavaBasePreferencePage.doubleclick.action=Action on double click in the Package Explorer +JavaBasePreferencePage.doubleclick.gointo=&Go into the selected element +JavaBasePreferencePage.doubleclick.expand=E&xpand the selected element + +NewJavaProjectPreferencePage.description=Specify the classpath entries used as default by the New Java Project creation wizard: + +NewJavaProjectPreferencePage.sourcefolder.label=Source and output folder +NewJavaProjectPreferencePage.sourcefolder.project=&Project +NewJavaProjectPreferencePage.sourcefolder.folder=&Folders +NewJavaProjectPreferencePage.folders.src=&Source folder name: +NewJavaProjectPreferencePage.folders.bin=&Output folder name: + +NewJavaProjectPreferencePage.jrelibrary.label=As &JRE library use: +NewJavaProjectPreferencePage.jre_variable.description=JRE_LIB variable +NewJavaProjectPreferencePage.jre_container.description=JRE container + +NewJavaProjectPreferencePage.folders.error.namesempty=Enter folder names. +NewJavaProjectPreferencePage.folders.error.invalidsrcname=Invalid source folder name: {0} +NewJavaProjectPreferencePage.folders.error.invalidbinname=Invalid output folder name: {0} +NewJavaProjectPreferencePage.folders.error.invalidcp=Settings will result in an invalid build path. Check for nested folders. + +NewJavaProjectPreferencePage.error.decode=Error while decoding JRE entry + +JavaEditorPreferencePage.annotationsTab.title= Annotation&s +JavaEditorPreferencePage.showQuickFixables= Indicate annotations solvable with &Quick Fix in vertical ruler +JavaEditorPreferencePage.analyseAnnotationsWhileTyping= Analyze annotations &while typing +JavaEditorPreferencePage.annotationPresentationOptions= Annotation &presentation: +JavaEditorPreferencePage.description=Java Editor settings: +JavaEditorPreferencePage.annotations.bookmarks= Bookmarks +JavaEditorPreferencePage.annotations.searchResults= Search Results +JavaEditorPreferencePage.annotations.errors= Errors +JavaEditorPreferencePage.annotations.warnings= Warnings +JavaEditorPreferencePage.annotations.tasks= Tasks +JavaEditorPreferencePage.annotations.others= Others +JavaEditorPreferencePage.annotations.showInText= Show in &text +JavaEditorPreferencePage.annotations.showInOverviewRuler= Show in overview &ruler +JavaEditorPreferencePage.annotations.color= C&olor: +JavaEditorPreferencePage.multiLineComment=Multi-line comment +JavaEditorPreferencePage.singleLineComment=Single-line comment +JavaEditorPreferencePage.keywords=Keywords +JavaEditorPreferencePage.strings=Strings +JavaEditorPreferencePage.others=Others +JavaEditorPreferencePage.javaCommentTaskTags=Task Tags +JavaEditorPreferencePage.javaDocKeywords=Javadoc keywords +JavaEditorPreferencePage.javaDocHtmlTags=Javadoc HTML tags +JavaEditorPreferencePage.javaDocLinks=Javadoc links +JavaEditorPreferencePage.javaDocOthers=Javadoc others +JavaEditorPreferencePage.backgroundColor=Background color +JavaEditorPreferencePage.systemDefault=S&ystem Default +JavaEditorPreferencePage.custom=C&ustom: +JavaEditorPreferencePage.foreground=Fo®round: +JavaEditorPreferencePage.color=C&olor: +JavaEditorPreferencePage.bold=&Bold +JavaEditorPreferencePage.preview=Preview: +JavaEditorPreferencePage.displayedTabWidth=Displayed &tab width: +JavaEditorPreferencePage.insertSpaceForTabs=Ins&ert space for tabs (see Code Formatter preference page) +JavaEditorPreferencePage.showOverviewRuler=Show overview &ruler +JavaEditorPreferencePage.highlightMatchingBrackets=Highlight &matching brackets +JavaEditorPreferencePage.highlightCurrentLine=Hi&ghlight current line +JavaEditorPreferencePage.showPrintMargin=Sho&w print margin +JavaEditorPreferencePage.printMarginColumn=Print margin col&umn: +JavaEditorPreferencePage.insertSingleProposalsAutomatically=Insert single &proposals automatically +JavaEditorPreferencePage.showOnlyProposalsVisibleInTheInvocationContext=Show only proposals &visible in the invocation context +JavaEditorPreferencePage.presentProposalsInAlphabeticalOrder=Present proposals in a&lphabetical order +JavaEditorPreferencePage.enableAutoActivation=&Enable auto activation +JavaEditorPreferencePage.automaticallyAddImportInsteadOfQualifiedName=Automatically add import instead of &qualified name +JavaEditorPreferencePage.completionInserts=Completion inser&ts +JavaEditorPreferencePage.completionOverwrites=Completion over&writes +JavaEditorPreferencePage.fillArgumentNamesOnMethodCompletion=&Fill argument names on method completion +JavaEditorPreferencePage.guessArgumentNamesOnMethodCompletion=&Guess filled argument names +JavaEditorPreferencePage.autoActivationDelay=Auto activation dela&y: +JavaEditorPreferencePage.autoActivationTriggersForJava=Auto activation &triggers for Java: +JavaEditorPreferencePage.autoActivationTriggersForJavaDoc=Auto activation triggers for &Javadoc: + +JavaEditorPreferencePage.codeAssist.colorOptions= Code assist colo&r options: +JavaEditorPreferencePage.codeAssist.color= C&olor: +JavaEditorPreferencePage.backgroundForCompletionProposals= Completion proposal background +JavaEditorPreferencePage.foregroundForCompletionProposals= Completion proposal foreground +JavaEditorPreferencePage.backgroundForMethodParameters= Method parameter background +JavaEditorPreferencePage.foregroundForMethodParameters= Method parameter foreground +JavaEditorPreferencePage.backgroundForCompletionReplacement= Completion overwrite background +JavaEditorPreferencePage.foregroundForCompletionReplacement= Completion overwrite foreground + +JavaEditorPreferencePage.general=Appeara&nce +JavaEditorPreferencePage.colors=Synta&x +JavaEditorPreferencePage.codeAssist= &Code Assist +JavaEditorPreferencePage.empty_input=Empty input +JavaEditorPreferencePage.invalid_input=''{0}'' is not a valid input. +JavaEditorPreferencePage.showLineNumbers=Show lin&e numbers +JavaEditorPreferencePage.lineNumberForegroundColor=Line number foreground +JavaEditorPreferencePage.matchingBracketsHighlightColor2=Matching brackets highlight +JavaEditorPreferencePage.currentLineHighlighColor=Current line highlight +JavaEditorPreferencePage.printMarginColor2=Print margin +JavaEditorPreferencePage.findScopeColor2=Find scope +JavaEditorPreferencePage.linkedPositionColor2=Linked position +JavaEditorPreferencePage.linkColor2=Link +JavaEditorPreferencePage.synchronizeOnCursor=Synchroni&ze outline selection on cursor move (editor must be reopened) +JavaEditorPreferencePage.appearanceOptions=Appearance co&lor options: + +JavaEditorPreferencePage.typing.tabTitle= T&yping +JavaEditorPreferencePage.typing.description= Select options for automatic text modifications +JavaEditorPreferencePage.closeStrings= Close strin&gs +JavaEditorPreferencePage.closeBrackets= Close &brackets and parenthesis +JavaEditorPreferencePage.closeBraces= Cl&ose braces +JavaEditorPreferencePage.closeJavaDocs= Close Java&docs and comments +JavaEditorPreferencePage.wrapStrings= &Wrap Java strings +JavaEditorPreferencePage.addJavaDocTags= Add Javadoc &tags +JavaEditorPreferencePage.smartPaste= Pasting fo&r correct indentation + +JavaEditorPreferencePage.smartHomeEnd= S&mart cursor positioning at line start and end + +JavaEditorPreferencePage.hoverTab.title= Ho&vers + +JavaEditorPreferencePage.navigationTab.title= Nav&igation +JavaEditorPreferencePage.navigation.browserLikeLinks= S&upport hyperlink style navigation for "Open Declaration" +JavaEditorPreferencePage.navigation.browserLikeLinksKeyModifier= Hyperlink style navigation key &modifier: +JavaEditorPreferencePage.navigation.modifierIsNotValid= Modifier ''{0}'' is not valid. +JavaEditorPreferencePage.navigation.shiftIsDisabled= The modifier 'Shift' is not allowed because 'Shift' + click sets a new selection. + +JavaEditorPreferencePage.navigation.delimiter= + +JavaEditorPreferencePage.navigation.insertDelimiterAndModifierAndDelimiter= \ + {0} + +JavaEditorPreferencePage.navigation.insertModifierAndDelimiter= \ {0} + +JavaEditorPreferencePage.navigation.insertDelimiterAndModifier= \ + {0} + +JavaEditorHoverConfigurationBlock.hoverPreferences= &Hover key modifier preferences: +JavaEditorHoverConfigurationBlock.enabled= &Enabled +JavaEditorHoverConfigurationBlock.keyModifier= Key &Modifier: +JavaEditorHoverConfigurationBlock.description= Description: +JavaEditorHoverConfigurationBlock.modifierIsNotValid= Modifier ''{0}'' is not valid. +JavaEditorHoverConfigurationBlock.modifierIsNotValidForHover= Modifier ''{0}'' for ''{1}'' hover is not valid. +JavaEditorHoverConfigurationBlock.duplicateModifier= ''{0}'' hover uses the same modifier as ''{1}'' hover. + +JavaEditorHoverConfigurationBlock.delimiter= + +JavaEditorHoverConfigurationBlock.insertDelimiterAndModifierAndDelimiter= \ + {0} + +JavaEditorHoverConfigurationBlock.insertModifierAndDelimiter= \ {0} + +JavaEditorHoverConfigurationBlock.insertDelimiterAndModifier= \ + {0} + +JavaElementInfoPage.binary=binary +JavaElementInfoPage.classpath_entry_kind=Classpath entry kind: +JavaElementInfoPage.library=library +JavaElementInfoPage.nameLabel=Name: +JavaElementInfoPage.not_present=not present +JavaElementInfoPage.package=Package: +JavaElementInfoPage.package_contents=Package contents: +JavaElementInfoPage.project=project +JavaElementInfoPage.resource_path=Resource path: +JavaElementInfoPage.source=source +JavaElementInfoPage.variable=variable +JavaElementInfoPage.variable_path=Variable path: +JavaElementInfoPage.location=Location: + +JavadocConfigurationPropertyPage.IsPackageFragmentRoot.description=Specify the location (URL) of the documentation generated by Javadoc. The Javadoc location will contain a file called 'package-list'. For example: \'http://www.sample-url.org/doc/\' +JavadocConfigurationPropertyPage.IsIncorrectElement.description=Javadoc location can only be attached to Java projects or JAR files in Java projects +JavadocConfigurationPropertyPage.IsJavaProject.description=Specify the location (URL) of the project\'s Javadoc documentation. This location is used by the Javadoc export wizard as default value and by the \'Open External Javadoc\' action. For example: \'file://c:/myworkspace/myproject/doc/\'. + +JavadocConfigurationBlock.location.label=Javadoc &location: +JavadocConfigurationBlock.location.button=Bro&wse... + +JavadocConfigurationBlock.error.notafolder=Location does not exist. +JavadocConfigurationBlock.warning.packagelistnotfound=Location does not contain file 'package-list'. + +JavadocConfigurationBlock.javadocLocationDialog.label=Javadoc Location Selection +JavadocConfigurationBlock.javadocLocationDialog.message=&Select Javadoc location: + +JavadocConfigurationBlock.MalformedURL.error=Invalid URL + +JavadocConfigurationBlock.ValidateButton.label=&Validate... +JavadocConfigurationBlock.InvalidLocation.message= Location is invalid. Location contains neither the file \'package-list\' nor \'index.html'. +JavadocConfigurationBlock.ValidLocation.message= Location is valid. Files \'package-list\' and \'index.html\' found. Click OK to open in browser. +JavadocConfigurationBlock.UnableToValidateLocation.message=Unable to validate location +JavadocConfigurationBlock.MessageDialog.title=Validating Javadoc Location + +JavadocPreferencePage.description=Specify the location of the Javadoc command to be used by the Javadoc export wizard. Location must be an absolute path. +JavadocPreferencePage.command.label=&Javadoc command: +JavadocPreferencePage.command.button=Bro&wse... + +JavadocPreferencePage.error.notexists=Javadoc command does not exist + +JavadocPreferencePage.browsedialog.title=Javadoc Command Selection + +MembersOrderPreferencePage.button.up=U&p +MembersOrderPreferencePage.button.down=Do&wn +MembersOrderPreferencePage.label.description=&Choose the order in which members will be displayed. The order is also used by the 'Sort Members' action. + +SourceAttachmentPropertyPage.error.title=Error Attaching Source +SourceAttachmentPropertyPage.error.message=An error occurred while associating the source + +SourceAttachmentPropertyPage.noarchive.message=Source can only be attached to JAR files in Java projects. +SourceAttachmentPropertyPage.containerentry.message=JAR belongs to the container ''{0}''.\nTo configure the source attachment, go directly to the corresponding configuration page (For example for JREs go to ''Installed JREs'' page in the preferences). + +AppearancePreferencePage.description= Appearance of Java elements in viewers: +AppearancePreferencePage.methodreturntype.label= Show &method return types +AppearancePreferencePage.overrideindicator.label= Show &override indicators in outline and hierarchy +AppearancePreferencePage.pkgNamePatternEnable.label= &Compress all package name segments, except the final segment +AppearancePreferencePage.pkgNamePattern.label= Com&pression pattern (e.g. given package name 'org.eclipse.jdt' pattern '.' will compress it to '..jdt', '0' to 'jdt', '1~.' to 'o~.e~.jdt'): +AppearancePreferencePage.showMembersInPackagesView=S&how members in Package Explorer +AppearancePreferencePage.stackViewsVerticallyInTheJavaBrowsingPerspective=&Stack views vertically in the Java Browsing perspective +AppearancePreferencePage.preferenceOnlyEffectiveForNewPerspectives=Note: This preference will only take effect on new perspectives +AppearancePreferencePage.packageNameCompressionPattern.error.isEmpty=Enter a package name compression pattern +AppearancePreferencePage.foldEmptyPackages= &Fold empty packages in hierarchical Package Explorer layout + +CodeFormatterPreferencePage.title=Code Formatter +CodeFormatterPreferencePage.description=Options for the Java Code Formatter: + +CodeFormatterPreferencePage.empty_input=Empty input +CodeFormatterPreferencePage.invalid_input=''{0}'' is not a valid input. + +CodeFormatterPreferencePage.newline_opening_braces.label=I&nsert a new line before an opening brace +CodeFormatterPreferencePage.newline_control_statement.label=Insert new &lines in control statements +CodeFormatterPreferencePage.newline_clear_lines=Clear all &blank lines +CodeFormatterPreferencePage.newline_else_if.label=&Insert new line between 'else if' +CodeFormatterPreferencePage.newline_empty_block.label=In&sert a new line inside an empty block +CodeFormatterPreferencePage.split_line.label=Ma&ximum line length: +CodeFormatterPreferencePage.style_compact_assignement.label=&Compact assignment +CodeFormatterPreferencePage.style_space_castexpression.label=Insert sp&ace after a cast +CodeFormatterPreferencePage.tab_char.label=Insert &tabs for indentation, not spaces +CodeFormatterPreferencePage.tab_size.label=&Number of spaces representing an indentation level: + +CodeFormatterPreferencePage.tab.newline.tabtitle=Ne&w Lines +CodeFormatterPreferencePage.tab.linesplit.tabtitle=Line S&plitting +CodeFormatterPreferencePage.tab.style.tabtitle=St&yle + +TodoTaskPreferencePage.title=Task Tags + +TodoTaskPropertyPage.useworkspacesettings.label=Use &workspace settings +TodoTaskPropertyPage.useworkspacesettings.change=&Configure Workspace Settings... +TodoTaskPropertyPage.useprojectsettings.label=Use pr&oject settings + +TodoTaskConfigurationBlock.markers.tasks.high.priority=High +TodoTaskConfigurationBlock.markers.tasks.normal.priority=Normal +TodoTaskConfigurationBlock.markers.tasks.low.priority=Low +TodoTaskConfigurationBlock.markers.tasks.label=&Strings indicating tasks in Java comments: +TodoTaskConfigurationBlock.markers.tasks.add.button=Ne&w... +TodoTaskConfigurationBlock.markers.tasks.remove.button=Remo&ve +TodoTaskConfigurationBlock.markers.tasks.edit.button=Edi&t... +TodoTaskConfigurationBlock.markers.tasks.name.column=Tag +TodoTaskConfigurationBlock.markers.tasks.priority.column=Priority + +TodoTaskConfigurationBlock.needsbuild.title=Task Tags Settings Changed +TodoTaskConfigurationBlock.needsfullbuild.message=The task tags settings have changed. A full rebuild is required to make changes effective. Do the full build now? +TodoTaskConfigurationBlock.needsprojectbuild.message=The task tags settings have changed. A rebuild of the project is required to make changes effective. Do the project build now? + +TodoTaskInputDialog.new.title=New Task Tag +TodoTaskInputDialog.edit.title=Edit Task Tag +TodoTaskInputDialog.name.label=T&ag: +TodoTaskInputDialog.priority.label=&Priority: +TodoTaskInputDialog.priority.high=High +TodoTaskInputDialog.priority.normal=Normal +TodoTaskInputDialog.priority.low=Low +TodoTaskInputDialog.error.enterName=Enter task tag name. +TodoTaskInputDialog.error.comma=Name cannot contain a comma. +TodoTaskInputDialog.error.entryExists=Entry with the same name already exists. +TodoTaskInputDialog.error.noSpace=Name can not start or end with a whitespace. + +CompilerPreferencePage.title=Compiler +CompilerPreferencePage.description=Options for the Java compiler:\nNote that a full rebuild is required to make changes effective. + +CompilerPropertyPage.useworkspacesettings.label=Use &workspace settings +CompilerPropertyPage.useworkspacesettings.change=&Configure Workspace Settings... +CompilerPropertyPage.useprojectsettings.label=Use pr&oject settings + +CompilerConfigurationBlock.style.tabtitle=&Style +CompilerConfigurationBlock.problems.tabtitle=&Problems +CompilerConfigurationBlock.compliance.tabtitle=&Compliance and Classfiles +CompilerConfigurationBlock.others.tabtitle=&Build Path + +CompilerConfigurationBlock.style.description=Select the severity level for the following problems: +CompilerConfigurationBlock.problems.description=Select the severity level for the following problems: +CompilerConfigurationBlock.build_warnings.description=Select the severity level for the following build path problems: + +CompilerConfigurationBlock.variable_attr.label=Add &variable attributes to generated class files (used by the debugger) +CompilerConfigurationBlock.line_number_attr.label=Add &line number attributes to generated class files (used by the debugger) +CompilerConfigurationBlock.source_file_attr.label=Add source &file name to generated class file (used by the debugger) +CompilerConfigurationBlock.codegen_unused_local.label=Pr&eserve unused local variables (i.e. never read) + +CompilerConfigurationBlock.compiler_compliance.label=C&ompiler compliance level: +CompilerConfigurationBlock.default_settings.label=&Use default compliance settings +CompilerConfigurationBlock.source_compatibility.label=Source co&mpatibility: +CompilerConfigurationBlock.codegen_targetplatform.label=Ge&nerated .class files compatibility: +CompilerConfigurationBlock.pb_assert_as_identifier.label=&Report 'assert' as identifier: + +CompilerConfigurationBlock.compliance.group.label=JDK Compliance +CompilerConfigurationBlock.classfiles.group.label=Classfile Generation + +CompilerConfigurationBlock.pb_unreachable_code.label=&Unreachable code: +CompilerConfigurationBlock.pb_invalid_import.label=Unresol&vable import statements: +CompilerConfigurationBlock.pb_overriding_pkg_dflt.label=&Methods overridden but not package visible: +CompilerConfigurationBlock.pb_method_naming.label=Me&thods with a constructor name: +CompilerConfigurationBlock.pb_no_effect_assignment.label=Assignment has no &effect (e.g. 'x = x'): +CompilerConfigurationBlock.pb_incompatible_interface_method.label=Conflict of interface method &with protected 'Object' method: + + +CompilerConfigurationBlock.pb_hidden_catchblock.label=&Hidden catch blocks: +CompilerConfigurationBlock.pb_static_access_receiver.label=Non-stat&ic access to static member +CompilerConfigurationBlock.pb_unused_imports.label=Unus&ed imports: +CompilerConfigurationBlock.pb_unused_local.label=Unused &local variables (i.e. never read): +CompilerConfigurationBlock.pb_unused_parameter.label=U&nused parameters (i.e. never read): +CompilerConfigurationBlock.pb_unused_private.label=Unused private &types, methods or fields: +CompilerConfigurationBlock.pb_non_externalized_strings.label=Usage of non-e&xternalized strings: +CompilerConfigurationBlock.pb_deprecation.label=Usa&ge of deprecated API: +CompilerConfigurationBlock.pb_deprecation_in_deprecation.label=Signal use &of deprecated API inside deprecated code. + +CompilerConfigurationBlock.pb_synth_access_emul.label=Access to a &non-accessible member of an enclosing type: +CompilerConfigurationBlock.pb_char_array_in_concat.label=&Using a char array in string concatenation: +CompilerConfigurationBlock.pb_incomplete_build_path.label=&Incomplete build path: +CompilerConfigurationBlock.pb_build_path_cycles.label=Circular d&ependencies: +CompilerConfigurationBlock.pb_duplicate_resources.label=D&uplicated resources: +CompilerConfigurationBlock.pb_max_per_unit.label=Ma&ximum number of problems reported per compilation unit: + + +CompilerConfigurationBlock.resource_filter.description=Enter resources and resource types that should not be copied to the output folder during a build. List is comma separated (e.g. '*.doc, plugin.xml, scripts/') +CompilerConfigurationBlock.resource_filter.label=Filtered &Resources: +CompilerConfigurationBlock.build_invalid_classpath.label=Ab&ort building on build path errors +CompilerConfigurationBlock.build_clean_outputfolder.label=Scrub output folders o&n full build +CompilerConfigurationBlock.enable_exclusion_patterns.label=Enable using e&xclusion patterns in source folders +CompilerConfigurationBlock.enable_multiple_outputlocations.label=Enable using &multiple output locations for source folders + +CompilerConfigurationBlock.error=Error +CompilerConfigurationBlock.warning=Warning +CompilerConfigurationBlock.ignore=Ignore + +CompilerConfigurationBlock.version11=1.1 +CompilerConfigurationBlock.version12=1.2 +CompilerConfigurationBlock.version13=1.3 +CompilerConfigurationBlock.version14=1.4 + +CompilerConfigurationBlock.needsbuild.title=Compiler Settings Changed +CompilerConfigurationBlock.needsfullbuild.message=The compiler settings have changed. A full rebuild is required to make changes effective. Do the full build now? +CompilerConfigurationBlock.needsprojectbuild.message=The compiler settings have changed. A rebuild of the project is required to make changes effective. Do the project build now? + +CompilerConfigurationBlock.cpl13src14.error=In 1.3 compliance level, source compatibility can not be 1.4 +CompilerConfigurationBlock.cpl13trg14.error=In 1.3 compliance level, the classfile compatibility can not be 1.4 +CompilerConfigurationBlock.src14asrterr.error=When source compatibility is 1.4, 'assert' cannot be an identifier. +CompilerConfigurationBlock.src14tgt14.error=When source compatibility is 1.4, the classfile compatibility has to be 1.4. + +CompilerConfigurationBlock.empty_input=Number of problems can not be empty. +CompilerConfigurationBlock.invalid_input={0} is not a valid number of problems. + +CompilerConfigurationBlock.filter.invalidsegment.error=Filter is invalid: {0} + +OptionsConfigurationBlock.builderror.title=Preference Changes +OptionsConfigurationBlock.builderror.message=Problem while building. Check log for details. + +OptionsConfigurationBlock.buildall.taskname=Build all... +OptionsConfigurationBlock.buildproject.taskname=Build project ''{0}''... + +CodeGenerationPreferencePage.title=&Code Generation +CodeGenerationPreferencePage.description=Options for Code Generation: + +CodeGenerationPreferencePage.tab.names.tabtitle=&Names +CodeGenerationPreferencePage.tab.templates.tabtitle=&Code and Comments + +NameConventionConfigurationBlock.field.label=Fields +NameConventionConfigurationBlock.static.label=Static Fields +NameConventionConfigurationBlock.arg.label=Parameters +NameConventionConfigurationBlock.local.label=Local Variables + +NameConventionConfigurationBlock.dialog.prefix=P&refix list: +NameConventionConfigurationBlock.dialog.suffix=S&uffix list: + +NameConventionConfigurationBlock.error.emptyprefix=Prefix strings can not contain an empty entry. +NameConventionConfigurationBlock.error.emptysuffix=Suffix strings can not contain an empty entry. +NameConventionConfigurationBlock.error.invalidprefix={0} is not a valid prefix. +NameConventionConfigurationBlock.error.invalidsuffix={0} is not a valid suffix. + +NameConventionConfigurationBlock.list.label=C&onventions for variable names: +NameConventionConfigurationBlock.list.edit.button=&Edit... +NameConventionConfigurationBlock.list.name.column=Variable type +NameConventionConfigurationBlock.list.prefix.column=Prefix list +NameConventionConfigurationBlock.list.suffix.column=Suffix list + +NameConventionConfigurationBlock.field.dialog.title=Field Name Conventions +NameConventionConfigurationBlock.field.dialog.message=Specify prefix and suffix to be used for fields (comma separated): + +NameConventionConfigurationBlock.static.dialog.title=Static Field Name Conventions +NameConventionConfigurationBlock.static.dialog.message=Specify prefix and suffix to be used for static fields (comma separated): + +NameConventionConfigurationBlock.arg.dialog.title=Parameter Name Conventions +NameConventionConfigurationBlock.arg.dialog.message=Specify prefix and suffix to be used for parameters (comma separated): + +NameConventionConfigurationBlock.local.dialog.title=Local Variable Name Conventions +NameConventionConfigurationBlock.local.dialog.message=Specify prefix and suffix to be used for local variables (comma separated): + +MembersOrderPreferencePage.fields.label=Fields +MembersOrderPreferencePage.constructors.label=Constructors +MembersOrderPreferencePage.methods.label=Methods +MembersOrderPreferencePage.staticfields.label=Static Fields +MembersOrderPreferencePage.staticmethods.label=Static Methods +MembersOrderPreferencePage.initialisers.label=Initializers +MembersOrderPreferencePage.staticinitialisers.label=Static Initializers +MembersOrderPreferencePage.types.label=Types + +CodeTemplateBlock.templates.comment.node=Comments +CodeTemplateBlock.templates.code.node=Code + +CodeTemplateBlock.catchblock.label=Catch block body +CodeTemplateBlock.methodstub.label=Method body +CodeTemplateBlock.constructorstub.label=Constructor body +CodeTemplateBlock.newtype.label=New Java files +CodeTemplateBlock.typecomment.label=Types +CodeTemplateBlock.methodcomment.label=Methods +CodeTemplateBlock.overridecomment.label=Overriding methods +CodeTemplateBlock.constructorcomment.label=Constructors + +CodeTemplateBlock.templates.edit.button=&Edit... +CodeTemplateBlock.templates.import.button=&Import... +CodeTemplateBlock.templates.export.button=E&xport... +CodeTemplateBlock.templates.exportall.button=Ex&port All... + +CodeTemplateBlock.createcomment.label=A&utomatically add comments for new methods and types +CodeTemplateBlock.createcomment.description=(does not apply to comments contained in the code patterns) +CodeTemplateBlock.templates.label=C&onfigure generated code and comments: +CodeTemplateBlock.preview=Pa&ttern: + +CodeTemplateBlock.import.title=Importing Templates +CodeTemplateBlock.import.extension=*.xml + +CodeTemplateBlock.export.title=Exporting {0} Code Template(s) +CodeTemplateBlock.export.filename=codetemplates.xml +CodeTemplateBlock.export.extension=*.xml + +CodeTemplateBlock.export.exists.title=Exporting Code Templates +CodeTemplateBlock.export.exists.message={0} already exists.\nDo you want to replace it? + +CodeTemplateBlock.error.read.title= Code Templates +CodeTemplateBlock.error.read.message= Failed to read templates. + +CodeTemplateBlock.error.parse.message= Failed to parse templates:\n{0} + +CodeTemplateBlock.error.write.title=Code Templates +CodeTemplateBlock.error.write.message=Failed to write templates. + +CodeTemplateBlock.export.error.title= Exporting Templates +CodeTemplateBlock.export.error.hidden= Export failed.\n{0} is a hidden file. +CodeTemplateBlock.export.error.canNotWrite= Export failed.\n{0} can not be modified. +CodeTemplateBlock.export.error.fileNotFound= Export failed:\n{0} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaColorManager.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaColorManager.java index a7a462b..3c57e1d 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaColorManager.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaColorManager.java @@ -20,20 +20,47 @@ import org.eclipse.swt.widgets.Display; * Java color manager. */ public class JavaColorManager implements IColorManager, IColorManagerExtension { - protected Map fKeyTable= new HashMap(10); protected Map fDisplayTable= new HashMap(2); - - + + /** + * Flag which tells if the colors are automatically disposed when + * the current display gets disposed. + */ + private boolean fAutoDisposeOnDisplayDispose; + + + /** + * Creates a new Java color manager which automatically + * disposes the allocated colors when the current display + * gets disposed. + */ public JavaColorManager() { + this(true); + } + + /** + * Creates a new Java color manager. + * + * @param autoDisposeOnDisplayDispose if true the color manager + * automatically disposes all managed colors when the current display gets disposed + * and all calls to {@link org.eclipse.jface.text.source.ISharedTextColors#dispose()} are ignored. + * + * @since 2.1 + */ + public JavaColorManager(boolean autoDisposeOnDisplayDispose) { + fAutoDisposeOnDisplayDispose= autoDisposeOnDisplayDispose; } - private void dispose(Display display) { + public void dispose(Display display) { Map colorTable= (Map) fDisplayTable.get(display); if (colorTable != null) { Iterator e= colorTable.values().iterator(); - while (e.hasNext()) - ((Color) e.next()).dispose(); + while (e.hasNext()) { + Color color= (Color)e.next(); + if (color != null && !color.isDisposed()) + color.dispose(); + } } } @@ -50,11 +77,13 @@ public class JavaColorManager implements IColorManager, IColorManagerExtension { if (colorTable == null) { colorTable= new HashMap(10); fDisplayTable.put(display, colorTable); - display.disposeExec(new Runnable() { - public void run() { - dispose(display); - } - }); + if (fAutoDisposeOnDisplayDispose) { + display.disposeExec(new Runnable() { + public void run() { + dispose(display); + } + }); + } } Color color= (Color) colorTable.get(rgb); @@ -70,7 +99,8 @@ public class JavaColorManager implements IColorManager, IColorManagerExtension { * @see IColorManager#dispose */ public void dispose() { - // nothing to dispose + if (!fAutoDisposeOnDisplayDispose) + dispose(Display.getCurrent()); } /* diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaElementProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaElementProvider.java new file mode 100644 index 0000000..ed4d33a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaElementProvider.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text; + + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.ui.actions.SelectionConverter; +import net.sourceforge.phpeclipse.phpeditor.PHPEditor; + +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.information.IInformationProvider; +import org.eclipse.jface.text.information.IInformationProviderExtension; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IEditorPart; + + + +/** + * Provides a Java element to be displayed in by an information presenter. + */ +public class JavaElementProvider implements IInformationProvider, IInformationProviderExtension { + + private PHPEditor fEditor; + private boolean fUseCodeResolve; + + public JavaElementProvider(IEditorPart editor) { + fUseCodeResolve= false; + if (editor instanceof PHPEditor) + fEditor= (PHPEditor)editor; + } + + public JavaElementProvider(IEditorPart editor, boolean useCodeResolve) { + this(editor); + fUseCodeResolve= useCodeResolve; + } + + /* + * @see IInformationProvider#getSubject(ITextViewer, int) + */ + public IRegion getSubject(ITextViewer textViewer, int offset) { + if (textViewer != null && fEditor != null) { + IRegion region= JavaWordFinder.findWord(textViewer.getDocument(), offset); + if (region != null) + return region; + else + return new Region(offset, 0); + } + return null; + } + + /* + * @see IInformationProvider#getInformation(ITextViewer, IRegion) + */ + public String getInformation(ITextViewer textViewer, IRegion subject) { + return getInformation2(textViewer, subject).toString(); + } + + /* + * @see IInformationProviderExtension#getElement(ITextViewer, IRegion) + */ + public Object getInformation2(ITextViewer textViewer, IRegion subject) { + if (fEditor == null) + return null; + + try { + if (fUseCodeResolve) { + IStructuredSelection sel= SelectionConverter.getStructuredSelection(fEditor); + if (!sel.isEmpty()) + return sel.getFirstElement(); + } + IJavaElement element= SelectionConverter.getElementAtOffset(fEditor); + if (element != null) + return element; + return SelectionConverter.getInput(fEditor); + } catch (JavaModelException e) { + return null; + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaOutlineInformationControl.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaOutlineInformationControl.java new file mode 100644 index 0000000..68db9b5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaOutlineInformationControl.java @@ -0,0 +1,608 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IParent; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.ui.actions.OpenActionUtil; +import net.sourceforge.phpdt.internal.ui.util.StringMatcher; +import net.sourceforge.phpdt.internal.ui.viewsupport.AppearanceAwareLabelProvider; +import net.sourceforge.phpdt.internal.ui.viewsupport.DecoratingJavaLabelProvider; +import net.sourceforge.phpdt.internal.ui.viewsupport.JavaElementLabels; +import net.sourceforge.phpdt.ui.JavaElementSorter; +import net.sourceforge.phpdt.ui.StandardJavaElementContentProvider; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlExtension; +import org.eclipse.jface.text.IInformationControlExtension2; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; + +/** + * @author dmegert + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class JavaOutlineInformationControl implements IInformationControl, IInformationControlExtension, IInformationControlExtension2 { + + + /** + * The NamePatternFilter selects the elements which + * match the given string patterns. + *

        + * The following characters have special meaning: + * ? => any character + * * => any string + *

        + * + * @since 2.0 + */ + private static class NamePatternFilter extends ViewerFilter { + private String fPattern; + private StringMatcher fMatcher; + private ILabelProvider fLabelProvider; + private Viewer fViewer; + + private StringMatcher getMatcher() { + return fMatcher; + } + + + /* (non-Javadoc) + * Method declared on ViewerFilter. + */ + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (fMatcher == null) + return true; + + ILabelProvider labelProvider= getLabelProvider(viewer); + + String matchName= null; + if (labelProvider != null) + matchName= ((ILabelProvider)labelProvider).getText(element); + else if (element instanceof IJavaElement) + matchName= ((IJavaElement) element).getElementName(); + + if (matchName != null && fMatcher.match(matchName)) + return true; + + return hasUnfilteredChild(viewer, element); + } + + private ILabelProvider getLabelProvider(Viewer viewer) { + if (fViewer == viewer) + return fLabelProvider; + + fLabelProvider= null; + IBaseLabelProvider baseLabelProvider= null; + if (viewer instanceof StructuredViewer) + baseLabelProvider= ((StructuredViewer)viewer).getLabelProvider(); + + if (baseLabelProvider instanceof ILabelProvider) + fLabelProvider= (ILabelProvider)baseLabelProvider; + + return fLabelProvider; + } + + private boolean hasUnfilteredChild(Viewer viewer, Object element) { + IJavaElement[] children; + if (element instanceof IParent) { + try { + children= ((IParent)element).getChildren(); + } catch (JavaModelException ex) { + return false; + } + for (int i= 0; i < children.length; i++) + if (select(viewer, element, children[i])) + return true; + } + return false; + } + + /** + * Sets the patterns to filter out for the receiver. + *

        + * The following characters have special meaning: + * ? => any character + * * => any string + *

        + */ + public void setPattern(String pattern) { + fPattern= pattern; + if (fPattern == null) { + fMatcher= null; + return; + } + boolean ignoreCase= pattern.toLowerCase().equals(pattern); + fMatcher= new StringMatcher(pattern, ignoreCase, false); + } + } + + + private static class BorderFillLayout extends Layout { + + /** The border widths. */ + final int fBorderSize; + + /** + * Creates a fill layout with a border. + */ + public BorderFillLayout(int borderSize) { + if (borderSize < 0) + throw new IllegalArgumentException(); + fBorderSize= borderSize; + } + + /** + * Returns the border size. + */ + public int getBorderSize() { + return fBorderSize; + } + + /* + * @see org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite, int, int, boolean) + */ + protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { + + Control[] children= composite.getChildren(); + Point minSize= new Point(0, 0); + + if (children != null) { + for (int i= 0; i < children.length; i++) { + Point size= children[i].computeSize(wHint, hHint, flushCache); + minSize.x= Math.max(minSize.x, size.x); + minSize.y= Math.max(minSize.y, size.y); + } + } + + minSize.x += fBorderSize * 2 + RIGHT_MARGIN; + minSize.y += fBorderSize * 2; + + return minSize; + } + /* + * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite, boolean) + */ + protected void layout(Composite composite, boolean flushCache) { + + Control[] children= composite.getChildren(); + Point minSize= new Point(composite.getClientArea().width, composite.getClientArea().height); + + if (children != null) { + for (int i= 0; i < children.length; i++) { + Control child= children[i]; + child.setSize(minSize.x - fBorderSize * 2, minSize.y - fBorderSize * 2); + child.setLocation(fBorderSize, fBorderSize); + } + } + } + } + + + /** Border thickness in pixels. */ + private static final int BORDER= 1; + /** Right margin in pixels. */ + private static final int RIGHT_MARGIN= 3; + + /** The control's shell */ + private Shell fShell; + /** The composite */ + Composite fComposite; + /** The control's text widget */ + private Text fFilterText; + /** The control's tree widget */ + private TreeViewer fTreeViewer; + /** The control width constraint */ + private int fMaxWidth= -1; + /** The control height constraint */ + private int fMaxHeight= -1; + + private StringMatcher fStringMatcher; + + + /** + * Creates a tree information control with the given shell as parent. The given + * style is applied to the tree widget. + * + * @param parent the parent shell + * @param style the additional styles for the tree widget + */ + public JavaOutlineInformationControl(Shell parent, int style) { + this(parent, SWT.RESIZE, style); + } + + /** + * Creates a tree information control with the given shell as parent. + * No additional styles are applied. + * + * @param parent the parent shell + */ + public JavaOutlineInformationControl(Shell parent) { + this(parent, SWT.NONE); + } + + /** + * Creates a tree information control with the given shell as parent. The given + * styles are applied to the shell and the tree widget. + * + * @param parent the parent shell + * @param shellStyle the additional styles for the shell + * @param treeStyle the additional styles for the tree widget + */ + public JavaOutlineInformationControl(Shell parent, int shellStyle, int treeStyle) { + fShell= new Shell(parent, shellStyle); + Display display= fShell.getDisplay(); + fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK)); + + // Composite for filter text and tree + fComposite= new Composite(fShell,SWT.RESIZE); + GridLayout layout= new GridLayout(1, false); + fComposite.setLayout(layout); + fComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + createFilterText(fComposite); + createTreeViewer(fComposite, treeStyle); + + int border= ((shellStyle & SWT.NO_TRIM) == 0) ? 0 : BORDER; + fShell.setLayout(new BorderFillLayout(border)); + + setInfoSystemColor(); + installFilter(); + } + + private void createTreeViewer(Composite parent, int style) { + Tree tree= new Tree(parent, SWT.SINGLE | (style & ~SWT.MULTI)); + GridData data= new GridData(GridData.FILL_BOTH); + tree.setLayoutData(data); + + fTreeViewer= new TreeViewer(tree); + + // Hide import declartions but show the container +// fTreeViewer.addFilter(new ViewerFilter() { +// public boolean select(Viewer viewer, Object parentElement, Object element) { +// return !(element instanceof IImportDeclaration); +// } +// }); + + fTreeViewer.setContentProvider(new StandardJavaElementContentProvider(true, true)); + fTreeViewer.setSorter(new JavaElementSorter()); + fTreeViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS); + + AppearanceAwareLabelProvider lprovider= new AppearanceAwareLabelProvider( + AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS | JavaElementLabels.F_APP_TYPE_SIGNATURE, + AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS + ); + fTreeViewer.setLabelProvider(new DecoratingJavaLabelProvider(lprovider)); + + fTreeViewer.getTree().addKeyListener(new KeyListener() { + public void keyPressed(KeyEvent e) { + if (e.character == 0x1B) // ESC + dispose(); + } + public void keyReleased(KeyEvent e) { + // do nothing + } + }); + + fTreeViewer.getTree().addSelectionListener(new SelectionListener() { + public void widgetSelected(SelectionEvent e) { + // do nothing + } + public void widgetDefaultSelected(SelectionEvent e) { + gotoSelectedElement(); + } + }); + } + + private Text createFilterText(Composite parent) { + fFilterText= new Text(parent, SWT.FLAT); + + GridData data= new GridData(); + GC gc= new GC(parent); + gc.setFont(parent.getFont()); + FontMetrics fontMetrics= gc.getFontMetrics(); + gc.dispose(); + + data.heightHint= org.eclipse.jface.dialogs.Dialog.convertHeightInCharsToPixels(fontMetrics, 1); + data.horizontalAlignment= GridData.FILL; + data.verticalAlignment= GridData.BEGINNING; + fFilterText.setLayoutData(data); + + fFilterText.addKeyListener(new KeyListener() { + public void keyPressed(KeyEvent e) { + if (e.keyCode == 0x0D) // return + gotoSelectedElement(); + if (e.keyCode == SWT.ARROW_DOWN) + fTreeViewer.getTree().setFocus(); + if (e.keyCode == SWT.ARROW_UP) + fTreeViewer.getTree().setFocus(); + if (e.character == 0x1B) // ESC + dispose(); + } + public void keyReleased(KeyEvent e) { + // do nothing + } + }); + + // Horizonral separator line + Label separator= new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.LINE_DOT); + separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + return fFilterText; + } + + private void setInfoSystemColor() { + Display display= fShell.getDisplay(); + setForegroundColor(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND)); + setBackgroundColor(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + } + + private void installFilter() { + final NamePatternFilter viewerFilter= new NamePatternFilter(); + fTreeViewer.addFilter(viewerFilter); + fFilterText.setText(""); //$NON-NLS-1$ + + fFilterText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + String pattern= fFilterText.getText(); + if (pattern != null) { + int length= pattern.length(); + if (length == 0) + pattern= null; + else if (pattern.charAt(length -1 ) != '*') + pattern= pattern + '*'; + } else + pattern= null; + viewerFilter.setPattern(pattern); + fStringMatcher= viewerFilter.getMatcher(); + fTreeViewer.getControl().setRedraw(false); + fTreeViewer.refresh(); + fTreeViewer.expandAll(); + selectFirstMatch(); + fTreeViewer.getControl().setRedraw(true); + } + }); + } + + private void gotoSelectedElement() { + Object selectedElement= ((IStructuredSelection)fTreeViewer.getSelection()).getFirstElement(); + if (selectedElement != null) { + try { + dispose(); + OpenActionUtil.open(selectedElement, true); + } catch (CoreException ex) { + PHPeclipsePlugin.log(ex); + } + } + } + + /** + * Selects the first element in the tree which + * matches the current filter pattern. + */ + private void selectFirstMatch() { + Tree tree= fTreeViewer.getTree(); + Object element= findElement(tree.getItems()); + if (element != null) + fTreeViewer.setSelection(new StructuredSelection(element), true); + else + fTreeViewer.setSelection(StructuredSelection.EMPTY); + } + + private IJavaElement findElement(TreeItem[] items) { + ILabelProvider labelProvider= (ILabelProvider)fTreeViewer.getLabelProvider(); + for (int i= 0; i < items.length; i++) { + IJavaElement element= (IJavaElement)items[i].getData(); + if (fStringMatcher == null) + return element; + + if (element != null) { + String label= labelProvider.getText(element); + if (fStringMatcher.match(label)) + return element; + } + + element= findElement(items[i].getItems()); + if (element != null) + return element; + } + return null; + } + + /* + * @see IInformationControl#setInformation(String) + */ + public void setInformation(String information) { + // this method is ignored, see IInformationControlExtension2 + } + + /* + * @see IInformationControlExtension2#setInput(Object) + */ + public void setInput(Object information) { + fFilterText.setText(""); //$NON-NLS-1$ + if (information == null || information instanceof String) { + setInput(null); + return; + } + IJavaElement je= (IJavaElement)information; + IJavaElement sel= null; + ICompilationUnit cu= (ICompilationUnit)je.getAncestor(IJavaElement.COMPILATION_UNIT); + if (cu != null) + sel= cu; + else + sel= je.getAncestor(IJavaElement.CLASS_FILE); + fTreeViewer.setInput(sel); + fTreeViewer.setSelection(new StructuredSelection(information)); + } + + /* + * @see IInformationControl#setVisible(boolean) + */ + public void setVisible(boolean visible) { + fShell.setVisible(visible); + } + + /* + * @see IInformationControl#dispose() + */ + public void dispose() { + if (fShell != null) { + if (!fShell.isDisposed()) + fShell.dispose(); + fShell= null; + fTreeViewer= null; + fComposite= null; + fFilterText= null; + } + } + + /* + * @see org.eclipse.jface.text.IInformationControlExtension#hasContents() + */ + public boolean hasContents() { + return fTreeViewer != null && fTreeViewer.getInput() != null; + } + + /* + * @see org.eclipse.jface.text.IInformationControl#setSizeConstraints(int, int) + */ + public void setSizeConstraints(int maxWidth, int maxHeight) { + fMaxWidth= maxWidth; + fMaxHeight= maxHeight; + } + + /* + * @see org.eclipse.jface.text.IInformationControl#computeSizeHint() + */ + public Point computeSizeHint() { + return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT); + } + + /* + * @see IInformationControl#setLocation(Point) + */ + public void setLocation(Point location) { + Rectangle trim= fShell.computeTrim(0, 0, 0, 0); + Point textLocation= fComposite.getLocation(); + location.x += trim.x - textLocation.x; + location.y += trim.y - textLocation.y; + fShell.setLocation(location); + } + + /* + * @see IInformationControl#setSize(int, int) + */ + public void setSize(int width, int height) { + fShell.setSize(width, height); + } + + /* + * @see IInformationControl#addDisposeListener(DisposeListener) + */ + public void addDisposeListener(DisposeListener listener) { + fShell.addDisposeListener(listener); + } + + /* + * @see IInformationControl#removeDisposeListener(DisposeListener) + */ + public void removeDisposeListener(DisposeListener listener) { + fShell.removeDisposeListener(listener); + } + + /* + * @see IInformationControl#setForegroundColor(Color) + */ + public void setForegroundColor(Color foreground) { + fTreeViewer.getTree().setForeground(foreground); + fFilterText.setForeground(foreground); + fComposite.setForeground(foreground); + } + + /* + * @see IInformationControl#setBackgroundColor(Color) + */ + public void setBackgroundColor(Color background) { + fTreeViewer.getTree().setBackground(background); + fFilterText.setBackground(background); + fComposite.setBackground(background); + } + + /* + * @see IInformationControl#isFocusControl() + */ + public boolean isFocusControl() { + return fTreeViewer.getControl().isFocusControl() || fFilterText.isFocusControl(); + } + + /* + * @see IInformationControl#setFocus() + */ + public void setFocus() { + fShell.forceFocus(); + fFilterText.setFocus(); + } + + /* + * @see IInformationControl#addFocusListener(FocusListener) + */ + public void addFocusListener(FocusListener listener) { + fShell.addFocusListener(listener); + } + + /* + * @see IInformationControl#removeFocusListener(FocusListener) + */ + public void removeFocusListener(FocusListener listener) { + fShell.removeFocusListener(listener); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaReconciler.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaReconciler.java new file mode 100644 index 0000000..880922e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaReconciler.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package net.sourceforge.phpdt.internal.ui.text; + + +import net.sourceforge.phpdt.internal.ui.text.java.JavaReconcilingStrategy; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.reconciler.IReconcilingStrategy; +import org.eclipse.jface.text.reconciler.MonoReconciler; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.texteditor.ITextEditor; + + + +/** + * A reconciler that is also activated on editor activation. + */ +public class JavaReconciler extends MonoReconciler { + + /** + * Internal part listener for activating the reconciler. + */ + class PartListener implements IPartListener { + + /* + * @see IPartListener#partActivated(IWorkbenchPart) + */ + public void partActivated(IWorkbenchPart part) { + if (part == fTextEditor) + JavaReconciler.this.forceReconciling(); + } + + /* + * @see IPartListener#partBroughtToTop(IWorkbenchPart) + */ + public void partBroughtToTop(IWorkbenchPart part) { + } + + /* + * @see IPartListener#partClosed(IWorkbenchPart) + */ + public void partClosed(IWorkbenchPart part) { + } + + /* + * @see IPartListener#partDeactivated(IWorkbenchPart) + */ + public void partDeactivated(IWorkbenchPart part) { + } + + /* + * @see IPartListener#partOpened(IWorkbenchPart) + */ + public void partOpened(IWorkbenchPart part) { + } + }; + + + /** The reconciler's editor */ + private ITextEditor fTextEditor; + /** The part listener */ + private IPartListener fPartListener; + + + /** + * Creates a new reconciler. + */ + public JavaReconciler(ITextEditor editor, IReconcilingStrategy strategy, boolean isIncremental) { + super(strategy, isIncremental); + fTextEditor= editor; + } + + /* + * @see IReconciler#install(ITextViewer) + */ + public void install(ITextViewer textViewer) { + super.install(textViewer); + + fPartListener= new PartListener(); + IWorkbenchPartSite site= fTextEditor.getSite(); + IWorkbenchWindow window= site.getWorkbenchWindow(); + window.getPartService().addPartListener(fPartListener); + } + + /* + * @see IReconciler#uninstall() + */ + public void uninstall() { + + IWorkbenchPartSite site= fTextEditor.getSite(); + IWorkbenchWindow window= site.getWorkbenchWindow(); + window.getPartService().removePartListener(fPartListener); + fPartListener= null; + + super.uninstall(); + } + + /* + * @see AbstractReconciler#forceReconciling() + */ + protected void forceReconciling() { + super.forceReconciling(); + IReconcilingStrategy strategy= getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE); + if (strategy instanceof JavaReconcilingStrategy) { + JavaReconcilingStrategy java= (JavaReconcilingStrategy) strategy; + java.notifyParticipants(false); + } + } + + /* + * @see AbstractReconciler#reconcilerReset() + */ + protected void reconcilerReset() { + super.reconcilerReset(); + IReconcilingStrategy strategy= getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE); + if (strategy instanceof JavaReconcilingStrategy) { + JavaReconcilingStrategy java= (JavaReconcilingStrategy) strategy; + java.notifyParticipants(true); + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaWordFinder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaWordFinder.java new file mode 100644 index 0000000..63934fa --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaWordFinder.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text; + + +import net.sourceforge.phpdt.internal.compiler.parser.Scanner; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Region; + +public class JavaWordFinder { + + public static IRegion findWord(IDocument document, int offset) { + + int start= -1; + int end= -1; + + + try { + + int pos= offset; + char c; + + while (pos >= 0) { + c= document.getChar(pos); + if (!Scanner.isPHPIdentifierPart(c)) + break; + --pos; + } + + start= pos; + + pos= offset; + int length= document.getLength(); + + while (pos < length) { + c= document.getChar(pos); + if (!Scanner.isPHPIdentifierPart(c)) + break; + ++pos; + } + + end= pos; + + } catch (BadLocationException x) { + } + + if (start > -1 && end > -1) { + if (start == offset && end == offset) + return new Region(offset, 0); + else if (start == offset) + return new Region(start, end - start); + else + return new Region(start + 1, end - start - 1); + } + + return null; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaReconcilingStrategy.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaReconcilingStrategy.java new file mode 100644 index 0000000..d12ddf9 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaReconcilingStrategy.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package net.sourceforge.phpdt.internal.ui.text.java; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.ui.IWorkingCopyManager; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.reconciler.DirtyRegion; +import org.eclipse.jface.text.reconciler.IReconcilingStrategy; +import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; + +public class JavaReconcilingStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension { + + private ITextEditor fEditor; + + private IWorkingCopyManager fManager; + private IDocumentProvider fDocumentProvider; + private IProgressMonitor fProgressMonitor; + private boolean fNotify = true; + + public JavaReconcilingStrategy(ITextEditor editor) { + fEditor = editor; + fManager = PHPeclipsePlugin.getDefault().getWorkingCopyManager(); + fDocumentProvider = PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider(); + } + + private IProblemRequestorExtension getProblemRequestorExtension() { + IAnnotationModel model = fDocumentProvider.getAnnotationModel(fEditor.getEditorInput()); + if (model instanceof IProblemRequestorExtension) + return (IProblemRequestorExtension) model; + return null; + } + + private void reconcile() { + // // try { + // + // /* fix for missing cancel flag communication */ + // IProblemRequestorExtension extension = getProblemRequestorExtension(); + // if (extension != null) + // extension.setProgressMonitor(fProgressMonitor); + // + // // reconcile + //// synchronized (unit) { + //// unit.reconcile(true, fProgressMonitor); + //// } + // + // Parser parser = new Parser(); + // parser.initializeScanner(); + // // actualParser.setFileToParse(fileToParse); + // String text = fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput()).get(); + // parser.init(text); + // parser.reportSyntaxError(); + //// checkAndReportBracketAnomalies(parser.problemReporter()); + // + // /* fix for missing cancel flag communication */ + // if (extension != null) + // extension.setProgressMonitor(null); + // + // // update participants + // try { + // if (fEditor instanceof IReconcilingParticipant && fNotify && !fProgressMonitor.isCanceled()) { + // IReconcilingParticipant p = (IReconcilingParticipant) fEditor; + // p.reconciled(); + // } + // } finally { + // fNotify = true; + // } + + // JDT implementation: + ICompilationUnit unit = fManager.getWorkingCopy(fEditor.getEditorInput()); + if (unit != null) { + try { + + /* fix for missing cancel flag communication */ + IProblemRequestorExtension extension = getProblemRequestorExtension(); + if (extension != null) + extension.setProgressMonitor(fProgressMonitor); + + // reconcile + synchronized (unit) { + unit.reconcile(true, fProgressMonitor); + } + + /* fix for missing cancel flag communication */ + if (extension != null) + extension.setProgressMonitor(null); + + // update participants + try { + if (fEditor instanceof IReconcilingParticipant && fNotify && !fProgressMonitor.isCanceled()) { + IReconcilingParticipant p = (IReconcilingParticipant) fEditor; + p.reconciled(); + } + } finally { + fNotify = true; + } + + } catch (JavaModelException x) { + // swallow exception + } + } + } + + /* + * @see IReconcilingStrategy#reconcile(IRegion) + */ + public void reconcile(IRegion partition) { + reconcile(); + } + + /* + * @see IReconcilingStrategy#reconcile(DirtyRegion, IRegion) + */ + public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) { + reconcile(); + } + + /* + * @see IReconcilingStrategy#setDocument(IDocument) + */ + public void setDocument(IDocument document) { + } + + /* + * @see IReconcilingStrategyExtension#setProgressMonitor(IProgressMonitor) + */ + public void setProgressMonitor(IProgressMonitor monitor) { + fProgressMonitor = monitor; + } + + /* + * @see IReconcilingStrategyExtension#initialReconcile() + */ + public void initialReconcile() { + reconcile(); + } + + /** + * Tells this strategy whether to inform its participants. + * + * @param notify true if participant should be notified + */ + public void notifyParticipants(boolean notify) { + fNotify = notify; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AbstractJavaEditorTextHover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AbstractJavaEditorTextHover.java new file mode 100644 index 0000000..565a8ab --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AbstractJavaEditorTextHover.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package net.sourceforge.phpdt.internal.ui.text.java.hover; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.internal.ui.text.JavaWordFinder; +import net.sourceforge.phpdt.ui.text.java.hover.IJavaEditorTextHover; + +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.ui.IEditorPart; + +/** + * Abstract class for providing hover information for Java elements. + * + * @since 2.1 + */ +public abstract class AbstractJavaEditorTextHover implements IJavaEditorTextHover { + + + private IEditorPart fEditor; + + + /* + * @see IJavaEditorTextHover#setEditor(IEditorPart) + */ + public void setEditor(IEditorPart editor) { + fEditor= editor; + } + + protected IEditorPart getEditor() { + return fEditor; + } + +// protected ICodeAssist getCodeAssist() { +// if (fEditor != null) { +// IEditorInput input= fEditor.getEditorInput(); +// if (input instanceof IClassFileEditorInput) { +// IClassFileEditorInput cfeInput= (IClassFileEditorInput) input; +// return cfeInput.getClassFile(); +// } +// +// IWorkingCopyManager manager= PHPeclipsePlugin.getDefault().getWorkingCopyManager(); +// return manager.getWorkingCopy(input); +// } +// +// return null; +// } + + /* + * @see ITextHover#getHoverRegion(ITextViewer, int) + */ + public IRegion getHoverRegion(ITextViewer textViewer, int offset) { + return JavaWordFinder.findWord(textViewer.getDocument(), offset); + } + + /* + * @see ITextHover#getHoverInfo(ITextViewer, IRegion) + */ + public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { + +// ICodeAssist resolve= getCodeAssist(); +// if (resolve != null) { +// try { +// IJavaElement[] result= null; +// +// synchronized (resolve) { +// result= resolve.codeSelect(hoverRegion.getOffset(), hoverRegion.getLength()); +// } +// +// if (result == null) +// return null; +// +// int nResults= result.length; +// if (nResults == 0) +// return null; +// +// return getHoverInfo(result); +// +// } catch (JavaModelException x) { +// PHPeclipsePlugin.log(x.getStatus()); +// } +// } + return null; + } + + /** + * Provides hover information for the given Java elements. + * + * @return the hover information string + * @since 2.1 + */ + protected String getHoverInfo(IJavaElement[] javaElements) { + return null; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/BestMatchHover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/BestMatchHover.java new file mode 100644 index 0000000..88cd055 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/BestMatchHover.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text.java.hover; + + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import net.sourceforge.phpdt.ui.PreferenceConstants; +import net.sourceforge.phpdt.ui.text.java.hover.IJavaEditorTextHover; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.ui.IEditorPart; + +/** + * Caution: this implementation is a layer breaker and contains some "shortcuts" + */ +public class BestMatchHover extends AbstractJavaEditorTextHover { + + private static class JavaEditorTextHoverDescriptorComparator implements Comparator { + + /* + * @see Comparator#compare(Object, Object) + */ + public int compare(Object object0, Object object1) { + + JavaEditorTextHoverDescriptor element0= (JavaEditorTextHoverDescriptor)object0; + JavaEditorTextHoverDescriptor element1= (JavaEditorTextHoverDescriptor)object1; + + String id0= element0.getId(); + String id1= element1.getId(); + + if (id0 != null && id0.equals(id1)) + return 0; + + if (id0 != null && JavaProblemHover.isJavaProblemHover(id0)) + return -1; + + if (id1 != null && JavaProblemHover.isJavaProblemHover(id1)) + return +1; + + + // now compare non-problem hovers + if (element0.dependsOn(element1)) + return -1; + + if (element1.dependsOn(element0)) + return +1; + + return 0; + } + } + + protected String fCurrentPerspectiveId; + protected List fTextHoverSpecifications; + protected List fInstantiatedTextHovers; + + + public BestMatchHover() { + installTextHovers(); + } + + public BestMatchHover(IEditorPart editor) { + this(); + setEditor(editor); + } + + /** + * Installs all text hovers. + */ + private void installTextHovers() { + + // initialize lists - indicates that the initialization happened + fTextHoverSpecifications= new ArrayList(2); + fInstantiatedTextHovers= new ArrayList(2); + + // populate list + JavaEditorTextHoverDescriptor[] hoverDescs= PHPeclipsePlugin.getDefault().getJavaEditorTextHoverDescriptors(); + for (int i= 0; i < hoverDescs.length; i++) { + // ensure that we don't add ourselves to the list + if (!PreferenceConstants.ID_BESTMATCH_HOVER.equals(hoverDescs[i].getId())) + fTextHoverSpecifications.add(hoverDescs[i]); + } + Collections.sort(fTextHoverSpecifications, new JavaEditorTextHoverDescriptorComparator()); + } + + private void checkTextHovers() { + if (fTextHoverSpecifications.size() == 0) + return; + + for (Iterator iterator= new ArrayList(fTextHoverSpecifications).iterator(); iterator.hasNext(); ) { + JavaEditorTextHoverDescriptor spec= (JavaEditorTextHoverDescriptor) iterator.next(); + + IJavaEditorTextHover hover= spec.createTextHover(); + if (hover != null) { + hover.setEditor(getEditor()); + addTextHover(hover); + fTextHoverSpecifications.remove(spec); + } + } + } + + protected void addTextHover(ITextHover hover) { + if (!fInstantiatedTextHovers.contains(hover)) + fInstantiatedTextHovers.add(hover); + } + + /* + * @see ITextHover#getHoverInfo(ITextViewer, IRegion) + */ + public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { + + checkTextHovers(); + + if (fInstantiatedTextHovers == null) + return null; + + for (Iterator iterator= fInstantiatedTextHovers.iterator(); iterator.hasNext(); ) { + ITextHover hover= (ITextHover) iterator.next(); + + String s= hover.getHoverInfo(textViewer, hoverRegion); + if (s != null && s.trim().length() > 0) + return s; + } + + return null; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaEditorTextHoverDescriptor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaEditorTextHoverDescriptor.java new file mode 100644 index 0000000..7f8148f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaEditorTextHoverDescriptor.java @@ -0,0 +1,312 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package net.sourceforge.phpdt.internal.ui.text.java.hover; + +import java.text.Collator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.StringTokenizer; + +import net.sourceforge.phpdt.ui.PreferenceConstants; +import net.sourceforge.phpdt.ui.text.java.hover.IJavaEditorTextHover; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.phpeditor.EditorUtility; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPluginDescriptor; +import org.eclipse.core.runtime.IPluginPrerequisite; +import org.eclipse.core.runtime.IPluginRegistry; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.text.Assert; +import org.eclipse.swt.SWT; + +/** + * Describes a Java editor text hover. + * + * @since 2.1 + */ +public class JavaEditorTextHoverDescriptor implements Comparable { + + private static final String JAVA_EDITOR_TEXT_HOVER_EXTENSION_POINT= "net.sourceforge.phpeclipse.phpEditorTextHovers"; //$NON-NLS-1$ + private static final String HOVER_TAG= "hover"; //$NON-NLS-1$ + private static final String ID_ATTRIBUTE= "id"; //$NON-NLS-1$ + private static final String CLASS_ATTRIBUTE= "class"; //$NON-NLS-1$ + private static final String LABEL_ATTRIBUTE= "label"; //$NON-NLS-1$ + private static final String ACTIVATE_PLUG_IN_ATTRIBUTE= "activate"; //$NON-NLS-1$ + private static final String DESCRIPTION_ATTRIBUTE= "description"; //$NON-NLS-1$ + + public static final String NO_MODIFIER= "0"; //$NON-NLS-1$ + public static final String DISABLED_TAG= "!"; //$NON-NLS-1$ + public static final String VALUE_SEPARATOR= ";"; //$NON-NLS-1$ + + private int fStateMask; + private String fModifierString; + private boolean fIsEnabled; + + private IConfigurationElement fElement; + + + /** + * Returns all Java editor text hovers contributed to the workbench. + */ + public static JavaEditorTextHoverDescriptor[] getContributedHovers() { + IPluginRegistry registry= Platform.getPluginRegistry(); + IConfigurationElement[] elements= registry.getConfigurationElementsFor(JAVA_EDITOR_TEXT_HOVER_EXTENSION_POINT); + JavaEditorTextHoverDescriptor[] hoverDescs= createDescriptors(elements); + initializeFromPreferences(hoverDescs); + return hoverDescs; + } + + /** + * Computes the state mask for the given modifier string. + * + * @param modifiers the string with the modifiers, separated by '+', '-', ';', ',' or '.' + * @return the state mask or -1 if the input is invalid + */ + public static int computeStateMask(String modifiers) { + if (modifiers == null) + return -1; + + if (modifiers.length() == 0) + return SWT.NONE; + + int stateMask= 0; + StringTokenizer modifierTokenizer= new StringTokenizer(modifiers, ",;.:+-* "); //$NON-NLS-1$ + while (modifierTokenizer.hasMoreTokens()) { + int modifier= EditorUtility.findLocalizedModifier(modifierTokenizer.nextToken()); + if (modifier == 0 || (stateMask & modifier) == modifier) + return -1; + stateMask= stateMask | modifier; + } + return stateMask; + } + + /** + * Creates a new Java Editor text hover descriptor from the given configuration element. + */ + private JavaEditorTextHoverDescriptor(IConfigurationElement element) { + Assert.isNotNull(element); + fElement= element; + } + + /** + * Creates the Java editor text hover. + */ + public IJavaEditorTextHover createTextHover() { + boolean isHoversPlugInActivated= fElement.getDeclaringExtension().getDeclaringPluginDescriptor().isPluginActivated(); + if (isHoversPlugInActivated || canActivatePlugIn()) { + try { + return (IJavaEditorTextHover)fElement.createExecutableExtension(CLASS_ATTRIBUTE); + } catch (CoreException x) { + PHPeclipsePlugin.log(new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), 0, JavaHoverMessages.getString("JavaTextHover.createTextHover"), null)); //$NON-NLS-1$ + } + } + + return null; + } + + //---- XML Attribute accessors --------------------------------------------- + + /** + * Returns the hover's id. + */ + public String getId() { + return fElement.getAttribute(ID_ATTRIBUTE); + } + + /** + * Returns the hover's class name. + */ + public String getHoverClassName() { + return fElement.getAttribute(CLASS_ATTRIBUTE); + } + + /** + * Returns the hover's label. + */ + public String getLabel() { + String label= fElement.getAttribute(LABEL_ATTRIBUTE); + if (label != null) + return label; + + // Return simple class name + label= getHoverClassName(); + int lastDot= label.lastIndexOf('.'); + if (lastDot >= 0 && lastDot < label.length() - 1) + return label.substring(lastDot + 1); + else + return label; + } + + /** + * Returns the hover's description. + * + * @return the hover's description or null if not provided + */ + public String getDescription() { + return fElement.getAttribute(DESCRIPTION_ATTRIBUTE); + } + + + public boolean canActivatePlugIn() { + return Boolean.valueOf(fElement.getAttribute(ACTIVATE_PLUG_IN_ATTRIBUTE)).booleanValue(); + } + + public boolean equals(Object obj) { + if (obj == null || !obj.getClass().equals(this.getClass()) || getId() == null) + return false; + return getId().equals(((JavaEditorTextHoverDescriptor)obj).getId()); + } + + public int hashCode() { + return getId().hashCode(); + } + + /* + * Implements a method from IComparable + */ + public int compareTo(Object o) { + return Collator.getInstance().compare(getLabel(), ((JavaEditorTextHoverDescriptor)o).getLabel()); + } + + /** + * @param descriptor a JavaEditorTextHoverDescriptor + * @return true if this contributed hover depends on the other one + */ + public boolean dependsOn(JavaEditorTextHoverDescriptor descriptor) { + if (descriptor == null) + return false; + + IPluginDescriptor thisPluginDescriptor= fElement.getDeclaringExtension().getDeclaringPluginDescriptor(); + IPluginDescriptor otherPluginDescriptor= descriptor.fElement.getDeclaringExtension().getDeclaringPluginDescriptor(); + return dependsOn(thisPluginDescriptor, otherPluginDescriptor); + } + + private boolean dependsOn(IPluginDescriptor descriptor0, IPluginDescriptor descriptor1) { + + IPluginRegistry registry= Platform.getPluginRegistry(); + IPluginPrerequisite[] prerequisites= descriptor0.getPluginPrerequisites(); + + for (int i= 0; i < prerequisites.length; i++) { + IPluginPrerequisite prerequisite= prerequisites[i]; + String id= prerequisite.getUniqueIdentifier(); + IPluginDescriptor descriptor= registry.getPluginDescriptor(id); + + if (descriptor != null && (descriptor.equals(descriptor1) || dependsOn(descriptor, descriptor1))) + return true; + } + + return false; + } + + private static JavaEditorTextHoverDescriptor[] createDescriptors(IConfigurationElement[] elements) { + List result= new ArrayList(elements.length); + for (int i= 0; i < elements.length; i++) { + IConfigurationElement element= elements[i]; + if (HOVER_TAG.equals(element.getName())) { + JavaEditorTextHoverDescriptor desc= new JavaEditorTextHoverDescriptor(element); + result.add(desc); + } + } + Collections.sort(result); + return (JavaEditorTextHoverDescriptor[])result.toArray(new JavaEditorTextHoverDescriptor[result.size()]); + } + + private static void initializeFromPreferences(JavaEditorTextHoverDescriptor[] hovers) { + String compiledTextHoverModifiers= PHPeclipsePlugin.getDefault().getPreferenceStore().getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS); + + StringTokenizer tokenizer= new StringTokenizer(compiledTextHoverModifiers, VALUE_SEPARATOR); + HashMap idToModifier= new HashMap(tokenizer.countTokens() / 2); + + while (tokenizer.hasMoreTokens()) { + String id= tokenizer.nextToken(); + if (tokenizer.hasMoreTokens()) + idToModifier.put(id, tokenizer.nextToken()); + } + + String compiledTextHoverModifierMasks= PHPeclipsePlugin.getDefault().getPreferenceStore().getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS); + + tokenizer= new StringTokenizer(compiledTextHoverModifierMasks, VALUE_SEPARATOR); + HashMap idToModifierMask= new HashMap(tokenizer.countTokens() / 2); + + while (tokenizer.hasMoreTokens()) { + String id= tokenizer.nextToken(); + if (tokenizer.hasMoreTokens()) + idToModifierMask.put(id, tokenizer.nextToken()); + } + + for (int i= 0; i < hovers.length; i++) { + String modifierString= (String)idToModifier.get(hovers[i].getId()); + boolean enabled= true; + if (modifierString == null) + modifierString= DISABLED_TAG; + + if (modifierString.startsWith(DISABLED_TAG)) { + enabled= false; + modifierString= modifierString.substring(1); + } + + if (modifierString.equals(NO_MODIFIER)) + modifierString= ""; //$NON-NLS-1$ + + hovers[i].fModifierString= modifierString; + hovers[i].fIsEnabled= enabled; + hovers[i].fStateMask= computeStateMask(modifierString); + if (hovers[i].fStateMask == -1) { + // Fallback: use stored modifier masks + try { + hovers[i].fStateMask= Integer.parseInt((String)idToModifierMask.get(hovers[i].getId())); + } catch (NumberFormatException ex) { + hovers[i].fStateMask= -1; + } + // Fix modifier string + int stateMask= hovers[i].fStateMask; + if (stateMask == -1) + hovers[i].fModifierString=""; //$NON-NLS-1$ + else + hovers[i].fModifierString= EditorUtility.getModifierString(stateMask); + } + } + } + + /** + * Returns the configured modifier getStateMask for this hover. + * + * @return the hover modifier stateMask or -1 if no hover is configured + */ + public int getStateMask() { + return fStateMask; + } + + /** + * Returns the modifier String as set in the preference store. + * + * @return the modifier string + */ + public String getModifierString() { + return fModifierString; + } + + /** + * Returns whether this hover is enabled or not. + * + * @return true if enabled + */ + public boolean isEnabled() { + return fIsEnabled; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaEditorTextHoverProxy.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaEditorTextHoverProxy.java new file mode 100644 index 0000000..9b08fae --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaEditorTextHoverProxy.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package net.sourceforge.phpdt.internal.ui.text.java.hover; + +import net.sourceforge.phpdt.ui.text.java.hover.IJavaEditorTextHover; + +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.ui.IEditorPart; + + +/** + * Proxy for JavaEditorTextHovers. + * + * @since 2.1 + */ +public class JavaEditorTextHoverProxy extends AbstractJavaEditorTextHover { + + private JavaEditorTextHoverDescriptor fHoverDescriptor; + private IJavaEditorTextHover fHover; + + public JavaEditorTextHoverProxy(JavaEditorTextHoverDescriptor descriptor, IEditorPart editor) { + fHoverDescriptor= descriptor; + setEditor(editor); + } + + /* + * @see IJavaEditorTextHover#setEditor(IEditorPart) + */ + public void setEditor(IEditorPart editor) { + super.setEditor(editor); + + if (fHover != null) + fHover.setEditor(getEditor()); + } + + public boolean isEnabled() { + return true; + } + + /* + * @see ITextHover#getHoverRegion(ITextViewer, int) + */ + public IRegion getHoverRegion(ITextViewer textViewer, int offset) { + if (!isEnabled() || fHoverDescriptor == null) + return null; + + if (isCreated() || createHover()) + return fHover.getHoverRegion(textViewer, offset); + else + return null; + } + + /* + * @see ITextHover#getHoverInfo(ITextViewer, IRegion) + */ + public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { + if (!isEnabled() || fHoverDescriptor == null) + return null; + + if (isCreated() || createHover()) + return fHover.getHoverInfo(textViewer, hoverRegion); + else + return null; + } + + private boolean isCreated() { + return fHover != null; + } + + private boolean createHover() { + fHover= fHoverDescriptor.createTextHover(); + if (fHover != null) + fHover.setEditor(getEditor()); + return isCreated(); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.java new file mode 100644 index 0000000..711f49d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text.java.hover; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +class JavaHoverMessages { + + private static final String RESOURCE_BUNDLE= "net.sourceforge.phpdt.internal.ui.text.java.hover.JavaHoverMessages";//$NON-NLS-1$ + + private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + private JavaHoverMessages() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.properties new file mode 100644 index 0000000..2a9d7f5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.properties @@ -0,0 +1,14 @@ +############################################################################### +# Copyright (c) 2000, 2003 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Common Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/cpl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### + +TypeHover.more_to_come=\ ... + +JavaTextHover.createTextHover=Could not create java text hover diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaProblemHover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaProblemHover.java new file mode 100644 index 0000000..1ca1d0b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaProblemHover.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package net.sourceforge.phpdt.internal.ui.text.java.hover; + +import java.util.Iterator; + +import net.sourceforge.phpdt.ui.PreferenceConstants; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.phpeditor.IJavaAnnotation; +import net.sourceforge.phpeclipse.phpeditor.JavaAnnotationIterator; +import net.sourceforge.phpeclipse.phpeditor.PHPUnitEditor; + +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.externaltools.internal.ant.editor.derived.HTMLPrinter; +import org.eclipse.ui.texteditor.IDocumentProvider; + + +public class JavaProblemHover extends AbstractJavaEditorTextHover { + + /* + * Formats a message as HTML text. + */ + private String formatMessage(String message) { + StringBuffer buffer= new StringBuffer(); + HTMLPrinter.addPageProlog(buffer); + HTMLPrinter.addParagraph(buffer, HTMLPrinter.convertToHTMLContent(message)); + HTMLPrinter.addPageEpilog(buffer); + return buffer.toString(); + } + + /* + * @see ITextHover#getHoverInfo(ITextViewer, IRegion) + */ + public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { + + if (getEditor() == null) + return null; + + IDocumentProvider provider= PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider(); + IAnnotationModel model= provider.getAnnotationModel(getEditor().getEditorInput()); + + if (model != null) { + Iterator e= new JavaAnnotationIterator(model, true); + while (e.hasNext()) { + Annotation a= (Annotation) e.next(); + Position p= model.getPosition(a); + if (p.overlapsWith(hoverRegion.getOffset(), hoverRegion.getLength())) { + String msg= ((IJavaAnnotation) a).getMessage(); + if (msg != null && msg.trim().length() > 0) + return formatMessage(msg); + } + } + } + + return null; + } + + /* + * @see IJavaEditorTextHover#setEditor(IEditorPart) + */ + public void setEditor(IEditorPart editor) { + if (editor instanceof PHPUnitEditor) + super.setEditor(editor); + else + super.setEditor(null); + } + + static boolean isJavaProblemHover(String id) { + return PreferenceConstants.ID_PROBLEM_HOVER.equals(id); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaSourceHover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaSourceHover.java new file mode 100644 index 0000000..786076f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaSourceHover.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package net.sourceforge.phpdt.internal.ui.text.java.hover; + +import java.io.IOException; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IMember; +import net.sourceforge.phpdt.core.ISourceReference; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.ui.text.PHPCodeReader; +import net.sourceforge.phpdt.internal.ui.viewsupport.JavaElementLabels; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.ui.externaltools.internal.ant.editor.derived.HTMLPrinter; + +/** + * Provides source as hover info for Java elements. + */ +public class JavaSourceHover extends AbstractJavaEditorTextHover { + + private final int LABEL_FLAGS= JavaElementLabels.ALL_FULLY_QUALIFIED + | JavaElementLabels.M_PRE_RETURNTYPE | JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_EXCEPTIONS + | JavaElementLabels.F_PRE_TYPE_SIGNATURE; + + + /* + * @see JavaElementHover + */ + protected String getHoverInfo(IJavaElement[] result) { + int nResults= result.length; + StringBuffer buffer= new StringBuffer(); + + if (nResults > 1) { + + for (int i= 0; i < result.length; i++) { + HTMLPrinter.startBulletList(buffer); + IJavaElement curr= result[i]; + if (curr instanceof IMember) + HTMLPrinter.addBullet(buffer, getInfoText((IMember) curr)); + HTMLPrinter.endBulletList(buffer); + } + + } else { + + IJavaElement curr= result[0]; + if (curr instanceof IMember && curr instanceof ISourceReference) { + HTMLPrinter.addSmallHeader(buffer, getInfoText(((IMember)curr))); + try { + String source= ((ISourceReference)curr).getSource(); + source= removeLeadingComments(source); + HTMLPrinter.addParagraph(buffer, "
        "); //$NON-NLS-1$
        +					HTMLPrinter.addParagraph(buffer, source);
        +					HTMLPrinter.addParagraph(buffer, "
        "); //$NON-NLS-1$ + } catch (JavaModelException ex) { + // only write small header + } + } + } + + if (buffer.length() > 0) { + HTMLPrinter.insertPageProlog(buffer, 0); + HTMLPrinter.addPageEpilog(buffer); + return buffer.toString(); + } + + return null; + } + + private String getInfoText(IMember member) { + return JavaElementLabels.getElementLabel(member, LABEL_FLAGS); + } + + private String removeLeadingComments(String source) { + PHPCodeReader reader= new PHPCodeReader(); + IDocument document= new Document(source); + int i; + try { + reader.configureForwardReader(document, 0, document.getLength(), true, false); + int c= reader.read(); + while (c != -1 && (c == '\r' || c == '\n')) { + c= reader.read(); + } + i= reader.getOffset(); + reader.close(); + } catch (IOException ex) { + i= 0; + } finally { + try { + if (reader != null) + reader.close(); + } catch (IOException ex) { + PHPeclipsePlugin.log(ex); + } + } + + if (i < 0) + return source; + return source.substring(i); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/util/PHPFileUtil.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/util/PHPFileUtil.java index 4917de5..1f8c8fe 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/util/PHPFileUtil.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/util/PHPFileUtil.java @@ -11,13 +11,106 @@ import org.eclipse.core.resources.IFile; * */ public class PHPFileUtil { - static public boolean isPHPFile(IFile file) { - if ("php".equalsIgnoreCase(file.getFileExtension()) - || "php3".equalsIgnoreCase(file.getFileExtension()) - || "php4".equalsIgnoreCase(file.getFileExtension()) - || "inc".equalsIgnoreCase(file.getFileExtension())) { - return true; + public final static char[] SUFFIX_php = ".php".toCharArray(); //$NON-NLS-1$ + public final static char[] SUFFIX_PHP = ".PHP".toCharArray(); //$NON-NLS-1$ + public final static char[] SUFFIX_php3 = ".php3".toCharArray(); //$NON-NLS-1$ + public final static char[] SUFFIX_PHP3 = ".PHP3".toCharArray(); //$NON-NLS-1$ + public final static char[] SUFFIX_php4 = ".php4".toCharArray(); //$NON-NLS-1$ + public final static char[] SUFFIX_PHP4 = ".PHP4".toCharArray(); //$NON-NLS-1$ + public final static char[] SUFFIX_inc = ".inc".toCharArray(); //$NON-NLS-1$ + public final static char[] SUFFIX_INC = ".INC".toCharArray(); //$NON-NLS-1$ + + public static boolean isPHPFile(IFile file) { + String extension = file.getFileExtension(); + return isPHPFileName(file.getLocation().toString()); + } + + /** + * Returns true iff str.toLowerCase().endsWith(".php") + * implementation is not creating extra strings. + */ + public final static boolean isPHPFileName(String name) { + return isPHP_FileName(name) || isPHP3_FileName(name) || isPHP4_FileName(name) || isINC_FileName(name); + } + // static public boolean isPHPFile(String extension) { + // if ("php".equalsIgnoreCase(extension) + // || "php3".equalsIgnoreCase(extension) + // || "php4".equalsIgnoreCase(extension) + // || "inc".equalsIgnoreCase(extension)) { + // return true; + // } + // return false; + // } + + /** + * Returns true iff str.toLowerCase().endsWith(".php") + * implementation is not creating extra strings. + */ + private final static boolean isPHP_FileName(String name) { + int nameLength = name == null ? 0 : name.length(); + int suffixLength = SUFFIX_PHP.length; + if (nameLength < suffixLength) + return false; + + for (int i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) { + char c = name.charAt(offset + i); + if (c != SUFFIX_php[i] && c != SUFFIX_PHP[i]) + return false; + } + return true; + } + + /** + * Returns true iff str.toLowerCase().endsWith(".php3") + * implementation is not creating extra strings. + */ + private final static boolean isPHP3_FileName(String name) { + int nameLength = name == null ? 0 : name.length(); + int suffixLength = SUFFIX_PHP3.length; + if (nameLength < suffixLength) + return false; + + for (int i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) { + char c = name.charAt(offset + i); + if (c != SUFFIX_php3[i] && c != SUFFIX_PHP3[i]) + return false; + } + return true; + } + + /** + * Returns true iff str.toLowerCase().endsWith(".php4") + * implementation is not creating extra strings. + */ + private final static boolean isPHP4_FileName(String name) { + int nameLength = name == null ? 0 : name.length(); + int suffixLength = SUFFIX_PHP4.length; + if (nameLength < suffixLength) + return false; + + for (int i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) { + char c = name.charAt(offset + i); + if (c != SUFFIX_php4[i] && c != SUFFIX_PHP4[i]) + return false; + } + return true; + } + + /** + * Returns true iff str.toLowerCase().endsWith(".inc") + * implementation is not creating extra strings. + */ + private final static boolean isINC_FileName(String name) { + int nameLength = name == null ? 0 : name.length(); + int suffixLength = SUFFIX_INC.length; + if (nameLength < suffixLength) + return false; + + for (int i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) { + char c = name.charAt(offset + i); + if (c != SUFFIX_inc[i] && c != SUFFIX_INC[i]) + return false; } - return false; + return true; } } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/util/SWTUtil.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/util/SWTUtil.java index 5344dc0..ffdd686 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/util/SWTUtil.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/util/SWTUtil.java @@ -1,12 +1,16 @@ -/* - * (c) Copyright IBM Corp. 2000, 2001. - * All Rights Reserved. - */ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ package net.sourceforge.phpdt.internal.ui.util; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.util.Assert; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.DragSource; import org.eclipse.swt.dnd.DropTarget; @@ -18,8 +22,13 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.ScrollBar; import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.Widget; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.Assert; + /** * Utility class to simplify access to some SWT resources. */ @@ -66,6 +75,8 @@ public class SWTUtil { * Returns a width hint for a button control. */ public static int getButtonWidthHint(Button button) { + if (button.getFont().equals(JFaceResources.getDefaultFont())) + button.setFont(JFaceResources.getDialogFont()); PixelConverter converter= new PixelConverter(button); int widthHint= converter.convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH); return Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x); @@ -75,6 +86,8 @@ public class SWTUtil { * Returns a height hint for a button control. */ public static int getButtonHeigthHint(Button button) { + if (button.getFont().equals(JFaceResources.getDefaultFont())) + button.setFont(JFaceResources.getDialogFont()); PixelConverter converter= new PixelConverter(button); return converter.convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT); } @@ -94,7 +107,16 @@ public class SWTUtil { ((GridData)gd).heightHint= getButtonHeigthHint(button); ((GridData)gd).widthHint= getButtonWidthHint(button); } - } + } + + public static int getTableHeightHint(Table table, int rows) { + if (table.getFont().equals(JFaceResources.getDefaultFont())) + table.setFont(JFaceResources.getDialogFont()); + int result= table.getItemHeight() * rows + table.getHeaderHeight(); + if (table.getLinesVisible()) + result+= table.getGridLineWidth() * (rows - 1); + return result; + } -} \ No newline at end of file +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/AppearanceAwareLabelProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/AppearanceAwareLabelProvider.java new file mode 100644 index 0000000..265ccbf --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/AppearanceAwareLabelProvider.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.viewsupport; + +import net.sourceforge.phpdt.ui.PreferenceConstants; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.LabelProviderChangedEvent; + + +/** + * JavaUILabelProvider that respects settings from the Appearance preference page. + * Triggers a viewer update when a preference changes. + */ +public class AppearanceAwareLabelProvider extends JavaUILabelProvider implements IPropertyChangeListener { + + public final static int DEFAULT_TEXTFLAGS= JavaElementLabels.ROOT_VARIABLE | JavaElementLabels.M_PARAMETER_TYPES | + JavaElementLabels.M_APP_RETURNTYPE | JavaElementLabels.REFERENCED_ROOT_POST_QUALIFIED; + public final static int DEFAULT_IMAGEFLAGS= JavaElementImageProvider.OVERLAY_ICONS; + + private int fTextFlagMask; + private int fImageFlagMask; + + /** + * Constructor for AppearanceAwareLabelProvider. + */ + public AppearanceAwareLabelProvider(int textFlags, int imageFlags) { + super(textFlags, imageFlags); + initMasks(); + PreferenceConstants.getPreferenceStore().addPropertyChangeListener(this); + } + + /** + * Creates a labelProvider with DEFAULT_TEXTFLAGS and DEFAULT_IMAGEFLAGS + */ + public AppearanceAwareLabelProvider() { + this(DEFAULT_TEXTFLAGS, DEFAULT_IMAGEFLAGS); + } + + private void initMasks() { + IPreferenceStore store= PreferenceConstants.getPreferenceStore(); + fTextFlagMask= -1; + if (!store.getBoolean(PreferenceConstants.APPEARANCE_METHOD_RETURNTYPE)) { + fTextFlagMask ^= JavaElementLabels.M_APP_RETURNTYPE; + } + if (!store.getBoolean(PreferenceConstants.APPEARANCE_COMPRESS_PACKAGE_NAMES)) { + fTextFlagMask ^= JavaElementLabels.P_COMPRESSED; + } + + fImageFlagMask= -1; + } + + /* + * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event) { + String property= event.getProperty(); + if (property.equals(PreferenceConstants.APPEARANCE_METHOD_RETURNTYPE) + || property.equals(PreferenceConstants.APPEARANCE_PKG_NAME_PATTERN_FOR_PKG_VIEW) + || property.equals(PreferenceConstants.APPEARANCE_COMPRESS_PACKAGE_NAMES)) { + initMasks(); + LabelProviderChangedEvent lpEvent= new LabelProviderChangedEvent(this, null); // refresh all + fireLabelProviderChanged(lpEvent); + } + } + + /* + * @see IBaseLabelProvider#dispose() + */ + public void dispose() { + PreferenceConstants.getPreferenceStore().removePropertyChangeListener(this); + super.dispose(); + } + + /* + * @see JavaUILabelProvider#evaluateImageFlags() + */ + protected int evaluateImageFlags(Object element) { + return getImageFlags() & fImageFlagMask; + } + + /* + * @see JavaUILabelProvider#evaluateTextFlags() + */ + protected int evaluateTextFlags(Object element) { + return getTextFlags() & fTextFlagMask; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/DecoratingJavaLabelProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/DecoratingJavaLabelProvider.java new file mode 100644 index 0000000..921fe54 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/DecoratingJavaLabelProvider.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.viewsupport; + +import net.sourceforge.phpdt.ui.OverrideIndicatorLabelDecorator; +import net.sourceforge.phpdt.ui.ProblemsLabelDecorator; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.DecoratingLabelProvider; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.IDecoratorManager; +import org.eclipse.ui.PlatformUI; + + +/** + * Decorator prepared for the switch to use lightweight label decorators: + * uncomment the lbale decorator entries in plugin.xml and change + * USE_LIGHTWEIGHT to true. + * Certain views don't want problems or override indicators, so they signal this + * in the constructor. So on each getImage the corrsponding decorators are + * turned off and on again. + */ +public class DecoratingJavaLabelProvider extends DecoratingLabelProvider { + + private static final boolean USE_LIGHTWEIGHT= false; + + private static final String PROBLEM_DECORATOR_ID= "net.sourceforge.phpdt.ui.problem.decorator"; //$NON-NLS-1$ + private static final String OVERRIDE_DECORATOR_ID= "net.sourceforge.phpdt.ui.override.decorator"; //$NON-NLS-1$ + + private boolean fUseErrorTick; + private boolean fUseOverride; + + /** + * Decorating label provider for Java. Combines a JavaUILabelProvider + * with problem and override indicuator with the workbench decorator (label + * decorator extension point). + */ + public DecoratingJavaLabelProvider(JavaUILabelProvider labelProvider) { + this(labelProvider, true, true); + } + + /** + * Decorating label provider for Java. Combines a JavaUILabelProvider + * (if enabled with problem and override indicator) with the workbench + * decorator (label decorator extension point). + */ + public DecoratingJavaLabelProvider(JavaUILabelProvider labelProvider, boolean errorTick, boolean override) { + super(labelProvider, PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator()); + fUseErrorTick= errorTick; + fUseOverride= override; + if (!USE_LIGHTWEIGHT) { + if (errorTick) { + labelProvider.addLabelDecorator(new ProblemsLabelDecorator(null)); + } + if (override) { + labelProvider.addLabelDecorator(new OverrideIndicatorLabelDecorator(null)); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object) + */ + public Image getImage(Object element) { + if (USE_LIGHTWEIGHT) { + IDecoratorManager manager= PlatformUI.getWorkbench().getDecoratorManager(); + + boolean disableErrorTick= manager.getEnabled(PROBLEM_DECORATOR_ID) && !fUseErrorTick; + boolean disableOverride= manager.getEnabled(OVERRIDE_DECORATOR_ID) && !fUseOverride; + try { + if (disableErrorTick) { + manager.setEnabled(PROBLEM_DECORATOR_ID, false); + } + if (disableOverride) { + manager.setEnabled(OVERRIDE_DECORATOR_ID, false); + } + Image image= super.getImage(element); + if (disableErrorTick) { + manager.setEnabled(PROBLEM_DECORATOR_ID, true); + } + if (disableOverride) { + manager.setEnabled(OVERRIDE_DECORATOR_ID, true); + } + return image; + } catch (CoreException e) { + PHPeclipsePlugin.log(e); + } + } + return super.getImage(element); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) + */ + public String getText(Object element) { + if (USE_LIGHTWEIGHT) { + IDecoratorManager manager= PlatformUI.getWorkbench().getDecoratorManager(); + + boolean disableErrorTick= manager.getEnabled(PROBLEM_DECORATOR_ID) && !fUseErrorTick; + boolean disableOverride= manager.getEnabled(OVERRIDE_DECORATOR_ID) && !fUseOverride; + try { + if (disableErrorTick) { + manager.setEnabled(PROBLEM_DECORATOR_ID, false); + } + if (disableOverride) { + manager.setEnabled(OVERRIDE_DECORATOR_ID, false); + } + String text= super.getText(element); + if (disableErrorTick) { + manager.setEnabled(PROBLEM_DECORATOR_ID, true); + } + if (disableOverride) { + manager.setEnabled(OVERRIDE_DECORATOR_ID, true); + } + return text; + } catch (CoreException e) { + PHPeclipsePlugin.log(e); + } + } + return super.getText(element); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/IProblemChangedListener.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/IProblemChangedListener.java new file mode 100644 index 0000000..ed030b0 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/IProblemChangedListener.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.viewsupport; + +import org.eclipse.core.resources.IResource; + +/** + * Can be added to a ProblemMarkerManager to get notified about problem + * marker changes. Used to update error ticks. + */ +public interface IProblemChangedListener { + + /** + * Called when problems changed. This call is posted in an aynch exec, therefore passed + * resources must not exist. + * @param changedElements A set with elements of type IResource that + * describe the resources that had an problem change. + * @param isMarkerChange If set to true, the change was a marker change, if + * false, the change came from an annotation model modification. + */ + void problemsChanged(IResource[] changedResources, boolean isMarkerChange); + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/ImageImageDescriptor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/ImageImageDescriptor.java new file mode 100644 index 0000000..2dd5a89 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/ImageImageDescriptor.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.viewsupport; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; + +import org.eclipse.jface.resource.ImageDescriptor; + +/** + */ +public class ImageImageDescriptor extends ImageDescriptor { + + private Image fImage; + + /** + * Constructor for ImagImageDescriptor. + */ + public ImageImageDescriptor(Image image) { + super(); + fImage= image; + } + + /* (non-Javadoc) + * @see ImageDescriptor#getImageData() + */ + public ImageData getImageData() { + return fImage.getImageData(); + } + + /* (non-Javadoc) + * @see Object#equals(Object) + */ + public boolean equals(Object obj) { + return (obj != null) && getClass().equals(obj.getClass()) && fImage.equals(((ImageImageDescriptor)obj).fImage); + } + + /* (non-Javadoc) + * @see Object#hashCode() + */ + public int hashCode() { + return fImage.hashCode(); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaElementImageProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaElementImageProvider.java new file mode 100644 index 0000000..1b842ab --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaElementImageProvider.java @@ -0,0 +1,421 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.viewsupport; + +import net.sourceforge.phpdt.core.Flags; +import net.sourceforge.phpdt.core.IField; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IMember; +import net.sourceforge.phpdt.core.IMethod; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.ui.PHPUiImages; +import net.sourceforge.phpdt.internal.ui.PHPUIMessages; +import net.sourceforge.phpdt.ui.JavaElementImageDescriptor; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.util.Assert; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.model.IWorkbenchAdapter; + +/** + * Default strategy of the Java plugin for the construction of Java element icons. + */ +public class JavaElementImageProvider { + + /** + * Flags for the JavaImageLabelProvider: + * Generate images with overlays. + */ + public final static int OVERLAY_ICONS = 0x1; + + /** + * Generate small sized images. + */ + public final static int SMALL_ICONS = 0x2; + + /** + * Use the 'light' style for rendering types. + */ + public final static int LIGHT_TYPE_ICONS = 0x4; + + public static final Point SMALL_SIZE = new Point(16, 16); + public static final Point BIG_SIZE = new Point(22, 16); + + private static ImageDescriptor DESC_OBJ_PROJECT_CLOSED; + private static ImageDescriptor DESC_OBJ_PROJECT; + private static ImageDescriptor DESC_OBJ_FOLDER; + { + ISharedImages images = PHPeclipsePlugin.getDefault().getWorkbench().getSharedImages(); + DESC_OBJ_PROJECT_CLOSED = images.getImageDescriptor(ISharedImages.IMG_OBJ_PROJECT_CLOSED); + DESC_OBJ_PROJECT = images.getImageDescriptor(ISharedImages.IMG_OBJ_PROJECT); + DESC_OBJ_FOLDER = images.getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER); + } + + private ImageDescriptorRegistry fRegistry; + + public JavaElementImageProvider() { + fRegistry = null; // lazy initialization + } + + /** + * Returns the icon for a given element. The icon depends on the element type + * and element properties. If configured, overlay icons are constructed for + * ISourceReferences. + * @param flags Flags as defined by the JavaImageLabelProvider + */ + public Image getImageLabel(Object element, int flags) { + return getImageLabel(computeDescriptor(element, flags)); + } + + private Image getImageLabel(ImageDescriptor descriptor) { + if (descriptor == null) + return null; + return getRegistry().get(descriptor); + } + + private ImageDescriptorRegistry getRegistry() { + if (fRegistry == null) { + fRegistry = PHPeclipsePlugin.getImageDescriptorRegistry(); + } + return fRegistry; + } + + private ImageDescriptor computeDescriptor(Object element, int flags) { + if (element instanceof IJavaElement) { + return getJavaImageDescriptor((IJavaElement) element, flags); + } else if (element instanceof IFile) { + IFile file = (IFile) element; + if ("java".equals(file.getFileExtension())) { //$NON-NLS-1$ + return getCUResourceImageDescriptor(file, flags); // image for a CU not on the build path + } + return getWorkbenchImageDescriptor(file, flags); + } else if (element instanceof IAdaptable) { + return getWorkbenchImageDescriptor((IAdaptable) element, flags); + } + return null; + } + + private static boolean showOverlayIcons(int flags) { + return (flags & OVERLAY_ICONS) != 0; + } + + private static boolean useSmallSize(int flags) { + return (flags & SMALL_ICONS) != 0; + } + + private static boolean useLightIcons(int flags) { + return (flags & LIGHT_TYPE_ICONS) != 0; + } + + /** + * Returns an image descriptor for a compilatio unit not on the class path. + * The descriptor includes overlays, if specified. + */ + public ImageDescriptor getCUResourceImageDescriptor(IFile file, int flags) { + Point size = useSmallSize(flags) ? SMALL_SIZE : BIG_SIZE; + return new JavaElementImageDescriptor(PHPUiImages.DESC_OBJS_CUNIT_RESOURCE, 0, size); + } + + /** + * Returns an image descriptor for a java element. The descriptor includes overlays, if specified. + */ + public ImageDescriptor getJavaImageDescriptor(IJavaElement element, int flags) { + int adornmentFlags = computeJavaAdornmentFlags(element, flags); + Point size = useSmallSize(flags) ? SMALL_SIZE : BIG_SIZE; + return new JavaElementImageDescriptor(getBaseImageDescriptor(element, flags), adornmentFlags, size); + } + + /** + * Returns an image descriptor for a IAdaptable. The descriptor includes overlays, if specified (only error ticks apply). + * Returns null if no image could be found. + */ + public ImageDescriptor getWorkbenchImageDescriptor(IAdaptable adaptable, int flags) { + IWorkbenchAdapter wbAdapter = (IWorkbenchAdapter) adaptable.getAdapter(IWorkbenchAdapter.class); + if (wbAdapter == null) { + return null; + } + ImageDescriptor descriptor = wbAdapter.getImageDescriptor(adaptable); + if (descriptor == null) { + return null; + } + + Point size = useSmallSize(flags) ? SMALL_SIZE : BIG_SIZE; + return new JavaElementImageDescriptor(descriptor, 0, size); + } + + // ---- Computation of base image key ------------------------------------------------- + + /** + * Returns an image descriptor for a java element. This is the base image, no overlays. + */ + public ImageDescriptor getBaseImageDescriptor(IJavaElement element, int renderFlags) { + IType type = null; + boolean isInterface = false; + try { + switch (element.getElementType()) { + case IJavaElement.INITIALIZER : + return PHPUiImages.DESC_MISC_PRIVATE; // 23479 + case IJavaElement.METHOD : + IMember member = (IMember) element; + type = member.getDeclaringType(); + isInterface = (type != null) && member.getDeclaringType().isInterface(); + return getMethodImageDescriptor(isInterface, member.getFlags()); + case IJavaElement.FIELD : + IField field = (IField) element; + return getFieldImageDescriptor(field.getDeclaringType().isInterface(), field.getFlags()); + + case IJavaElement.PACKAGE_DECLARATION : + return PHPUiImages.DESC_OBJS_PACKDECL; + + case IJavaElement.IMPORT_DECLARATION : + return PHPUiImages.DESC_OBJS_IMPDECL; + + case IJavaElement.IMPORT_CONTAINER : + return PHPUiImages.DESC_OBJS_IMPCONT; + + case IJavaElement.TYPE : + { + type = (IType) element; + isInterface = type.isInterface(); + + if (useLightIcons(renderFlags)) { + return isInterface ? PHPUiImages.DESC_OBJS_INTERFACEALT : PHPUiImages.DESC_OBJS_CLASSALT; + } + boolean isInner = type.getDeclaringType() != null; + return getTypeImageDescriptor(isInterface, isInner, type.getFlags()); + } + + case IJavaElement.PACKAGE_FRAGMENT_ROOT : + { + IPackageFragmentRoot root = (IPackageFragmentRoot) element; + // if (root.isArchive()) { + // IPath attach= root.getSourceAttachmentPath(); + // if (root.isExternal()) { + // if (attach == null) { + // return PHPUiImages.DESC_OBJS_EXTJAR; + // } else { + // return PHPUiImages.DESC_OBJS_EXTJAR_WSRC; + // } + // } else { + // if (attach == null) { + // return PHPUiImages.DESC_OBJS_JAR; + // } else { + // return PHPUiImages.DESC_OBJS_JAR_WSRC; + // } + // } + // } else { + return PHPUiImages.DESC_OBJS_PACKFRAG_ROOT; + // } + } + + case IJavaElement.PACKAGE_FRAGMENT : + return getPackageFragmentIcon(element, renderFlags); + + case IJavaElement.COMPILATION_UNIT : + return PHPUiImages.DESC_OBJS_CUNIT; + + case IJavaElement.CLASS_FILE : + /* this is too expensive for large packages + try { + IClassFile cfile= (IClassFile)element; + if (cfile.isClass()) + return PHPUiImages.IMG_OBJS_CFILECLASS; + return PHPUiImages.IMG_OBJS_CFILEINT; + } catch(JavaModelException e) { + // fall through; + }*/ + return PHPUiImages.DESC_OBJS_CFILE; + + case IJavaElement.JAVA_PROJECT : + IJavaProject jp = (IJavaProject) element; + if (jp.getProject().isOpen()) { + IProject project = jp.getProject(); + IWorkbenchAdapter adapter = (IWorkbenchAdapter) project.getAdapter(IWorkbenchAdapter.class); + if (adapter != null) { + ImageDescriptor result = adapter.getImageDescriptor(project); + if (result != null) + return result; + } + return DESC_OBJ_PROJECT; + } + return DESC_OBJ_PROJECT_CLOSED; + + case IJavaElement.JAVA_MODEL : + return PHPUiImages.DESC_OBJS_JAVA_MODEL; + } + + Assert.isTrue(false, PHPUIMessages.getString("JavaImageLabelprovider.assert.wrongImage")); //$NON-NLS-1$ + return null; //$NON-NLS-1$ + + } catch (JavaModelException e) { + if (e.isDoesNotExist()) + return PHPUiImages.DESC_OBJS_UNKNOWN; + PHPeclipsePlugin.log(e); + return PHPUiImages.DESC_OBJS_GHOST; + } + } + + protected ImageDescriptor getPackageFragmentIcon(IJavaElement element, int renderFlags) throws JavaModelException { + // IPackageFragment fragment= (IPackageFragment)element; + // boolean containsJavaElements= false; + // try { + // containsJavaElements= fragment.hasChildren(); + // } catch(JavaModelException e) { + // // assuming no children; + // } + // if(!containsJavaElements && (fragment.getNonJavaResources().length > 0)) + // return PHPUiImages.DESC_OBJS_EMPTY_PACKAGE_RESOURCES; + // else if (!containsJavaElements) + // return PHPUiImages.DESC_OBJS_EMPTY_PACKAGE; + return PHPUiImages.DESC_OBJS_PACKAGE; + } + + public void dispose() { + } + + // ---- Methods to compute the adornments flags --------------------------------- + + private int computeJavaAdornmentFlags(IJavaElement element, int renderFlags) { + int flags = 0; + if (showOverlayIcons(renderFlags) && element instanceof IMember) { + try { + IMember member = (IMember) element; + + if (element.getElementType() == IJavaElement.METHOD && ((IMethod) element).isConstructor()) + flags |= JavaElementImageDescriptor.CONSTRUCTOR; + + int modifiers = member.getFlags(); + if (Flags.isAbstract(modifiers) && confirmAbstract(member)) + flags |= JavaElementImageDescriptor.ABSTRACT; + if (Flags.isFinal(modifiers) || isInterfaceField(member)) + flags |= JavaElementImageDescriptor.FINAL; + // if (Flags.isSynchronized(modifiers) && confirmSynchronized(member)) + // flags |= JavaElementImageDescriptor.SYNCHRONIZED; + if (Flags.isStatic(modifiers) || isInterfaceField(member)) + flags |= JavaElementImageDescriptor.STATIC; + + // if (member.getElementType() == IJavaElement.TYPE) { + // if (JavaModelUtil.hasMainMethod((IType) member)) { + // flags |= JavaElementImageDescriptor.RUNNABLE; + // } + // } + } catch (JavaModelException e) { + // do nothing. Can't compute runnable adornment or get flags + } + } + return flags; + } + + private static boolean confirmAbstract(IMember element) throws JavaModelException { + // never show the abstract symbol on interfaces or members in interfaces + if (element.getElementType() == IJavaElement.TYPE) { + return ((IType) element).isClass(); + } + return element.getDeclaringType().isClass(); + } + + private static boolean isInterfaceField(IMember element) throws JavaModelException { + // always show the final && static symbol on interface fields + if (element.getElementType() == IJavaElement.FIELD) { + return element.getDeclaringType().isInterface(); + } + return false; + } + + private static boolean confirmSynchronized(IJavaElement member) { + // Synchronized types are allowed but meaningless. + return member.getElementType() != IJavaElement.TYPE; + } + + public static ImageDescriptor getMethodImageDescriptor(boolean isInInterface, int flags) { + if (Flags.isPublic(flags) || isInInterface) + return PHPUiImages.DESC_MISC_PUBLIC; + if (Flags.isProtected(flags)) + return PHPUiImages.DESC_MISC_PROTECTED; + if (Flags.isPrivate(flags)) + return PHPUiImages.DESC_MISC_PRIVATE; + + return PHPUiImages.DESC_MISC_DEFAULT; + } + + public static ImageDescriptor getFieldImageDescriptor(boolean isInInterface, int flags) { + if (Flags.isPublic(flags) || isInInterface) + return PHPUiImages.DESC_FIELD_PUBLIC; + if (Flags.isProtected(flags)) + return PHPUiImages.DESC_FIELD_PROTECTED; + if (Flags.isPrivate(flags)) + return PHPUiImages.DESC_FIELD_PRIVATE; + + return PHPUiImages.DESC_FIELD_DEFAULT; + } + + public static ImageDescriptor getTypeImageDescriptor(boolean isInterface, boolean isInner, int flags) { + if (isInner) { + if (isInterface) { + return getInnerInterfaceImageDescriptor(flags); + } else { + return getInnerClassImageDescriptor(flags); + } + } else { + if (isInterface) { + return getInterfaceImageDescriptor(flags); + } else { + return getClassImageDescriptor(flags); + } + } + } + + private static ImageDescriptor getClassImageDescriptor(int flags) { + if (Flags.isPublic(flags) || Flags.isProtected(flags) || Flags.isPrivate(flags)) + return PHPUiImages.DESC_OBJS_CLASS; + else + return PHPUiImages.DESC_OBJS_CLASS_DEFAULT; + } + + private static ImageDescriptor getInnerClassImageDescriptor(int flags) { + if (Flags.isPublic(flags)) + return PHPUiImages.DESC_OBJS_INNER_CLASS_PUBLIC; + else if (Flags.isPrivate(flags)) + return PHPUiImages.DESC_OBJS_INNER_CLASS_PRIVATE; + else if (Flags.isProtected(flags)) + return PHPUiImages.DESC_OBJS_INNER_CLASS_PROTECTED; + else + return PHPUiImages.DESC_OBJS_INNER_CLASS_DEFAULT; + } + + private static ImageDescriptor getInterfaceImageDescriptor(int flags) { + if (Flags.isPublic(flags) || Flags.isProtected(flags) || Flags.isPrivate(flags)) + return PHPUiImages.DESC_OBJS_INTERFACE; + else + return PHPUiImages.DESC_OBJS_INTERFACE_DEFAULT; + } + + private static ImageDescriptor getInnerInterfaceImageDescriptor(int flags) { + if (Flags.isPublic(flags)) + return PHPUiImages.DESC_OBJS_INNER_INTERFACE_PUBLIC; + else if (Flags.isPrivate(flags)) + return PHPUiImages.DESC_OBJS_INNER_INTERFACE_PRIVATE; + else if (Flags.isProtected(flags)) + return PHPUiImages.DESC_OBJS_INNER_INTERFACE_PROTECTED; + else + return PHPUiImages.DESC_OBJS_INTERFACE_DEFAULT; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaElementLabels.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaElementLabels.java new file mode 100644 index 0000000..4e71612 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaElementLabels.java @@ -0,0 +1,765 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.viewsupport; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IField; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IMethod; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.Signature; +import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil; +import net.sourceforge.phpdt.internal.ui.PHPUIMessages; +import net.sourceforge.phpdt.ui.PreferenceConstants; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.ui.model.IWorkbenchAdapter; + +public class JavaElementLabels { + + /** + * Method names contain parameter types. + * e.g. foo(int) + */ + public final static int M_PARAMETER_TYPES = 1 << 0; + + /** + * Method names contain parameter names. + * e.g. foo(index) + */ + public final static int M_PARAMETER_NAMES = 1 << 1; + + /** + * Method names contain thrown exceptions. + * e.g. foo throws IOException + */ + public final static int M_EXCEPTIONS = 1 << 2; + + /** + * Method names contain return type (appended) + * e.g. foo : int + */ + public final static int M_APP_RETURNTYPE = 1 << 3; + + /** + * Method names contain return type (appended) + * e.g. int foo + */ + public final static int M_PRE_RETURNTYPE = 1 << 4; + + /** + * Method names are fully qualified. + * e.g. java.util.Vector.size + */ + public final static int M_FULLY_QUALIFIED = 1 << 5; + + /** + * Method names are post qualified. + * e.g. size - java.util.Vector + */ + public final static int M_POST_QUALIFIED = 1 << 6; + + /** + * Initializer names are fully qualified. + * e.g. java.util.Vector.{ ... } + */ + public final static int I_FULLY_QUALIFIED = 1 << 7; + + /** + * Type names are post qualified. + * e.g. { ... } - java.util.Map + */ + public final static int I_POST_QUALIFIED = 1 << 8; + + /** + * Field names contain the declared type (appended) + * e.g. int fHello + */ + public final static int F_APP_TYPE_SIGNATURE = 1 << 9; + + /** + * Field names contain the declared type (prepended) + * e.g. fHello : int + */ + public final static int F_PRE_TYPE_SIGNATURE = 1 << 10; + + /** + * Fields names are fully qualified. + * e.g. java.lang.System.out + */ + public final static int F_FULLY_QUALIFIED = 1 << 11; + + /** + * Fields names are post qualified. + * e.g. out - java.lang.System + */ + public final static int F_POST_QUALIFIED = 1 << 12; + + /** + * Type names are fully qualified. + * e.g. java.util.Map.MapEntry + */ + public final static int T_FULLY_QUALIFIED = 1 << 13; + + /** + * Type names are type container qualified. + * e.g. Map.MapEntry + */ + public final static int T_CONTAINER_QUALIFIED = 1 << 14; + + /** + * Type names are post qualified. + * e.g. MapEntry - java.util.Map + */ + public final static int T_POST_QUALIFIED = 1 << 15; + + /** + * Declarations (import container / declarartion, package declarartion) are qualified. + * e.g. java.util.Vector.class/import container + */ + public final static int D_QUALIFIED = 1 << 16; + + /** + * Declarations (import container / declarartion, package declarartion) are post qualified. + * e.g. import container - java.util.Vector.class + */ + public final static int D_POST_QUALIFIED = 1 << 17; + + /** + * Class file names are fully qualified. + * e.g. java.util.Vector.class + */ + public final static int CF_QUALIFIED = 1 << 18; + + /** + * Class file names are post qualified. + * e.g. Vector.class - java.util + */ + public final static int CF_POST_QUALIFIED = 1 << 19; + + /** + * Compilation unit names are fully qualified. + * e.g. java.util.Vector.java + */ + public final static int CU_QUALIFIED = 1 << 20; + + /** + * Compilation unit names are post qualified. + * e.g. Vector.java - java.util + */ + public final static int CU_POST_QUALIFIED = 1 << 21; + + /** + * Package names are qualified. + * e.g. MyProject/src/java.util + */ + public final static int P_QUALIFIED = 1 << 22; + + /** + * Package names are post qualified. + * e.g. java.util - MyProject/src + */ + public final static int P_POST_QUALIFIED = 1 << 23; + + /** + * Package Fragment Roots contain variable name if from a variable. + * e.g. JRE_LIB - c:\java\lib\rt.jar + */ + public final static int ROOT_VARIABLE = 1 << 24; + + /** + * Package Fragment Roots contain the project name if not an archive (prepended). + * e.g. MyProject/src + */ + public final static int ROOT_QUALIFIED = 1 << 25; + + /** + * Package Fragment Roots contain the project name if not an archive (appended). + * e.g. src - MyProject + */ + public final static int ROOT_POST_QUALIFIED = 1 << 26; + + /** + * Add root path to all elements except Package Fragment Roots and Java projects. + * e.g. java.lang.Vector - c:\java\lib\rt.jar + * Option only applies to getElementLabel + */ + public final static int APPEND_ROOT_PATH = 1 << 27; + + /** + * Add root path to all elements except Package Fragment Roots and Java projects. + * e.g. java.lang.Vector - c:\java\lib\rt.jar + * Option only applies to getElementLabel + */ + public final static int PREPEND_ROOT_PATH = 1 << 28; + + /** + * Package names are compressed. + * e.g. o*.e*.search + */ + public final static int P_COMPRESSED = 1 << 29; + + /** + * Post qualify referenced package fragement roots. For example + * jdt.jar - org.eclipse.jdt.ui if the jar is referenced + * from another project. + */ + public final static int REFERENCED_ROOT_POST_QUALIFIED = 1 << 30; + + /** + * Qualify all elements + */ + public final static int ALL_FULLY_QUALIFIED = + F_FULLY_QUALIFIED + | M_FULLY_QUALIFIED + | I_FULLY_QUALIFIED + | T_FULLY_QUALIFIED + | D_QUALIFIED + | CF_QUALIFIED + | CU_QUALIFIED + | P_QUALIFIED + | ROOT_QUALIFIED; + + /** + * Post qualify all elements + */ + public final static int ALL_POST_QUALIFIED = + F_POST_QUALIFIED + | M_POST_QUALIFIED + | I_POST_QUALIFIED + | T_POST_QUALIFIED + | D_POST_QUALIFIED + | CF_POST_QUALIFIED + | CU_POST_QUALIFIED + | P_POST_QUALIFIED + | ROOT_POST_QUALIFIED; + + /** + * Default options (M_PARAMETER_TYPES enabled) + */ + public final static int ALL_DEFAULT = M_PARAMETER_TYPES; + + /** + * Default qualify options (All except Root and Package) + */ + public final static int DEFAULT_QUALIFIED = + F_FULLY_QUALIFIED | M_FULLY_QUALIFIED | I_FULLY_QUALIFIED | T_FULLY_QUALIFIED | D_QUALIFIED | CF_QUALIFIED | CU_QUALIFIED; + + /** + * Default post qualify options (All except Root and Package) + */ + public final static int DEFAULT_POST_QUALIFIED = + F_POST_QUALIFIED + | M_POST_QUALIFIED + | I_POST_QUALIFIED + | T_POST_QUALIFIED + | D_POST_QUALIFIED + | CF_POST_QUALIFIED + | CU_POST_QUALIFIED; + + public final static String CONCAT_STRING = PHPUIMessages.getString("JavaElementLabels.concat_string"); // " - "; //$NON-NLS-1$ + public final static String COMMA_STRING = PHPUIMessages.getString("JavaElementLabels.comma_string"); // ", "; //$NON-NLS-1$ + public final static String DECL_STRING = PHPUIMessages.getString("JavaElementLabels.declseparator_string"); // " "; // use for return type //$NON-NLS-1$ + + /* + * Package name compression + */ + private static String fgPkgNamePattern = ""; //$NON-NLS-1$ + private static String fgPkgNamePrefix; + private static String fgPkgNamePostfix; + private static int fgPkgNameChars; + private static int fgPkgNameLength = -1; + + private JavaElementLabels() { + } + + private static boolean getFlag(int flags, int flag) { + return (flags & flag) != 0; + } + + public static String getTextLabel(Object obj, int flags) { + if (obj instanceof IJavaElement) { + return getElementLabel((IJavaElement) obj, flags); + } else if (obj instanceof IAdaptable) { + IWorkbenchAdapter wbadapter = (IWorkbenchAdapter) ((IAdaptable) obj).getAdapter(IWorkbenchAdapter.class); + if (wbadapter != null) { + return wbadapter.getLabel(obj); + } + } + return ""; //$NON-NLS-1$ + } + + /** + * Returns the label for a Java element. Flags as defined above. + */ + public static String getElementLabel(IJavaElement element, int flags) { + StringBuffer buf = new StringBuffer(60); + getElementLabel(element, flags, buf); + return buf.toString(); + } + + /** + * Returns the label for a Java element. Flags as defined above. + */ + public static void getElementLabel(IJavaElement element, int flags, StringBuffer buf) { + int type = element.getElementType(); + IPackageFragmentRoot root = null; + + if (type != IJavaElement.JAVA_MODEL && type != IJavaElement.JAVA_PROJECT && type != IJavaElement.PACKAGE_FRAGMENT_ROOT) + root = JavaModelUtil.getPackageFragmentRoot(element); + if (root != null && getFlag(flags, PREPEND_ROOT_PATH)) { + getPackageFragmentRootLabel(root, ROOT_QUALIFIED, buf); + buf.append(CONCAT_STRING); + } + + switch (type) { + case IJavaElement.METHOD : + getMethodLabel((IMethod) element, flags, buf); + break; + case IJavaElement.FIELD : + getFieldLabel((IField) element, flags, buf); + break; + // case IJavaElement.INITIALIZER: + // getInitializerLabel((IInitializer) element, flags, buf); + // break; + case IJavaElement.TYPE : + getTypeLabel((IType) element, flags, buf); + break; + // case IJavaElement.CLASS_FILE: + // getClassFileLabel((IClassFile) element, flags, buf); + // break; + case IJavaElement.COMPILATION_UNIT : + getCompilationUnitLabel((ICompilationUnit) element, flags, buf); + break; + case IJavaElement.PACKAGE_FRAGMENT : + getPackageFragmentLabel((IPackageFragment) element, flags, buf); + break; + case IJavaElement.PACKAGE_FRAGMENT_ROOT : + getPackageFragmentRootLabel((IPackageFragmentRoot) element, flags, buf); + break; + case IJavaElement.IMPORT_CONTAINER : + case IJavaElement.IMPORT_DECLARATION : + case IJavaElement.PACKAGE_DECLARATION : + getDeclararionLabel(element, flags, buf); + break; + case IJavaElement.JAVA_PROJECT : + case IJavaElement.JAVA_MODEL : + buf.append(element.getElementName()); + break; + default : + buf.append(element.getElementName()); + } + + if (root != null && getFlag(flags, APPEND_ROOT_PATH)) { + buf.append(CONCAT_STRING); + getPackageFragmentRootLabel(root, ROOT_QUALIFIED, buf); + } + } + + /** + * Appends the label for a method to a StringBuffer. Considers the M_* flags. + */ + public static void getMethodLabel(IMethod method, int flags, StringBuffer buf) { + try { + // return type + if (getFlag(flags, M_PRE_RETURNTYPE) && method.exists() && !method.isConstructor()) { + buf.append(Signature.getSimpleName(Signature.toString(method.getReturnType()))); + buf.append(' '); + } + + // qualification + if (getFlag(flags, M_FULLY_QUALIFIED)) { + getTypeLabel(method.getDeclaringType(), T_FULLY_QUALIFIED | (flags & P_COMPRESSED), buf); + buf.append('.'); + } + + buf.append(method.getElementName()); + + // parameters + if (getFlag(flags, M_PARAMETER_TYPES | M_PARAMETER_NAMES)) { + buf.append('('); + + String[] types = getFlag(flags, M_PARAMETER_TYPES) ? method.getParameterTypes() : null; + String[] names = (getFlag(flags, M_PARAMETER_NAMES) && method.exists()) ? method.getParameterNames() : null; + int nParams = types != null ? types.length : names.length; + + for (int i = 0; i < nParams; i++) { + if (i > 0) { + buf.append(COMMA_STRING); //$NON-NLS-1$ + } + if (types != null) { + buf.append(Signature.getSimpleName(Signature.toString(types[i]))); + } + if (names != null) { + if (types != null) { + buf.append(' '); + } + buf.append(names[i]); + } + } + buf.append(')'); + } + + if (getFlag(flags, M_EXCEPTIONS) && method.exists()) { + String[] types = method.getExceptionTypes(); + if (types.length > 0) { + buf.append(" throws "); //$NON-NLS-1$ + for (int i = 0; i < types.length; i++) { + if (i > 0) { + buf.append(COMMA_STRING); + } + buf.append(Signature.getSimpleName(Signature.toString(types[i]))); + } + } + } + + if (getFlag(flags, M_APP_RETURNTYPE) && method.exists() && !method.isConstructor()) { + buf.append(DECL_STRING); + buf.append(Signature.getSimpleName(Signature.toString(method.getReturnType()))); + } + + // post qualification + if (getFlag(flags, M_POST_QUALIFIED)) { + buf.append(CONCAT_STRING); + getTypeLabel(method.getDeclaringType(), T_FULLY_QUALIFIED | (flags & P_COMPRESSED), buf); + } + + } catch (JavaModelException e) { + PHPeclipsePlugin.log(e); // NotExistsException will not reach this point + } + } + + /** + * Appends the label for a field to a StringBuffer. Considers the F_* flags. + */ + public static void getFieldLabel(IField field, int flags, StringBuffer buf) { + try { + if (getFlag(flags, F_PRE_TYPE_SIGNATURE) && field.exists()) { + buf.append(Signature.toString(field.getTypeSignature())); + buf.append(' '); + } + + // qualification + if (getFlag(flags, F_FULLY_QUALIFIED)) { + getTypeLabel(field.getDeclaringType(), T_FULLY_QUALIFIED | (flags & P_COMPRESSED), buf); + buf.append('.'); + } + buf.append(field.getElementName()); + + if (getFlag(flags, F_APP_TYPE_SIGNATURE) && field.exists()) { + buf.append(DECL_STRING); + buf.append(Signature.toString(field.getTypeSignature())); + } + + // post qualification + if (getFlag(flags, F_POST_QUALIFIED)) { + buf.append(CONCAT_STRING); + getTypeLabel(field.getDeclaringType(), T_FULLY_QUALIFIED | (flags & P_COMPRESSED), buf); + } + + } catch (JavaModelException e) { + PHPeclipsePlugin.log(e); // NotExistsException will not reach this point + } + } + + /** + * Appends the label for a initializer to a StringBuffer. Considers the I_* flags. + */ + // public static void getInitializerLabel(IInitializer initializer, int flags, StringBuffer buf) { + // // qualification + // if (getFlag(flags, I_FULLY_QUALIFIED)) { + // getTypeLabel(initializer.getDeclaringType(), T_FULLY_QUALIFIED | (flags & P_COMPRESSED), buf); + // buf.append('.'); + // } + // buf.append(JavaUIMessages.getString("JavaElementLabels.initializer")); //$NON-NLS-1$ + // + // // post qualification + // if (getFlag(flags, I_POST_QUALIFIED)) { + // buf.append(CONCAT_STRING); + // getTypeLabel(initializer.getDeclaringType(), T_FULLY_QUALIFIED | (flags & P_COMPRESSED), buf); + // } + // } + + /** + * Appends the label for a type to a StringBuffer. Considers the T_* flags. + */ + public static void getTypeLabel(IType type, int flags, StringBuffer buf) { + if (getFlag(flags, T_FULLY_QUALIFIED)) { + if (type != null) { // jsurfer INSERT + IPackageFragment pack = type.getPackageFragment(); + if (!pack.isDefaultPackage()) { + getPackageFragmentLabel(pack, (flags & P_COMPRESSED), buf); + buf.append('.'); + } + buf.append(JavaModelUtil.getTypeQualifiedName(type)); + } // jsurfer INSERT + } else if (getFlag(flags, T_CONTAINER_QUALIFIED)) { + buf.append(JavaModelUtil.getTypeQualifiedName(type)); + } else { + buf.append(type.getElementName()); + } + // post qualification + if (getFlag(flags, T_POST_QUALIFIED)) { + buf.append(CONCAT_STRING); + IType declaringType = type.getDeclaringType(); + if (declaringType != null) { + getTypeLabel(declaringType, T_FULLY_QUALIFIED | (flags & P_COMPRESSED), buf); + } else { + getPackageFragmentLabel(type.getPackageFragment(), (flags & P_COMPRESSED), buf); + } + } + } + + /** + * Appends the label for a declaration to a StringBuffer. Considers the D_* flags. + */ + public static void getDeclararionLabel(IJavaElement declaration, int flags, StringBuffer buf) { + if (getFlag(flags, D_QUALIFIED)) { + IJavaElement openable = (IJavaElement) declaration.getOpenable(); + if (openable != null) { + buf.append(getElementLabel(openable, CF_QUALIFIED | CU_QUALIFIED)); + buf.append('/'); + } + } + if (declaration.getElementType() == IJavaElement.IMPORT_CONTAINER) { + buf.append(PHPUIMessages.getString("JavaElementLabels.import_container")); //$NON-NLS-1$ + } else { + buf.append(declaration.getElementName()); + } + // post qualification + if (getFlag(flags, D_POST_QUALIFIED)) { + IJavaElement openable = (IJavaElement) declaration.getOpenable(); + if (openable != null) { + buf.append(CONCAT_STRING); + buf.append(getElementLabel(openable, CF_QUALIFIED | CU_QUALIFIED)); + } + } + } + + /** + * Appends the label for a class file to a StringBuffer. Considers the CF_* flags. + */ + // public static void getClassFileLabel(IClassFile classFile, int flags, StringBuffer buf) { + // if (getFlag(flags, CF_QUALIFIED)) { + // IPackageFragment pack= (IPackageFragment) classFile.getParent(); + // if (!pack.isDefaultPackage()) { + // buf.append(pack.getElementName()); + // buf.append('.'); + // } + // } + // buf.append(classFile.getElementName()); + // + // if (getFlag(flags, CF_POST_QUALIFIED)) { + // buf.append(CONCAT_STRING); + // getPackageFragmentLabel((IPackageFragment) classFile.getParent(), 0, buf); + // } + // } + + /** + * Appends the label for a compilation unit to a StringBuffer. Considers the CU_* flags. + */ + public static void getCompilationUnitLabel(ICompilationUnit cu, int flags, StringBuffer buf) { + if (getFlag(flags, CU_QUALIFIED)) { + IPackageFragment pack = (IPackageFragment) cu.getParent(); + if (!pack.isDefaultPackage()) { + buf.append(pack.getElementName()); + buf.append('.'); + } + } + buf.append(cu.getElementName()); + + if (getFlag(flags, CU_POST_QUALIFIED)) { + buf.append(CONCAT_STRING); + getPackageFragmentLabel((IPackageFragment) cu.getParent(), 0, buf); + } + } + + /** + * Appends the label for a package fragment to a StringBuffer. Considers the P_* flags. + */ + public static void getPackageFragmentLabel(IPackageFragment pack, int flags, StringBuffer buf) { + if (getFlag(flags, P_QUALIFIED)) { + getPackageFragmentRootLabel((IPackageFragmentRoot) pack.getParent(), ROOT_QUALIFIED, buf); + buf.append('/'); + } + refreshPackageNamePattern(); + if (pack.isDefaultPackage()) { + buf.append(PHPUIMessages.getString("JavaElementLabels.default_package")); //$NON-NLS-1$ + } else if (getFlag(flags, P_COMPRESSED) && fgPkgNameLength >= 0) { + String name = pack.getElementName(); + int start = 0; + int dot = name.indexOf('.', start); + while (dot > 0) { + if (dot - start > fgPkgNameLength - 1) { + buf.append(fgPkgNamePrefix); + if (fgPkgNameChars > 0) + buf.append(name.substring(start, Math.min(start + fgPkgNameChars, dot))); + buf.append(fgPkgNamePostfix); + } else + buf.append(name.substring(start, dot + 1)); + start = dot + 1; + dot = name.indexOf('.', start); + } + buf.append(name.substring(start)); + } else { + buf.append(pack.getElementName()); + } + if (getFlag(flags, P_POST_QUALIFIED)) { + buf.append(CONCAT_STRING); + getPackageFragmentRootLabel((IPackageFragmentRoot) pack.getParent(), ROOT_QUALIFIED, buf); + } + } + + /** + * Appends the label for a package fragment root to a StringBuffer. Considers the ROOT_* flags. + */ + public static void getPackageFragmentRootLabel(IPackageFragmentRoot root, int flags, StringBuffer buf) { + if (root.isArchive()) + getArchiveLabel(root, flags, buf); + else + getFolderLabel(root, flags, buf); + } + + private static void getArchiveLabel(IPackageFragmentRoot root, int flags, StringBuffer buf) { + // Handle variables different + if (getFlag(flags, ROOT_VARIABLE) && getVariableLabel(root, flags, buf)) + return; + boolean external = root.isExternal(); + if (external) + getExternalArchiveLabel(root, flags, buf); + else + getInternalArchiveLabel(root, flags, buf); + } + + private static boolean getVariableLabel(IPackageFragmentRoot root, int flags, StringBuffer buf) { + // try { + // IClasspathEntry rawEntry= root.getRawClasspathEntry(); + // if (rawEntry != null) { + // if (rawEntry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) { + // buf.append(rawEntry.getPath().makeRelative()); + // buf.append(CONCAT_STRING); + // if (root.isExternal()) + // buf.append(root.getPath().toOSString()); + // else + // buf.append(root.getPath().makeRelative().toString()); + // return true; + // } + // } + // } catch (JavaModelException e) { + // PHPeclipsePlugin.log(e); // problems with class path + // } + return false; + } + + private static void getExternalArchiveLabel(IPackageFragmentRoot root, int flags, StringBuffer buf) { + IPath path = root.getPath(); + if (getFlag(flags, REFERENCED_ROOT_POST_QUALIFIED)) { + int segements = path.segmentCount(); + if (segements > 0) { + buf.append(path.segment(segements - 1)); + if (segements > 1 || path.getDevice() != null) { + buf.append(CONCAT_STRING); + buf.append(path.removeLastSegments(1).toOSString()); + } + } else { + buf.append(path.toOSString()); + } + } else { + buf.append(path.toOSString()); + } + } + + private static void getInternalArchiveLabel(IPackageFragmentRoot root, int flags, StringBuffer buf) { + IResource resource = root.getResource(); + boolean rootQualified = getFlag(flags, ROOT_QUALIFIED); + boolean referencedQualified = + getFlag(flags, REFERENCED_ROOT_POST_QUALIFIED) && JavaModelUtil.isReferenced(root) && resource != null; + if (rootQualified) { + buf.append(root.getPath().makeRelative().toString()); + } else { + buf.append(root.getElementName()); + if (referencedQualified) { + buf.append(CONCAT_STRING); + buf.append(resource.getParent().getFullPath().makeRelative().toString()); + } else if (getFlag(flags, ROOT_POST_QUALIFIED)) { + buf.append(CONCAT_STRING); + buf.append(root.getParent().getPath().makeRelative().toString()); + } + } + } + + private static void getFolderLabel(IPackageFragmentRoot root, int flags, StringBuffer buf) { + IResource resource = root.getResource(); + boolean rootQualified = getFlag(flags, ROOT_QUALIFIED); + boolean referencedQualified = + getFlag(flags, REFERENCED_ROOT_POST_QUALIFIED) && JavaModelUtil.isReferenced(root) && resource != null; + if (rootQualified) { + buf.append(root.getPath().makeRelative().toString()); + } else { + if (resource != null) + buf.append(resource.getProjectRelativePath().toString()); + else + buf.append(root.getElementName()); + if (referencedQualified) { + buf.append(CONCAT_STRING); + buf.append(resource.getProject().getName()); + } else if (getFlag(flags, ROOT_POST_QUALIFIED)) { + buf.append(CONCAT_STRING); + buf.append(root.getParent().getElementName()); + } + } + } + + private static void refreshPackageNamePattern() { + String pattern = getPkgNamePatternForPackagesView(); + if (pattern.equals(fgPkgNamePattern)) + return; + else if (pattern.equals("")) { //$NON-NLS-1$ + fgPkgNamePattern = ""; //$NON-NLS-1$ + fgPkgNameLength = -1; + return; + } + fgPkgNamePattern = pattern; + int i = 0; + fgPkgNameChars = 0; + fgPkgNamePrefix = ""; //$NON-NLS-1$ + fgPkgNamePostfix = ""; //$NON-NLS-1$ + while (i < pattern.length()) { + char ch = pattern.charAt(i); + if (Character.isDigit(ch)) { + fgPkgNameChars = ch - 48; + if (i > 0) + fgPkgNamePrefix = pattern.substring(0, i); + if (i >= 0) + fgPkgNamePostfix = pattern.substring(i + 1); + fgPkgNameLength = fgPkgNamePrefix.length() + fgPkgNameChars + fgPkgNamePostfix.length(); + return; + } + i++; + } + fgPkgNamePrefix = pattern; + fgPkgNameLength = pattern.length(); + } + + private static String getPkgNamePatternForPackagesView() { + IPreferenceStore store = PreferenceConstants.getPreferenceStore(); + if (!store.getBoolean(PreferenceConstants.APPEARANCE_COMPRESS_PACKAGE_NAMES)) + return ""; //$NON-NLS-1$ + return store.getString(PreferenceConstants.APPEARANCE_PKG_NAME_PATTERN_FOR_PKG_VIEW); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaUILabelProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaUILabelProvider.java new file mode 100644 index 0000000..eac133f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaUILabelProvider.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.viewsupport; + +import java.util.ArrayList; + +import org.eclipse.core.resources.IStorage; + +import org.eclipse.swt.graphics.Image; + +import org.eclipse.jface.viewers.ILabelDecorator; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.LabelProvider; + +public class JavaUILabelProvider extends LabelProvider { + + protected JavaElementImageProvider fImageLabelProvider; + protected StorageLabelProvider fStorageLabelProvider; + + protected ArrayList fLabelDecorators; + + private int fImageFlags; + private int fTextFlags; + + /** + * Creates a new label provider with default flags. + */ + public JavaUILabelProvider() { + this(JavaElementLabels.M_PARAMETER_TYPES, JavaElementImageProvider.OVERLAY_ICONS); + } + + /** + * @param textFlags Flags defined in JavaElementLabels. + * @param imageFlags Flags defined in JavaElementImageProvider. + */ + public JavaUILabelProvider(int textFlags, int imageFlags) { + fImageLabelProvider= new JavaElementImageProvider(); + fLabelDecorators= null; + + fStorageLabelProvider= new StorageLabelProvider(); + fImageFlags= imageFlags; + fTextFlags= textFlags; + } + + /** + * Adds a decorator to the label provider + */ + public void addLabelDecorator(ILabelDecorator decorator) { + if (fLabelDecorators == null) { + fLabelDecorators= new ArrayList(2); + } + fLabelDecorators.add(decorator); + } + + /** + * Sets the textFlags. + * @param textFlags The textFlags to set + */ + public final void setTextFlags(int textFlags) { + fTextFlags= textFlags; + } + + /** + * Sets the imageFlags + * @param imageFlags The imageFlags to set + */ + public final void setImageFlags(int imageFlags) { + fImageFlags= imageFlags; + } + + /** + * Gets the image flags. + * Can be overwriten by super classes. + * @return Returns a int + */ + public final int getImageFlags() { + return fImageFlags; + } + + /** + * Gets the text flags. + * @return Returns a int + */ + public final int getTextFlags() { + return fTextFlags; + } + + /** + * Evaluates the image flags for a element. + * Can be overwriten by super classes. + * @return Returns a int + */ + protected int evaluateImageFlags(Object element) { + return getImageFlags(); + } + + /** + * Evaluates the text flags for a element. Can be overwriten by super classes. + * @return Returns a int + */ + protected int evaluateTextFlags(Object element) { + return getTextFlags(); + } + + + /* (non-Javadoc) + * @see ILabelProvider#getImage + */ + public Image getImage(Object element) { + Image result= fImageLabelProvider.getImageLabel(element, evaluateImageFlags(element)); + if (result == null && (element instanceof IStorage)) { + result= fStorageLabelProvider.getImage(element); + } + if (fLabelDecorators != null && result != null) { + for (int i= 0; i < fLabelDecorators.size(); i++) { + ILabelDecorator decorator= (ILabelDecorator) fLabelDecorators.get(i); + result= decorator.decorateImage(result, element); + } + } + return result; + } + + /* (non-Javadoc) + * @see ILabelProvider#getText + */ + public String getText(Object element) { + String result= JavaElementLabels.getTextLabel(element, evaluateTextFlags(element)); + if (result.length() == 0 && (element instanceof IStorage)) { + result= fStorageLabelProvider.getText(element); + } + if (fLabelDecorators != null && result.length() > 0) { + for (int i= 0; i < fLabelDecorators.size(); i++) { + ILabelDecorator decorator= (ILabelDecorator) fLabelDecorators.get(i); + result= decorator.decorateText(result, element); + } + } + return result; + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#dispose + */ + public void dispose() { + if (fLabelDecorators != null) { + for (int i= 0; i < fLabelDecorators.size(); i++) { + ILabelDecorator decorator= (ILabelDecorator) fLabelDecorators.get(i); + decorator.dispose(); + } + fLabelDecorators= null; + } + fStorageLabelProvider.dispose(); + fImageLabelProvider.dispose(); + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#addListener(ILabelProviderListener) + */ + public void addListener(ILabelProviderListener listener) { + if (fLabelDecorators != null) { + for (int i= 0; i < fLabelDecorators.size(); i++) { + ILabelDecorator decorator= (ILabelDecorator) fLabelDecorators.get(i); + decorator.addListener(listener); + } + } + super.addListener(listener); + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#isLabelProperty(Object, String) + */ + public boolean isLabelProperty(Object element, String property) { + return true; + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#removeListener(ILabelProviderListener) + */ + public void removeListener(ILabelProviderListener listener) { + if (fLabelDecorators != null) { + for (int i= 0; i < fLabelDecorators.size(); i++) { + ILabelDecorator decorator= (ILabelDecorator) fLabelDecorators.get(i); + decorator.removeListener(listener); + } + } + super.removeListener(listener); + } + + public static ILabelDecorator[] getDecorators(boolean errortick, ILabelDecorator extra) { + if (errortick) { + if (extra == null) { + return new ILabelDecorator[] {}; + } else { + return new ILabelDecorator[] { extra }; + } + } + if (extra != null) { + return new ILabelDecorator[] { extra }; + } + return null; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/MemberFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/MemberFilter.java new file mode 100644 index 0000000..8e8bad2 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/MemberFilter.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.viewsupport; + +import net.sourceforge.phpdt.core.Flags; +import net.sourceforge.phpdt.core.IField; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IMember; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; + +/** + * Filter for the methods viewer. + * Changing a filter property does not trigger a refiltering of the viewer + */ +public class MemberFilter extends ViewerFilter { + + public static final int FILTER_NONPUBLIC= 1; + public static final int FILTER_STATIC= 2; + public static final int FILTER_FIELDS= 4; + + private int fFilterProperties; + + /** + * Modifies filter and add a property to filter for + */ + public final void addFilter(int filter) { + fFilterProperties |= filter; + } + /** + * Modifies filter and remove a property to filter for + */ + public final void removeFilter(int filter) { + fFilterProperties &= (-1 ^ filter); + } + /** + * Tests if a property is filtered + */ + public final boolean hasFilter(int filter) { + return (fFilterProperties & filter) != 0; + } + + /* + * @see ViewerFilter@isFilterProperty + */ + public boolean isFilterProperty(Object element, Object property) { + return false; + } + /* + * @see ViewerFilter@select + */ + public boolean select(Viewer viewer, Object parentElement, Object element) { + try { + if (hasFilter(FILTER_FIELDS) && element instanceof IField) { + return false; + } + if (element instanceof IMember) { + IMember member= (IMember)element; + if (member.getElementName().startsWith("<")) { // filter out //$NON-NLS-1$ + return false; + } + int flags= member.getFlags(); + if (hasFilter(FILTER_STATIC) && (Flags.isStatic(flags) || isFieldInInterface(member)) && member.getElementType() != IJavaElement.TYPE) { + return false; + } + if (hasFilter(FILTER_NONPUBLIC) && !Flags.isPublic(flags) && !isMemberInInterface(member) && !isTopLevelType(member)) { + return false; + } + } + } catch (JavaModelException e) { + // ignore + } + return true; + } + + private boolean isMemberInInterface(IMember member) throws JavaModelException { + IType parent= member.getDeclaringType(); + return parent != null && parent.isInterface(); + } + + private boolean isFieldInInterface(IMember member) throws JavaModelException { + return (member.getElementType() == IJavaElement.FIELD) && member.getDeclaringType().isInterface(); + } + + private boolean isTopLevelType(IMember member) throws JavaModelException { + IType parent= member.getDeclaringType(); + return parent == null; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/MemberFilterAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/MemberFilterAction.java new file mode 100644 index 0000000..30080af --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/MemberFilterAction.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.viewsupport; + +import net.sourceforge.phpdt.ui.actions.MemberFilterActionGroup; + +import org.eclipse.jface.action.Action; +import org.eclipse.ui.help.WorkbenchHelp; + +/** + * Action used to enable / disable method filter properties + */ +public class MemberFilterAction extends Action { + + private int fFilterProperty; + private MemberFilterActionGroup fFilterActionGroup; + + public MemberFilterAction(MemberFilterActionGroup actionGroup, String title, int property, String contextHelpId, boolean initValue) { + super(title); + fFilterActionGroup= actionGroup; + fFilterProperty= property; + + WorkbenchHelp.setHelp(this, contextHelpId); + + setChecked(initValue); + } + + /** + * Returns this action's filter property. + */ + public int getFilterProperty() { + return fFilterProperty; + } + + /* + * @see Action#actionPerformed + */ + public void run() { + fFilterActionGroup.setMemberFilter(fFilterProperty, isChecked()); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/ProblemMarkerManager.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/ProblemMarkerManager.java new file mode 100644 index 0000000..3be74d5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/ProblemMarkerManager.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.viewsupport; + + +import java.util.HashSet; + +import net.sourceforge.phpdt.internal.ui.util.SWTUtil; +//import net.sourceforge.phpeclipse.PHPCore; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.phpeditor.CompilationUnitAnnotationModelEvent; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.text.source.AnnotationModelEvent; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IAnnotationModelListener; +import org.eclipse.jface.text.source.IAnnotationModelListenerExtension; +import org.eclipse.jface.util.ListenerList; +import org.eclipse.swt.widgets.Display; + + + +/** + * Listens to resource deltas and filters for marker changes of type IMarker.PROBLEM + * Viewers showing error ticks should register as listener to + * this type. + */ +public class ProblemMarkerManager implements IResourceChangeListener, IAnnotationModelListener , IAnnotationModelListenerExtension { + + /** + * Visitors used to look if the element change delta containes a marker change. + */ + private static class ProjectErrorVisitor implements IResourceDeltaVisitor { + + private HashSet fChangedElements; + + public ProjectErrorVisitor(HashSet changedElements) { + fChangedElements= changedElements; + } + + public boolean visit(IResourceDelta delta) throws CoreException { + IResource res= delta.getResource(); + if (res instanceof IProject && delta.getKind() == IResourceDelta.CHANGED) { + try { + IProject project= (IProject) res; + if (!project.isAccessible() || !project.hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) { + // only track open Java projects + return false; + } + } catch (CoreException e) { + PHPeclipsePlugin.log(e); + return false; + } + } + checkInvalidate(delta, res); + return true; + } + + private void checkInvalidate(IResourceDelta delta, IResource resource) { + int kind= delta.getKind(); + if (kind == IResourceDelta.REMOVED || kind == IResourceDelta.ADDED || (kind == IResourceDelta.CHANGED && isErrorDelta(delta))) { + // invalidate the resource and all parents + while (resource.getType() != IResource.ROOT && fChangedElements.add(resource)) { + resource= resource.getParent(); + } + } + } + + private boolean isErrorDelta(IResourceDelta delta) { + if ((delta.getFlags() & IResourceDelta.MARKERS) != 0) { + IMarkerDelta[] markerDeltas= delta.getMarkerDeltas(); + for (int i= 0; i < markerDeltas.length; i++) { + if (markerDeltas[i].isSubtypeOf(IMarker.PROBLEM)) { + int kind= markerDeltas[i].getKind(); + if (kind == IResourceDelta.ADDED || kind == IResourceDelta.REMOVED) + return true; + int severity= markerDeltas[i].getAttribute(IMarker.SEVERITY, -1); + int newSeverity= markerDeltas[i].getMarker().getAttribute(IMarker.SEVERITY, -1); + if (newSeverity != severity) + return true; + } + } + } + return false; + } + } + + private ListenerList fListeners; + + + public ProblemMarkerManager() { + fListeners= new ListenerList(10); + } + + /* + * @see IResourceChangeListener#resourceChanged + */ + public void resourceChanged(IResourceChangeEvent event) { + HashSet changedElements= new HashSet(); + + try { + IResourceDelta delta= event.getDelta(); + if (delta != null) + delta.accept(new ProjectErrorVisitor(changedElements)); + } catch (CoreException e) { + PHPeclipsePlugin.log(e.getStatus()); + } + + if (!changedElements.isEmpty()) { + IResource[] changes= (IResource[]) changedElements.toArray(new IResource[changedElements.size()]); + fireChanges(changes, true); + } + } + + /* (non-Javadoc) + * @see IAnnotationModelListener#modelChanged(IAnnotationModel) + */ + public void modelChanged(IAnnotationModel model) { + // no action + } + + /* (non-Javadoc) + * @see IAnnotationModelListenerExtension#modelChanged(AnnotationModelEvent) + */ + public void modelChanged(AnnotationModelEvent event) { + if (event instanceof CompilationUnitAnnotationModelEvent) { + CompilationUnitAnnotationModelEvent cuEvent= (CompilationUnitAnnotationModelEvent) event; + if (cuEvent.includesMarkerAnnotationChanges()) { + IResource[] changes= new IResource[] { cuEvent.getUnderlyingResource() }; + fireChanges(changes, false); + } + } + } + + + /** + * Adds a listener for problem marker changes. + */ + public void addListener(IProblemChangedListener listener) { + if (fListeners.isEmpty()) { + PHPeclipsePlugin.getWorkspace().addResourceChangeListener(this); + PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider().addGlobalAnnotationModelListener(this); + } + fListeners.add(listener); + } + + /** + * Removes a IProblemChangedListener. + */ + public void removeListener(IProblemChangedListener listener) { + fListeners.remove(listener); + if (fListeners.isEmpty()) { + PHPeclipsePlugin.getWorkspace().removeResourceChangeListener(this); + PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider().removeGlobalAnnotationModelListener(this); + } + } + + private void fireChanges(final IResource[] changes, final boolean isMarkerChange) { + Display display= SWTUtil.getStandardDisplay(); + if (display != null && !display.isDisposed()) { + display.asyncExec(new Runnable() { + public void run() { + Object[] listeners= fListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) { + IProblemChangedListener curr= (IProblemChangedListener) listeners[i]; + curr.problemsChanged(changes, isMarkerChange); + } + } + }); + } + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/StatusBarUpdater.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/StatusBarUpdater.java new file mode 100644 index 0000000..ec9f214 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/StatusBarUpdater.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.viewsupport; + + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.internal.ui.PHPUIMessages; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; + +/** + * Add the StatusBarUpdater to your ViewPart to have the statusbar + * describing the selected elements. + */ +public class StatusBarUpdater implements ISelectionChangedListener { + + private final int LABEL_FLAGS= JavaElementLabels.DEFAULT_QUALIFIED | JavaElementLabels.ROOT_POST_QUALIFIED | JavaElementLabels.APPEND_ROOT_PATH | + JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_APP_RETURNTYPE | JavaElementLabels.M_EXCEPTIONS | + JavaElementLabels.F_APP_TYPE_SIGNATURE; + + private IStatusLineManager fStatusLineManager; + + public StatusBarUpdater(IStatusLineManager statusLineManager) { + fStatusLineManager= statusLineManager; + } + + /* + * @see ISelectionChangedListener#selectionChanged + */ + public void selectionChanged(SelectionChangedEvent event) { + String statusBarMessage= formatMessage(event.getSelection()); + fStatusLineManager.setMessage(statusBarMessage); + } + + + protected String formatMessage(ISelection sel) { + if (sel instanceof IStructuredSelection && !sel.isEmpty()) { + IStructuredSelection selection= (IStructuredSelection) sel; + + int nElements= selection.size(); + if (nElements > 1) { + return PHPUIMessages.getFormattedString("StatusBarUpdater.num_elements_selected", String.valueOf(nElements)); //$NON-NLS-1$ + } else { + Object elem= selection.getFirstElement(); + if (elem instanceof IJavaElement) { + return formatJavaElementMessage((IJavaElement) elem); + } else if (elem instanceof IResource) { + return formatResourceMessage((IResource) elem); + } + } + } + return ""; //$NON-NLS-1$ + } + + private String formatJavaElementMessage(IJavaElement element) { + return JavaElementLabels.getElementLabel(element, LABEL_FLAGS); + } + + private String formatResourceMessage(IResource element) { + IContainer parent= element.getParent(); + if (parent != null && parent.getType() != IResource.ROOT) + return element.getName() + JavaElementLabels.CONCAT_STRING + parent.getFullPath().makeRelative().toString(); + else + return element.getName(); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/StorageLabelProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/StorageLabelProvider.java new file mode 100644 index 0000000..7ba4287 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/StorageLabelProvider.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.viewsupport; + + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.runtime.IPath; + +import org.eclipse.swt.graphics.Image; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.LabelProvider; + +import org.eclipse.ui.IEditorRegistry; +import org.eclipse.ui.IFileEditorMapping; +import org.eclipse.ui.PlatformUI; + +/** + * Standard label provider for IStorage objects. + * Use this class when you want to present IStorage objects in a viewer. + */ +public class StorageLabelProvider extends LabelProvider { + + private IEditorRegistry fEditorRegistry= PlatformUI.getWorkbench().getEditorRegistry(); + private Map fJarImageMap= new HashMap(10); + private Image fDefaultImage; + + /* (non-Javadoc) + * @see ILabelProvider#getImage + */ + public Image getImage(Object element) { + if (element instanceof IStorage) + return getImageForJarEntry((IStorage)element); + + return super.getImage(element); + } + + /* (non-Javadoc) + * @see ILabelProvider#getText + */ + public String getText(Object element) { + if (element instanceof IStorage) + return ((IStorage)element).getName(); + + return super.getText(element); + } + + /* (non-Javadoc) + * + * @see IBaseLabelProvider#dispose + */ + public void dispose() { + if (fJarImageMap != null) { + Iterator each= fJarImageMap.values().iterator(); + while (each.hasNext()) { + Image image= (Image)each.next(); + image.dispose(); + } + fJarImageMap= null; + } + if (fDefaultImage != null) + fDefaultImage.dispose(); + fDefaultImage= null; + } + + /* + * Gets and caches an image for a JarEntryFile. + * The image for a JarEntryFile is retrieved from the EditorRegistry. + */ + private Image getImageForJarEntry(IStorage element) { + if (fJarImageMap == null) + return getDefaultImage(); + + if (element == null || element.getName() == null) + return getDefaultImage(); + + // Try to find icon for full name + String name= element.getName(); + Image image= (Image)fJarImageMap.get(name); + if (image != null) + return image; + IFileEditorMapping[] mappings= fEditorRegistry.getFileEditorMappings(); + int i= 0; + while (i < mappings.length) { + if (mappings[i].getLabel().equals(name)) + break; + i++; + } + String key= name; + if (i == mappings.length) { + // Try to find icon for extension + IPath path= element.getFullPath(); + if (path == null) + return getDefaultImage(); + key= path.getFileExtension(); + if (key == null) + return getDefaultImage(); + image= (Image)fJarImageMap.get(key); + if (image != null) + return image; + } + + // Get the image from the editor registry + ImageDescriptor desc= fEditorRegistry.getImageDescriptor(name); + image= desc.createImage(); + + fJarImageMap.put(key, image); + + return image; + } + + private Image getDefaultImage() { + if (fDefaultImage == null) + fDefaultImage= fEditorRegistry.getImageDescriptor((String)null).createImage(); + return fDefaultImage; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/IWorkingCopyManager.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/IWorkingCopyManager.java new file mode 100644 index 0000000..bab2691 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/IWorkingCopyManager.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.ui; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.ui.IEditorInput; + +import net.sourceforge.phpdt.core.ICompilationUnit; + +/** + * Interface for accessing working copies of ICompilationUnit + * objects. The original compilation unit is only given indirectly by means + * of an IEditorInput. The life cycle is as follows: + *
          + *
        • connect creates and remembers a working copy of the + * compilation unit which is encoded in the given editor input
        • + *
        • getWorkingCopy returns the working copy remembered on + * connect
        • + *
        • disconnect destroys the working copy remembered on + * connect
        • + *
        + *

        + * This interface is not intended to be implemented by clients. + *

        + * + * @see JavaUI#getWorkingCopyManager + */ +public interface IWorkingCopyManager { + + /** + * Connects the given editor input to this manager. After calling + * this method, a working copy will be available for the compilation unit encoded + * in the given editor input (does nothing if there is no encoded compilation unit). + * + * @param input the editor input + * @exception CoreException if the working copy cannot be created for the + * compilation unit + */ + void connect(IEditorInput input) throws CoreException; + + /** + * Disconnects the given editor input from this manager. After calling + * this method, a working copy for the compilation unit encoded + * in the given editor input will no longer be available. Does nothing if there + * is no encoded compilation unit, or if there is no remembered working copy for + * the compilation unit. + * + * @param input the editor input + */ + void disconnect(IEditorInput input); + + /** + * Returns the working copy remembered for the compilation unit encoded in the + * given editor input. + * + * @param input the editor input + * @return the working copy of the compilation unit, or null if the + * input does not encode an editor input, or if there is no remembered working + * copy for this compilation unit + */ + ICompilationUnit getWorkingCopy(IEditorInput input); + + /** + * Shuts down this working copy manager. All working copies still remembered + * by this manager are destroyed. + */ + void shutdown(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/IWorkingCopyManagerExtension.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/IWorkingCopyManagerExtension.java new file mode 100644 index 0000000..541f630 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/IWorkingCopyManagerExtension.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package net.sourceforge.phpdt.ui; + +import org.eclipse.ui.IEditorInput; + +import net.sourceforge.phpdt.core.ICompilationUnit; + +/** + * Extension interface for IWorkingCopyManager. + * @since 2.1 + */ +public interface IWorkingCopyManagerExtension { + + /** + * Sets the given working copy for the given editor input. If the given editor input + * is not connected to this working copy manager, this call has no effect.

        + * This working copy manager does not assume the ownership of this working copy, i.e., + * the given working copy is not automatically be freed when this manager is shut down. + * + * @param input the editor input + * @param workingCopy the working copy + */ + void setWorkingCopy(IEditorInput input, ICompilationUnit workingCopy); + + /** + * Removes the working copy set for the given editor input. If there is no + * working copy set for this input or this input is not connected to this + * working copy manager, this call has no effect. + * + * @param input the editor input + */ + void removeWorkingCopy(IEditorInput input); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/IWorkingCopyProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/IWorkingCopyProvider.java new file mode 100644 index 0000000..7d588ff --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/IWorkingCopyProvider.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.ui; + +/** + * Interface used for Java element content providers to indicate that + * the content provider can return working copy elements for members + * below compilation units. + * + *

        + * This interface is not intended to be implemented by clients. + *

        + * + * @see org.eclipse.jdt.ui.StandardJavaElementContentProvider + * @see org.eclipse.jdt.core.IWorkingCopy + * + * @since 2.0 + */ +public interface IWorkingCopyProvider { + + /** + * Returns true if the content provider returns working + * copy elements; otherwise false is returned. + * + * @return whether working copy elements are provided. + */ + public boolean providesWorkingCopies(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/JavaElementImageDescriptor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/JavaElementImageDescriptor.java new file mode 100644 index 0000000..4cf8183 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/JavaElementImageDescriptor.java @@ -0,0 +1,237 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.ui; + + +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Point; + +import org.eclipse.jface.resource.CompositeImageDescriptor; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.util.Assert; + +import net.sourceforge.phpdt.internal.ui.PHPUiImages; + +/** + * A JavaImageDescriptor consists of a base image and several adornments. The adornments + * are computed according to the flags either passed during creation or set via the method + * setAdornments. + * + *

        + * This class may be instantiated; it is not intended to be subclassed. + *

        + * + * @since 2.0 + */ +public class JavaElementImageDescriptor extends CompositeImageDescriptor { + + /** Flag to render the abstract adornment */ + public final static int ABSTRACT= 0x001; + + /** Flag to render the final adornment */ + public final static int FINAL= 0x002; + + /** Flag to render the synchronized adornment */ + public final static int SYNCHRONIZED= 0x004; + + /** Flag to render the static adornment */ + public final static int STATIC= 0x008; + + /** Flag to render the runnable adornment */ + public final static int RUNNABLE= 0x010; + + /** Flag to render the waring adornment */ + public final static int WARNING= 0x020; + + /** Flag to render the error adornment */ + public final static int ERROR= 0x040; + + /** Flag to render the 'override' adornment */ + public final static int OVERRIDES= 0x080; + + /** Flag to render the 'implements' adornment */ + public final static int IMPLEMENTS= 0x100; + + /** Flag to render the 'constructor' adornment */ + public final static int CONSTRUCTOR= 0x200; + + private ImageDescriptor fBaseImage; + private int fFlags; + private Point fSize; + + /** + * Creates a new JavaElementImageDescriptor. + * + * @param baseImage an image descriptor used as the base image + * @param flags flags indicating which adornments are to be rendered. See setAdornments + * for valid values. + * @param size the size of the resulting image + * @see #setAdornments(int) + */ + public JavaElementImageDescriptor(ImageDescriptor baseImage, int flags, Point size) { + fBaseImage= baseImage; + Assert.isNotNull(fBaseImage); + fFlags= flags; + Assert.isTrue(fFlags >= 0); + fSize= size; + Assert.isNotNull(fSize); + } + + /** + * Sets the descriptors adornments. Valid values are: ABSTRACT, FINAL, + * SYNCHRONIZED, STATIC, RUNNABLE, WARNING, + * ERROR, OVERRIDDES, IMPLEMENTS, CONSTRUCTOR, + * or any combination of those. + * + * @param adornments the image descritpors adornments + */ + public void setAdornments(int adornments) { + Assert.isTrue(adornments >= 0); + fFlags= adornments; + } + + /** + * Returns the current adornments. + * + * @return the current adornments + */ + public int getAdronments() { + return fFlags; + } + + /** + * Sets the size of the image created by calling createImage(). + * + * @param size the size of the image returned from calling createImage() + * @see ImageDescriptor#createImage() + */ + public void setImageSize(Point size) { + Assert.isNotNull(size); + Assert.isTrue(size.x >= 0 && size.y >= 0); + fSize= size; + } + + /** + * Returns the size of the image created by calling createImage(). + * + * @return the size of the image created by calling createImage() + * @see ImageDescriptor#createImage() + */ + public Point getImageSize() { + return new Point(fSize.x, fSize.y); + } + + /* (non-Javadoc) + * Method declared in CompositeImageDescriptor + */ + protected Point getSize() { + return fSize; + } + + /* (non-Javadoc) + * Method declared on Object. + */ + public boolean equals(Object object) { + if (object == null || !JavaElementImageDescriptor.class.equals(object.getClass())) + return false; + + JavaElementImageDescriptor other= (JavaElementImageDescriptor)object; + return (fBaseImage.equals(other.fBaseImage) && fFlags == other.fFlags && fSize.equals(other.fSize)); + } + + /* (non-Javadoc) + * Method declared on Object. + */ + public int hashCode() { + return fBaseImage.hashCode() | fFlags | fSize.hashCode(); + } + + /* (non-Javadoc) + * Method declared in CompositeImageDescriptor + */ + protected void drawCompositeImage(int width, int height) { + ImageData bg; + if ((bg= fBaseImage.getImageData()) == null) + bg= DEFAULT_IMAGE_DATA; + + drawImage(bg, 0, 0); + drawTopRight(); + drawBottomRight(); + drawBottomLeft(); + } + + private void drawTopRight() { + int x= getSize().x; + ImageData data= null; + if ((fFlags & ABSTRACT) != 0) { + data= PHPUiImages.DESC_OVR_ABSTRACT.getImageData(); + x-= data.width; + drawImage(data, x, 0); + } + if ((fFlags & CONSTRUCTOR) != 0) { + data= PHPUiImages.DESC_OVR_CONSTRUCTOR.getImageData(); + x-= data.width; + drawImage(data, x, 0); + } + if ((fFlags & FINAL) != 0) { + data= PHPUiImages.DESC_OVR_FINAL.getImageData(); + x-= data.width; + drawImage(data, x, 0); + } + if ((fFlags & STATIC) != 0) { + data= PHPUiImages.DESC_OVR_STATIC.getImageData(); + x-= data.width; + drawImage(data, x, 0); + } + } + + private void drawBottomRight() { + Point size= getSize(); + int x= size.x; + ImageData data= null; + if ((fFlags & OVERRIDES) != 0) { + data= PHPUiImages.DESC_OVR_OVERRIDES.getImageData(); + x-= data.width; + drawImage(data, x, size.y - data.height); + } + if ((fFlags & IMPLEMENTS) != 0) { + data= PHPUiImages.DESC_OVR_IMPLEMENTS.getImageData(); + x-= data.width; + drawImage(data, x, size.y - data.height); + } + if ((fFlags & SYNCHRONIZED) != 0) { + data= PHPUiImages.DESC_OVR_SYNCH.getImageData(); + x-= data.width; + drawImage(data, x, size.y - data.height); + } + if ((fFlags & RUNNABLE) != 0) { + data= PHPUiImages.DESC_OVR_RUN.getImageData(); + x-= data.width; + drawImage(data, x, size.y - data.height); + } + } + + private void drawBottomLeft() { + Point size= getSize(); + int x= 0; + ImageData data= null; + if ((fFlags & ERROR) != 0) { + data= PHPUiImages.DESC_OVR_ERROR.getImageData(); + drawImage(data, x, size.y - data.height); + x+= data.width; + } + if ((fFlags & WARNING) != 0) { + data= PHPUiImages.DESC_OVR_WARNING.getImageData(); + drawImage(data, x, size.y - data.height); + x+= data.width; + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/JavaElementLabelProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/JavaElementLabelProvider.java new file mode 100644 index 0000000..4067228 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/JavaElementLabelProvider.java @@ -0,0 +1,268 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.ui; + +import net.sourceforge.phpdt.internal.ui.viewsupport.JavaElementImageProvider; +import net.sourceforge.phpdt.internal.ui.viewsupport.JavaElementLabels; +import net.sourceforge.phpdt.internal.ui.viewsupport.StorageLabelProvider; + +import org.eclipse.core.resources.IStorage; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + + + +/** + * Standard label provider for Java elements. + * Use this class when you want to present the Java elements in a viewer. + *

        + * The implementation also handles non-Java elements by forwarding the requests to the + * IWorkbenchAdapter of the element. + *

        + *

        + * This class may be instantiated; it is not intended to be subclassed. + *

        + */ +public class JavaElementLabelProvider extends LabelProvider { + + /** + * Flag (bit mask) indicating that methods labels include the method return type. (appended) + */ + public final static int SHOW_RETURN_TYPE= 0x001; + + /** + * Flag (bit mask) indicating that method label include method parameter types. + */ + public final static int SHOW_PARAMETERS= 0x002; + + /** + * Flag (bit mask) indicating that the label of a member should include the container. + * For example, include the name of the type enclosing a field. + * @deprecated Use SHOW_QUALIFIED or SHOW_ROOT instead + */ + public final static int SHOW_CONTAINER= 0x004; + + /** + * Flag (bit mask) indicating that the label of a type should be fully qualified. + * For example, include the fully qualified name of the type enclosing a type. + * @deprecated Use SHOW_QUALIFIED instead + */ + public final static int SHOW_CONTAINER_QUALIFICATION= 0x008; + + /** + * Flag (bit mask) indicating that the label should include overlay icons + * for element type and modifiers. + */ + public final static int SHOW_OVERLAY_ICONS= 0x010; + + /** + * Flag (bit mask) indicating thata field label should include the declared type. + */ + public final static int SHOW_TYPE= 0x020; + + /** + * Flag (bit mask) indicating that the label should include the name of the + * package fragment root (appended). + */ + public final static int SHOW_ROOT= 0x040; + + /** + * Flag (bit mask) indicating that the label qualification of a type should + * be shown after the name. + * @deprecated SHOW_POST_QUALIFIED instead + */ + public final static int SHOW_POSTIFIX_QUALIFICATION= 0x080; + + /** + * Flag (bit mask) indicating that the label should show the icons with no space + * reserved for overlays. + */ + public final static int SHOW_SMALL_ICONS= 0x100; + + /** + * Flag (bit mask) indicating that the packagefragment roots from variables should + * be rendered with the variable in the name + */ + public final static int SHOW_VARIABLE= 0x200; + + /** + * Flag (bit mask) indicating that Complation Units, Class Files, Types, Declarations and Members + * should be rendered qualified. + * Examples: java.lang.String, java.util.Vector.size() + * + * @since 2.0 + */ + public final static int SHOW_QUALIFIED= 0x400; + + /** + * Flag (bit mask) indicating that Complation Units, Class Files, Types, Declarations and Members + * should be rendered qualified. The qualifcation is appended + * Examples: String - java.lang, size() - java.util.Vector + * + * @since 2.0 + */ + public final static int SHOW_POST_QUALIFIED= 0x800; + + + /** + * Constant (value 0) indicating that the label should show + * the basic images only. + */ + public final static int SHOW_BASICS= 0x000; + + + /** + * Constant indicating the default label rendering. + * Currently the default is equivalent to + * SHOW_PARAMETERS | SHOW_OVERLAY_ICONS. + */ + public final static int SHOW_DEFAULT= new Integer(SHOW_PARAMETERS | SHOW_OVERLAY_ICONS).intValue(); + + private JavaElementImageProvider fImageLabelProvider; + + private StorageLabelProvider fStorageLabelProvider; + private int fFlags; + private int fImageFlags; + private int fTextFlags; + + /** + * Creates a new label provider with SHOW_DEFAULT flag. + * + * @see #SHOW_DEFAULT + * @since 2.0 + */ + public JavaElementLabelProvider() { + this(SHOW_DEFAULT); + } + + /** + * Creates a new label provider. + * + * @param flags the initial options; a bitwise OR of SHOW_* constants + */ + public JavaElementLabelProvider(int flags) { + fImageLabelProvider= new JavaElementImageProvider(); + fStorageLabelProvider= new StorageLabelProvider(); + fFlags= flags; + updateImageProviderFlags(); + updateTextProviderFlags(); + } + + private boolean getFlag( int flag) { + return (fFlags & flag) != 0; + } + + /** + * Turns on the rendering options specified in the given flags. + * + * @param flags the options; a bitwise OR of SHOW_* constants + */ + public void turnOn(int flags) { + fFlags |= flags; + updateImageProviderFlags(); + updateTextProviderFlags(); + } + + /** + * Turns off the rendering options specified in the given flags. + * + * @param flags the initial options; a bitwise OR of SHOW_* constants + */ + public void turnOff(int flags) { + fFlags &= (~flags); + updateImageProviderFlags(); + updateTextProviderFlags(); + } + + private void updateImageProviderFlags() { + fImageFlags= 0; + if (getFlag(SHOW_OVERLAY_ICONS)) { + fImageFlags |= JavaElementImageProvider.OVERLAY_ICONS; + } + if (getFlag(SHOW_SMALL_ICONS)) { + fImageFlags |= JavaElementImageProvider.SMALL_ICONS; + } + } + + private void updateTextProviderFlags() { + fTextFlags= 0; + if (getFlag(SHOW_RETURN_TYPE)) { + fTextFlags |= JavaElementLabels.M_APP_RETURNTYPE; + } + if (getFlag(SHOW_PARAMETERS)) { + fTextFlags |= JavaElementLabels.M_PARAMETER_TYPES; + } + if (getFlag(SHOW_CONTAINER)) { + fTextFlags |= JavaElementLabels.P_POST_QUALIFIED | JavaElementLabels.T_POST_QUALIFIED | JavaElementLabels.CF_POST_QUALIFIED | JavaElementLabels.CU_POST_QUALIFIED | JavaElementLabels.M_POST_QUALIFIED | JavaElementLabels.F_POST_QUALIFIED; + } + if (getFlag(SHOW_POSTIFIX_QUALIFICATION)) { + fTextFlags |= (JavaElementLabels.T_POST_QUALIFIED | JavaElementLabels.CF_POST_QUALIFIED | JavaElementLabels.CU_POST_QUALIFIED); + } else if (getFlag(SHOW_CONTAINER_QUALIFICATION)) { + fTextFlags |=(JavaElementLabels.T_FULLY_QUALIFIED | JavaElementLabels.CF_QUALIFIED | JavaElementLabels.CU_QUALIFIED); + } + if (getFlag(SHOW_TYPE)) { + fTextFlags |= JavaElementLabels.F_APP_TYPE_SIGNATURE; + } + if (getFlag(SHOW_ROOT)) { + fTextFlags |= JavaElementLabels.APPEND_ROOT_PATH; + } + if (getFlag(SHOW_VARIABLE)) { + fTextFlags |= JavaElementLabels.ROOT_VARIABLE; + } + if (getFlag(SHOW_QUALIFIED)) { + fTextFlags |= (JavaElementLabels.F_FULLY_QUALIFIED | JavaElementLabels.M_FULLY_QUALIFIED | JavaElementLabels.I_FULLY_QUALIFIED + | JavaElementLabels.T_FULLY_QUALIFIED | JavaElementLabels.D_QUALIFIED | JavaElementLabels.CF_QUALIFIED | JavaElementLabels.CU_QUALIFIED); + } + if (getFlag(SHOW_POST_QUALIFIED)) { + fTextFlags |= (JavaElementLabels.F_POST_QUALIFIED | JavaElementLabels.M_POST_QUALIFIED | JavaElementLabels.I_POST_QUALIFIED + | JavaElementLabels.T_POST_QUALIFIED | JavaElementLabels.D_POST_QUALIFIED | JavaElementLabels.CF_POST_QUALIFIED | JavaElementLabels.CU_POST_QUALIFIED); + } + } + + /* (non-Javadoc) + * @see ILabelProvider#getImage + */ + public Image getImage(Object element) { + Image result= fImageLabelProvider.getImageLabel(element, fImageFlags); + if (result != null) { + return result; + } + + if (element instanceof IStorage) + return fStorageLabelProvider.getImage(element); + + return result; + } + + /* (non-Javadoc) + * @see ILabelProvider#getText + */ + public String getText(Object element) { + String text= JavaElementLabels.getTextLabel(element, fTextFlags); + if (text.length() > 0) { + return text; + } + + if (element instanceof IStorage) + return fStorageLabelProvider.getText(element); + + return text; + } + + /* (non-Javadoc) + * + * @see IBaseLabelProvider#dispose + */ + public void dispose() { + fStorageLabelProvider.dispose(); + fImageLabelProvider.dispose(); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/JavaElementSorter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/JavaElementSorter.java new file mode 100644 index 0000000..95bcc5e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/JavaElementSorter.java @@ -0,0 +1,278 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.ui; + +import java.text.Collator; + +import net.sourceforge.phpdt.core.Flags; +import net.sourceforge.phpdt.core.IField; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IMethod; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.Signature; +import net.sourceforge.phpdt.internal.ui.preferences.MembersOrderPreferenceCache; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.viewers.ContentViewer; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.ui.model.IWorkbenchAdapter; + + +/** + * Sorter for Java elements. Ordered by element category, then by element name. + * Package fragment roots are sorted as ordered on the classpath. + * + *

        + * This class may be instantiated; it is not intended to be subclassed. + *

        + * + * @since 2.0 + */ +public class JavaElementSorter extends ViewerSorter { + + private static final int PROJECTS= 1; + private static final int PACKAGEFRAGMENTROOTS= 2; + private static final int PACKAGEFRAGMENT= 3; + + private static final int COMPILATIONUNITS= 4; + private static final int CLASSFILES= 5; + + private static final int RESOURCEFOLDERS= 7; + private static final int RESOURCES= 8; + private static final int STORAGE= 9; + + private static final int PACKAGE_DECL= 10; + private static final int IMPORT_CONTAINER= 11; + private static final int IMPORT_DECLARATION= 12; + + // Includes all categories ordered using the OutlineSortOrderPage: + // types, initializers, methods & fields + private static final int MEMBERSOFFSET= 15; + + private static final int JAVAELEMENTS= 50; + private static final int OTHERS= 51; + + public JavaElementSorter() { + super(null); // delay initialization of collator + } + + /** + * @deprecated Bug 22518. Method never used: does not override ViewerSorter#isSorterProperty(Object, String). + * Method could be removed, but kept for API compatibility. + */ + public boolean isSorterProperty(Object element, Object property) { + return true; + } + + /* + * @see ViewerSorter#category + */ + public int category(Object element) { + if (element instanceof IJavaElement) { + try { + IJavaElement je= (IJavaElement) element; + + switch (je.getElementType()) { + case IJavaElement.METHOD: + { + IMethod method= (IMethod) je; + if (method.isConstructor()) { + return getMemberCategory(MembersOrderPreferenceCache.CONSTRUCTORS_INDEX); + } + int flags= method.getFlags(); + if (Flags.isStatic(flags)) + return getMemberCategory(MembersOrderPreferenceCache.STATIC_METHODS_INDEX); + else + return getMemberCategory(MembersOrderPreferenceCache.METHOD_INDEX); + } + case IJavaElement.FIELD : + { + int flags= ((IField) je).getFlags(); + if (Flags.isStatic(flags)) + return getMemberCategory(MembersOrderPreferenceCache.STATIC_FIELDS_INDEX); + else + return getMemberCategory(MembersOrderPreferenceCache.FIELDS_INDEX); + } +// case IJavaElement.INITIALIZER : +// { +// int flags= ((IInitializer) je).getFlags(); +// if (Flags.isStatic(flags)) +// return getMemberCategory(MembersOrderPreferenceCache.STATIC_INIT_INDEX); +// else +// return getMemberCategory(MembersOrderPreferenceCache.INIT_INDEX); +// } + case IJavaElement.TYPE : + return getMemberCategory(MembersOrderPreferenceCache.TYPE_INDEX); + case IJavaElement.PACKAGE_DECLARATION : + return PACKAGE_DECL; + case IJavaElement.IMPORT_CONTAINER : + return IMPORT_CONTAINER; + case IJavaElement.IMPORT_DECLARATION : + return IMPORT_DECLARATION; + case IJavaElement.PACKAGE_FRAGMENT : + IPackageFragment pack= (IPackageFragment) je; + if (pack.getParent().getResource() instanceof IProject) { + return PACKAGEFRAGMENTROOTS; + } + return PACKAGEFRAGMENT; + case IJavaElement.PACKAGE_FRAGMENT_ROOT : + return PACKAGEFRAGMENTROOTS; + case IJavaElement.JAVA_PROJECT : + return PROJECTS; + case IJavaElement.CLASS_FILE : + return CLASSFILES; + case IJavaElement.COMPILATION_UNIT : + return COMPILATIONUNITS; + } + + } catch (JavaModelException e) { + PHPeclipsePlugin.log(e); + } + return JAVAELEMENTS; + } else if (element instanceof IFile) { + return RESOURCES; + } else if (element instanceof IProject) { + return PROJECTS; + } else if (element instanceof IContainer) { + return RESOURCEFOLDERS; + } else if (element instanceof IStorage) { + return STORAGE; +// } else if (element instanceof ClassPathContainer) { +// return PACKAGEFRAGMENTROOTS; + } + return OTHERS; + } + + private int getMemberCategory(int kind) { + int offset= PHPeclipsePlugin.getDefault().getMemberOrderPreferenceCache().getIndex(kind); + return offset + MEMBERSOFFSET; + } + + /* + * @see ViewerSorter#compare + */ + public int compare(Viewer viewer, Object e1, Object e2) { + int cat1= category(e1); + int cat2= category(e2); + + if (cat1 != cat2) + return cat1 - cat2; + + if (cat1 == PROJECTS) { + IWorkbenchAdapter a1= (IWorkbenchAdapter)((IAdaptable)e1).getAdapter(IWorkbenchAdapter.class); + IWorkbenchAdapter a2= (IWorkbenchAdapter)((IAdaptable)e2).getAdapter(IWorkbenchAdapter.class); + return getCollator().compare(a1.getLabel(e1), a2.getLabel(e2)); + } + +// if (cat1 == PACKAGEFRAGMENTROOTS) { +// IPackageFragmentRoot root1= getPackageFragmentRoot(e1); +// IPackageFragmentRoot root2= getPackageFragmentRoot(e2); +// if (!root1.getPath().equals(root2.getPath())) { +// int p1= getClassPathIndex(root1); +// int p2= getClassPathIndex(root2); +// if (p1 != p2) { +// return p1 - p2; +// } +// } +// } + // non - java resources are sorted using the label from the viewers label provider + if (cat1 == PROJECTS || cat1 == RESOURCES || cat1 == RESOURCEFOLDERS || cat1 == STORAGE || cat1 == OTHERS) { + return compareWithLabelProvider(viewer, e1, e2); + } + + String name1= ((IJavaElement) e1).getElementName(); + String name2= ((IJavaElement) e2).getElementName(); + + // java element are sorted by name + int cmp= getCollator().compare(name1, name2); + if (cmp != 0) { + return cmp; + } + + if (e1 instanceof IMethod) { + String[] params1= ((IMethod) e1).getParameterTypes(); + String[] params2= ((IMethod) e2).getParameterTypes(); + int len= Math.min(params1.length, params2.length); + for (int i = 0; i < len; i++) { + cmp= getCollator().compare(Signature.toString(params1[i]), Signature.toString(params2[i])); + if (cmp != 0) { + return cmp; + } + } + return params1.length - params2.length; + } + return 0; + } + +// private IPackageFragmentRoot getPackageFragmentRoot(Object element) { +// if (element instanceof ClassPathContainer) { +// // return first package fragment root from the container +// ClassPathContainer cp= (ClassPathContainer)element; +// Object[] roots= cp.getPackageFragmentRoots(); +// if (roots.length > 0) +// return (IPackageFragmentRoot)roots[0]; +// // non resolvable - return a dummy package fragment root +// return cp.getJavaProject().getPackageFragmentRoot("Non-Resolvable"); //$NON-NLS-1$ +// } +// return JavaModelUtil.getPackageFragmentRoot((IJavaElement)element); +// } + + private int compareWithLabelProvider(Viewer viewer, Object e1, Object e2) { + if (viewer == null || !(viewer instanceof ContentViewer)) { + IBaseLabelProvider prov = ((ContentViewer) viewer).getLabelProvider(); + if (prov instanceof ILabelProvider) { + ILabelProvider lprov= (ILabelProvider) prov; + String name1 = lprov.getText(e1); + String name2 = lprov.getText(e2); + if (name1 != null && name2 != null) { + return getCollator().compare(name1, name2); + } + } + } + return 0; // can't compare + } + +// private int getClassPathIndex(IPackageFragmentRoot root) { +// try { +// IPath rootPath= root.getPath(); +// IPackageFragmentRoot[] roots= root.getJavaProject().getPackageFragmentRoots(); +// for (int i= 0; i < roots.length; i++) { +// if (roots[i].getPath().equals(rootPath)) { +// return i; +// } +// } +// } catch (JavaModelException e) { +// } +// +// return Integer.MAX_VALUE; +// } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ViewerSorter#getCollator() + */ + public final Collator getCollator() { + if (collator == null) { + collator= Collator.getInstance(); + } + return collator; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/JavaUI.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/JavaUI.java new file mode 100644 index 0000000..23ff50e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/JavaUI.java @@ -0,0 +1,702 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.ui; + +import net.sourceforge.phpdt.core.IBufferFactory; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IWorkingCopy; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpeclipse.PHPCore; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.phpeditor.EditorUtility; +import net.sourceforge.phpeclipse.phpeditor.PHPDocumentProvider; + +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.internal.SharedImages; +import org.eclipse.ui.texteditor.IDocumentProvider; + +/** + * Central access point for the Java UI plug-in (id "org.eclipse.jdt.ui"). + * This class provides static methods for: + *
          + *
        • creating various kinds of selection dialogs to present a collection + * of Java elements to the user and let them make a selection.
        • + *
        • opening a Java editor on a compilation unit.
        • + *
        + *

        + * This class provides static methods and fields only; it is not intended to be + * instantiated or subclassed by clients. + *

        + */ +public final class JavaUI { + + private static ISharedImages fgSharedImages= null; + + private JavaUI() { + // prevent instantiation of JavaUI. + } + + /** + * The id of the Java plugin (value "org.eclipse.jdt.ui"). + */ +// public static final String ID_PLUGIN= "org.eclipse.jdt.ui"; //$NON-NLS-1$ + + /** + * The id of the Java perspective + * (value "org.eclipse.jdt.ui.JavaPerspective"). + */ +// public static final String ID_PERSPECTIVE= "org.eclipse.jdt.ui.JavaPerspective"; //$NON-NLS-1$ + + /** + * The id of the Java hierarchy perspective + * (value "org.eclipse.jdt.ui.JavaHierarchyPerspective"). + */ +// public static final String ID_HIERARCHYPERSPECTIVE= "org.eclipse.jdt.ui.JavaHierarchyPerspective"; //$NON-NLS-1$ + + /** + * The id of the Java action set + * (value "org.eclipse.jdt.ui.JavaActionSet"). + */ +// public static final String ID_ACTION_SET= "org.eclipse.jdt.ui.JavaActionSet"; //$NON-NLS-1$ + + /** + * The id of the Java Element Creation action set + * (value "org.eclipse.jdt.ui.JavaElementCreationActionSet"). + * + * @since 2.0 + */ +// public static final String ID_ELEMENT_CREATION_ACTION_SET= "org.eclipse.jdt.ui.JavaElementCreationActionSet"; //$NON-NLS-1$ + + /** + * The id of the Java Coding action set + * (value "org.eclipse.jdt.ui.CodingActionSet"). + * + * @since 2.0 + */ +// public static final String ID_CODING_ACTION_SET= "org.eclipse.jdt.ui.CodingActionSet"; //$NON-NLS-1$ + + /** + * The id of the Java action set for open actions + * (value "org.eclipse.jdt.ui.A_OpenActionSet"). + * + * @since 2.0 + */ +// public static final String ID_OPEN_ACTION_SET= "org.eclipse.jdt.ui.A_OpenActionSet"; //$NON-NLS-1$ + + /** + * The id of the Java Search action set + * (value org.eclipse.jdt.ui.SearchActionSet"). + * + * @since 2.0 + */ +// public static final String ID_SEARCH_ACTION_SET= "org.eclipse.jdt.ui.SearchActionSet"; //$NON-NLS-1$ + + /** + * The editor part id of the editor that presents Java compilation units + * (value "org.eclipse.jdt.ui.CompilationUnitEditor"). + */ +// public static final String ID_CU_EDITOR= "net.sourceforge.phpdt.ui.PHPUnitEditor"; //$NON-NLS-1$ + + /** + * The editor part id of the editor that presents Java binary class files + * (value "org.eclipse.jdt.ui.ClassFileEditor"). + */ +// public static final String ID_CF_EDITOR= "org.eclipse.jdt.ui.ClassFileEditor"; //$NON-NLS-1$ + + /** + * The editor part id of the code snippet editor + * (value "org.eclipse.jdt.ui.SnippetEditor"). + */ +// public static final String ID_SNIPPET_EDITOR= "org.eclipse.jdt.ui.SnippetEditor"; //$NON-NLS-1$ + + /** + * The view part id of the Packages view + * (value "org.eclipse.jdt.ui.PackageExplorer"). + *

        + * When this id is used to access + * a view part with IWorkbenchPage.findView or + * showView, the returned IViewPart + * can be safely cast to an IPackagesViewPart. + *

        + * + * @see IPackagesViewPart + * @see org.eclipse.ui.IWorkbenchPage#findView(java.lang.String) + * @see org.eclipse.ui.IWorkbenchPage#showView(java.lang.String) + */ + public static final String ID_PACKAGES= "net.sourceforge.phpdt.ui.PackageExplorer"; //$NON-NLS-1$ + + /** + * The view part id of the type hierarchy part. + * (value "org.eclipse.jdt.ui.TypeHierarchy"). + *

        + * When this id is used to access + * a view part with IWorkbenchPage.findView or + * showView, the returned IViewPart + * can be safely cast to an ITypeHierarchyViewPart. + *

        + * + * @see ITypeHierarchyViewPart + * @see org.eclipse.ui.IWorkbenchPage#findView(java.lang.String) + * @see org.eclipse.ui.IWorkbenchPage#showView(java.lang.String) + */ +// public static final String ID_TYPE_HIERARCHY= "org.eclipse.jdt.ui.TypeHierarchy"; //$NON-NLS-1$ + + /** + * The id of the Java Browsing Perspective + * (value "org.eclipse.jdt.ui.JavaBrowsingPerspective"). + * + * @since 2.0 + */ +// public static String ID_BROWSING_PERSPECTIVE= "org.eclipse.jdt.ui.JavaBrowsingPerspective"; //$NON-NLS-1$ + + /** + * The view part id of the Java Browsing Projects view + * (value "org.eclipse.jdt.ui.ProjectsView"). + * + * @since 2.0 + */ +// public static String ID_PROJECTS_VIEW= "org.eclipse.jdt.ui.ProjectsView"; //$NON-NLS-1$ + + /** + * The view part id of the Java Browsing Packages view + * (value "org.eclipse.jdt.ui.PackagesView"). + * + * @since 2.0 + */ +// public static String ID_PACKAGES_VIEW= "org.eclipse.jdt.ui.PackagesView"; //$NON-NLS-1$ + + /** + * The view part id of the Java Browsing Types view + * (value "org.eclipse.jdt.ui.TypesView"). + * + * @since 2.0 + */ +// public static String ID_TYPES_VIEW= "org.eclipse.jdt.ui.TypesView"; //$NON-NLS-1$ + + /** + * The view part id of the Java Browsing Members view + * (value "org.eclipse.jdt.ui.MembersView"). + * + * @since 2.0 + */ +// public static String ID_MEMBERS_VIEW= "org.eclipse.jdt.ui.MembersView"; //$NON-NLS-1$ + + /** + * The class org.eclipse.debug.core.model.IProcess allows attaching + * String properties to processes. The Java UI contributes a property + * page for IProcess that will show the contents of the property + * with this key. + * The intent of this property is to show the command line a process + * was launched with. + * @deprecated + */ +// public final static String ATTR_CMDLINE= "org.eclipse.jdt.ui.launcher.cmdLine"; //$NON-NLS-1$ + + /** + * Returns the shared images for the Java UI. + * + * @return the shared images manager + */ + public static ISharedImages getSharedImages() { + if (fgSharedImages == null) + fgSharedImages= new SharedImages(); + + return fgSharedImages; + } + + /** + * Creates a selection dialog that lists all packages of the given Java project. + * The caller is responsible for opening the dialog with Window.open, + * and subsequently extracting the selected package (of type + * IPackageFragment) via SelectionDialog.getResult. + * + * @param parent the parent shell of the dialog to be created + * @param project the Java project + * @param style flags defining the style of the dialog; the valid flags are: + * IJavaElementSearchConstants.CONSIDER_BINARIES, indicating that + * packages from binary package fragment roots should be included in addition + * to those from source package fragment roots; + * IJavaElementSearchConstants.CONSIDER_REQUIRED_PROJECTS, indicating that + * packages from required projects should be included as well. + * @param filter the initial pattern to filter the set of packages. For example "com" shows + * all packages starting with "com". The meta character '?' representing any character and + * '*' representing any string are supported. Clients can pass an empty string if no filtering + * is required. + * @return a new selection dialog + * @exception JavaModelException if the selection dialog could not be opened + * + * @since 2.0 + */ +// public static SelectionDialog createPackageDialog(Shell parent, IJavaProject project, int style, String filter) throws JavaModelException { +// Assert.isTrue((style | IJavaElementSearchConstants.CONSIDER_BINARIES | IJavaElementSearchConstants.CONSIDER_REQUIRED_PROJECTS) == +// (IJavaElementSearchConstants.CONSIDER_BINARIES | IJavaElementSearchConstants.CONSIDER_REQUIRED_PROJECTS)); +// +// IPackageFragmentRoot[] roots= null; +// if ((style & IJavaElementSearchConstants.CONSIDER_REQUIRED_PROJECTS) != 0) { +// roots= project.getAllPackageFragmentRoots(); +// } else { +// roots= project.getPackageFragmentRoots(); +// } +// +// List consideredRoots= null; +// if ((style & IJavaElementSearchConstants.CONSIDER_BINARIES) != 0) { +// consideredRoots= Arrays.asList(roots); +// } else { +// consideredRoots= new ArrayList(roots.length); +// for (int i= 0; i < roots.length; i++) { +// IPackageFragmentRoot root= roots[i]; +// if (root.getKind() != IPackageFragmentRoot.K_BINARY) +// consideredRoots.add(root); +// +// } +// } +// +// int flags= JavaElementLabelProvider.SHOW_DEFAULT; +// if (consideredRoots.size() > 1) +// flags= flags | JavaElementLabelProvider.SHOW_ROOT; +// +// List packages= new ArrayList(); +// Iterator iter= consideredRoots.iterator(); +// while(iter.hasNext()) { +// IPackageFragmentRoot root= (IPackageFragmentRoot)iter.next(); +// packages.addAll(Arrays.asList(root.getChildren())); +// } +// ElementListSelectionDialog dialog= new ElementListSelectionDialog(parent, new JavaElementLabelProvider(flags)); +// dialog.setIgnoreCase(false); +// dialog.setElements(packages.toArray()); // XXX inefficient +// dialog.setFilter(filter); +// return dialog; +// } + + /** + * Creates a selection dialog that lists all packages of the given Java project. + * The caller is responsible for opening the dialog with Window.open, + * and subsequently extracting the selected package (of type + * IPackageFragment) via SelectionDialog.getResult. + * + * @param parent the parent shell of the dialog to be created + * @param project the Java project + * @param style flags defining the style of the dialog; the valid flags are: + * IJavaElementSearchConstants.CONSIDER_BINARIES, indicating that + * packages from binary package fragment roots should be included in addition + * to those from source package fragment roots; + * IJavaElementSearchConstants.CONSIDER_REQUIRED_PROJECTS, indicating that + * packages from required projects should be included as well. + * @return a new selection dialog + * @exception JavaModelException if the selection dialog could not be opened + */ +// public static SelectionDialog createPackageDialog(Shell parent, IJavaProject project, int style) throws JavaModelException { +// return createPackageDialog(parent, project, style, ""); //$NON-NLS-1$ +// } + + /** + * Creates a selection dialog that lists all packages under the given package + * fragment root. + * The caller is responsible for opening the dialog with Window.open, + * and subsequently extracting the selected package (of type + * IPackageFragment) via SelectionDialog.getResult. + * + * @param parent the parent shell of the dialog to be created + * @param root the package fragment root + * @param filter the initial pattern to filter the set of packages. For example "com" shows + * all packages starting with "com". The meta character '?' representing any character and + * '*' representing any string are supported. Clients can pass an empty string if no filtering + * is required. + * @return a new selection dialog + * @exception JavaModelException if the selection dialog could not be opened + * + * @since 2.0 + */ +// public static SelectionDialog createPackageDialog(Shell parent, IPackageFragmentRoot root, String filter) throws JavaModelException { +// ElementListSelectionDialog dialog= new ElementListSelectionDialog(parent, new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT)); +// dialog.setIgnoreCase(false); +// dialog.setElements(root.getChildren()); +// dialog.setFilter(filter); +// return dialog; +// } + + /** + * Creates a selection dialog that lists all packages under the given package + * fragment root. + * The caller is responsible for opening the dialog with Window.open, + * and subsequently extracting the selected package (of type + * IPackageFragment) via SelectionDialog.getResult. + * + * @param parent the parent shell of the dialog to be created + * @param root the package fragment root + * @return a new selection dialog + * @exception JavaModelException if the selection dialog could not be opened + */ +// public static SelectionDialog createPackageDialog(Shell parent, IPackageFragmentRoot root) throws JavaModelException { +// return createPackageDialog(parent, root, ""); //$NON-NLS-1$ +// } + + /** + * Creates a selection dialog that lists all types in the given scope. + * The caller is responsible for opening the dialog with Window.open, + * and subsequently extracting the selected type(s) (of type + * IType) via SelectionDialog.getResult. + * + * @param parent the parent shell of the dialog to be created + * @param context the runnable context used to show progress when the dialog + * is being populated + * @param scope the scope that limits which types are included + * @param style flags defining the style of the dialog; the only valid values are + * IJavaElementSearchConstants.CONSIDER_CLASSES, + * CONSIDER_INTERFACES, or their bitwise OR + * (equivalent to CONSIDER_TYPES) + * @param multipleSelection true if multiple selection is allowed + * @param filter the initial pattern to filter the set of types. For example "Abstract" shows + * all types starting with "abstract". The meta character '?' representing any character and + * '*' representing any string are supported. Clients can pass an empty string if no filtering + * is required. + * @exception JavaModelException if the selection dialog could not be opened + * + * @since 2.0 + */ +// public static SelectionDialog createTypeDialog(Shell parent, IRunnableContext context, IJavaSearchScope scope, int style, boolean multipleSelection, String filter) throws JavaModelException { +// int elementKinds= 0; +// if (style == IJavaElementSearchConstants.CONSIDER_TYPES) { +// elementKinds= IJavaSearchConstants.TYPE; +// } else if (style == IJavaElementSearchConstants.CONSIDER_INTERFACES) { +// elementKinds= IJavaSearchConstants.INTERFACE; +// } else if (style == IJavaElementSearchConstants.CONSIDER_CLASSES) { +// elementKinds= IJavaSearchConstants.CLASS; +// } else { +// Assert.isTrue(false, "illegal style"); //$NON-NLS-1$ +// } +// if (multipleSelection) { +// MultiTypeSelectionDialog dialog= new MultiTypeSelectionDialog(parent, context, elementKinds, scope); +// dialog.setMessage(JavaUIMessages.getString("JavaUI.defaultDialogMessage")); //$NON-NLS-1$ +// dialog.setFilter(filter); +// return dialog; +// } else { +// TypeSelectionDialog dialog= new TypeSelectionDialog(parent, context, elementKinds, scope); +// dialog.setMessage(JavaUIMessages.getString("JavaUI.defaultDialogMessage")); //$NON-NLS-1$ +// dialog.setFilter(filter); +// return dialog; +// } +// } + + /** + * Creates a selection dialog that lists all types in the given scope. + * The caller is responsible for opening the dialog with Window.open, + * and subsequently extracting the selected type(s) (of type + * IType) via SelectionDialog.getResult. + * + * @param parent the parent shell of the dialog to be created + * @param context the runnable context used to show progress when the dialog + * is being populated + * @param scope the scope that limits which types are included + * @param style flags defining the style of the dialog; the only valid values are + * IJavaElementSearchConstants.CONSIDER_CLASSES, + * CONSIDER_INTERFACES, or their bitwise OR + * (equivalent to CONSIDER_TYPES) + * @param multipleSelection true if multiple selection is allowed + * @return a new selection dialog + * @exception JavaModelException if the selection dialog could not be opened + */ +// public static SelectionDialog createTypeDialog(Shell parent, IRunnableContext context, IJavaSearchScope scope, int style, boolean multipleSelection) throws JavaModelException { +// return createTypeDialog(parent, context, scope, style, multipleSelection, "");//$NON-NLS-1$ +// } + + /** + * Creates a selection dialog that lists all types in the given scope containing + * a standard main method. + * The caller is responsible for opening the dialog with Window.open, + * and subsequently extracting the selected type(s) (of type + * IType) via SelectionDialog.getResult. + * + * @param parent the parent shell of the dialog to be created + * @param context the runnable context used to show progress when the dialog + * is being populated + * @param scope the scope that limits which types are included + * @param style flags defining the style of the dialog; the only valid values are + * IJavaElementSearchConstants.CONSIDER_BINARIES, + * CONSIDER_EXTERNAL_JARS, or their bitwise OR, or 0 + * @param multipleSelection true if multiple selection is allowed + * @param filter the initial pattern to filter the set of types containg a main method. For + * example "App" shows all types starting with "app". The meta character '?' representing + * any character and '*' representing any string are supported. Clients can pass an empty + * string if no filtering is required. + * @return a new selection dialog + * + * @since 2.0 + */ +// public static SelectionDialog createMainTypeDialog(Shell parent, IRunnableContext context, IJavaSearchScope scope, int style, boolean multipleSelection, String filter) { +// if (multipleSelection) { +// MultiMainTypeSelectionDialog dialog= new MultiMainTypeSelectionDialog(parent, context, scope, style); +// dialog.setFilter(filter); +// return dialog; +// } else { +// MainTypeSelectionDialog dialog= new MainTypeSelectionDialog(parent, context, scope, style); +// dialog.setFilter(filter); +// return dialog; +// } +// } + + /** + * Creates a selection dialog that lists all types in the given scope containing + * a standard main method. + * The caller is responsible for opening the dialog with Window.open, + * and subsequently extracting the selected type(s) (of type + * IType) via SelectionDialog.getResult. + * + * @param parent the parent shell of the dialog to be created + * @param context the runnable context used to show progress when the dialog + * is being populated + * @param scope the scope that limits which types are included + * @param style flags defining the style of the dialog; the only valid values are + * IJavaElementSearchConstants.CONSIDER_BINARIES, + * CONSIDER_EXTERNAL_JARS, or their bitwise OR, or 0 + * @param multipleSelection true if multiple selection is allowed + * @return a new selection dialog + */ +// public static SelectionDialog createMainTypeDialog(Shell parent, IRunnableContext context, IJavaSearchScope scope, int style, boolean multipleSelection) { +// return createMainTypeDialog(parent, context, scope, style, multipleSelection, "");//$NON-NLS-1$ +// } + + /** + * Creates a selection dialog that lists all types in the given project. + * The caller is responsible for opening the dialog with Window.open, + * and subsequently extracting the selected type(s) (of type + * IType) via SelectionDialog.getResult. + * + * @param parent the parent shell of the dialog to be created + * @param context the runnable context used to show progress when the dialog + * is being populated + * @param project the Java project + * @param style flags defining the style of the dialog; the only valid values are + * IJavaElementSearchConstants.CONSIDER_CLASSES, + * CONSIDER_INTERFACES, or their bitwise OR + * (equivalent to CONSIDER_TYPES) + * @param multipleSelection true if multiple selection is allowed + * @return a new selection dialog + * @exception JavaModelException if the selection dialog could not be opened + */ +// public static SelectionDialog createTypeDialog(Shell parent, IRunnableContext context, IProject project, int style, boolean multipleSelection) throws JavaModelException { +// IJavaSearchScope scope= SearchEngine.createJavaSearchScope(new IJavaProject[] { JavaCore.create(project) }); +// return createTypeDialog(parent, context, scope, style, multipleSelection); +// } + + /** + * Opens a Java editor on the given Java element. The element can be a compilation unit + * or class file. If there already is an open Java editor for the given element, it is returned. + * + * @param element the input element; either a compilation unit + * (ICompilationUnit) or a class file (
        IClassFile) + * @return the editor, or null if wrong element type or opening failed + * @exception PartInitException if the editor could not be initialized + * @exception JavaModelException if this element does not exist or if an + * exception occurs while accessing its underlying resource + */ + public static IEditorPart openInEditor(IJavaElement element) throws JavaModelException, PartInitException { + return EditorUtility.openInEditor(element); + } + + /** + * Reveals the source range of the given source reference element in the + * given editor. No checking is done if the editor displays a compilation unit or + * class file that contains the given source reference. The editor simply reveals + * the source range denoted by the given source reference. + * + * @param part the editor displaying the compilation unit or class file + * @param element the source reference element defining the source range to be revealed + * + * @deprecated use revealInEditor(IEditorPart, IJavaElement) instead + */ +// public static void revealInEditor(IEditorPart part, ISourceReference element) { +// if (element instanceof IJavaElement) +// revealInEditor(part, (IJavaElement) element); +// } + + /** + * Reveals the given java element in the given editor. If the element is not an instance + * of ISourceReference this method result in a NOP. If it is a source + * reference no checking is done if the editor displays a compilation unit or class file that + * contains the source reference element. The editor simply reveals the source range + * denoted by the given element. + * + * @param part the editor displaying a compilation unit or class file + * @param element the element to be revealed + * + * @since 2.0 + */ +// public static void revealInEditor(IEditorPart part, IJavaElement element) { +// EditorUtility.revealInEditor(part, element); +// } + + /** + * Returns the working copy manager for the Java UI plug-in. + * + * @return the working copy manager for the Java UI plug-in + */ + public static IWorkingCopyManager getWorkingCopyManager() { + return PHPeclipsePlugin.getDefault().getWorkingCopyManager(); + } + + /** + * Answers the shared working copies currently registered for the Java plug-in. + * Note that the returned array can include working copies that are + * not on the class path of a Java project. + * + * @return the list of shared working copies + * + * @see org.eclipse.jdt.core.JavaCore#getSharedWorkingCopies(org.eclipse.jdt.core.IBufferFactory) + * @since 2.0 + */ + public static IWorkingCopy[] getSharedWorkingCopies() { + return PHPCore.getSharedWorkingCopies(getBufferFactory()); + } + + /** + * Answers the shared working copies that are on the class path of a Java + * project currently registered for the Java plug-in. + * + * + * @return the list of shared working copies + * + * @see #getSharedWorkingCopies() + * @since 2.1 + */ +// public static IWorkingCopy[] getSharedWorkingCopiesOnClasspath() { +// IWorkingCopy[] wcs= getSharedWorkingCopies(); +// List result= new ArrayList(wcs.length); +// for (int i = 0; i < wcs.length; i++) { +// IWorkingCopy wc= wcs[i]; +// if (wc instanceof IJavaElement) { +// IJavaElement je= (IJavaElement)wc; +// if (je.getJavaProject().isOnClasspath(je)) { +// result.add(wc); +// } +// } +// } +// return (IWorkingCopy[])result.toArray(new IWorkingCopy[result.size()]); +// } + + /** + * Returns the BufferFactory for the Java UI plug-in. + * + * @return the BufferFactory for the Java UI plug-in + * + * @see org.eclipse.jdt.core.IBufferFactory + * @since 2.0 + */ + public static IBufferFactory getBufferFactory() { + PHPDocumentProvider provider= PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider(); + if (provider != null) + return provider.getBufferFactory(); + return null; + } + + /** + * Returns the DocumentProvider used for Java compilation units. + * + * @return the DocumentProvider for Java compilation units. + * + * @see IDocumentProvider + * @since 2.0 + */ + public static IDocumentProvider getDocumentProvider() { + return PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider(); + } + + /** + * Sets the Javadoc location for an archive with the given path. + * + * @param archivePath the path of the library; this can be an workspace path + * or an external path in case of an external library. + * @param url The Javadoc location to set. This location should contain index.html and + * a file 'package-list'. null clears the current documentation + * location. + * + * @since 2.0 + */ +// public static void setLibraryJavadocLocation(IPath archivePath, URL url) { +// JavaDocLocations.setLibraryJavadocLocation(archivePath, url); +// } + + /** + * Returns the Javadoc location for an archive or null if no + * location is available. + * + * @param archivePath the path of the library. This can be an workspace path + * or an external path in case of an external library. + * + * @since 2.0 + */ +// public static URL getLibraryJavadocLocation(IPath archivePath) { +// return JavaDocLocations.getLibraryJavadocLocation(archivePath); +// } + + /** + * Sets the Javadoc location for a Java project. This location is used for + * all types located in the project's source folders. + * + * @param project the project + * @param url The Javadoc location to set. This location should contain index.html and + * a file 'package-list'. null clears the current documentation + * location. + * + * @since 2.1 + */ +// public static void setProjectJavadocLocation(IJavaProject project, URL url) { +// JavaDocLocations.setProjectJavadocLocation(project, url); +// } + + /** + * Returns the Javadoc location for a Java project or null if no + * location is available. This location is used for all types located in the project's + * source folders. + * + * @param project the project + * + * @since 2.1 + */ +// public static URL getProjectJavadocLocation(IJavaProject project) { +// return JavaDocLocations.getProjectJavadocLocation(project); +// } + + /** + * Returns the Javadoc base URL for an element. The base location contains the + * index file. This location doesn't have to exist. Returns + * null if no javadoc location has been attached to the + * element's library or project. Example of a returned URL is http://www. + * junit. org/junit/javadoc. + * + * @param The element for which the doc URL is requested. + * + * @since 2.0 + */ +// public static URL getJavadocBaseLocation(IJavaElement element) throws JavaModelException { +// return JavaDocLocations.getJavadocBaseLocation(element); +// } + + /** + * Returns the Javadoc URL for an element. Example of a returned URL is + * http://www.junit.org/junit/javadoc/junit/extensions/TestSetup.html. + * This returned location doesn't have to exist. Returns null + * if no javadoc location has been attached to the element's library or + * project. + * + * @param The element for which the doc URL is requested. + * @param includeAnchor If set, the URL contains an anchor for member references: + * http://www.junit.org/junit/javadoc/junit/extensions/TestSetup.html#run(junit.framework.TestResult). Note + * that this involves type resolving and is a more expensive call than without anchor. + * + * @since 2.0 + */ +// public static URL getJavadocLocation(IJavaElement element, boolean includeAnchor) throws JavaModelException { +// return JavaDocLocations.getJavadocLocation(element, includeAnchor); +// } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/OverrideIndicatorLabelDecorator.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/OverrideIndicatorLabelDecorator.java new file mode 100644 index 0000000..895ee73 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/OverrideIndicatorLabelDecorator.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.ui; + +import net.sourceforge.phpdt.core.Flags; +import net.sourceforge.phpdt.core.IMethod; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil; +import net.sourceforge.phpdt.internal.ui.PHPUiImages; +import net.sourceforge.phpdt.internal.ui.viewsupport.ImageDescriptorRegistry; +import net.sourceforge.phpdt.internal.ui.viewsupport.ImageImageDescriptor; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IDecoration; +import org.eclipse.jface.viewers.ILabelDecorator; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ILightweightLabelDecorator; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; + + +/** + * LabelDecorator that decorates an method's image with override or implements overlays. + * The viewer using this decorator is responsible for updating the images on element changes. + * + *

        + * This class may be instantiated; it is not intended to be subclassed. + *

        + * + * @since 2.0 + */ +public class OverrideIndicatorLabelDecorator implements ILabelDecorator, ILightweightLabelDecorator { + + private ImageDescriptorRegistry fRegistry; + private boolean fUseNewRegistry= false; + + /** + * Creates a decorator. The decorator creates an own image registry to cache + * images. + */ + public OverrideIndicatorLabelDecorator() { + this(null); + fUseNewRegistry= true; + } + + /* + * Creates decorator with a shared image registry. + * + * @param registry The registry to use or null to use the Java plugin's + * image registry. + */ + /** + * Note: This constructor is for internal use only. Clients should not call this constructor. + */ + public OverrideIndicatorLabelDecorator(ImageDescriptorRegistry registry) { + fRegistry= registry; + } + + private ImageDescriptorRegistry getRegistry() { + if (fRegistry == null) { + fRegistry= fUseNewRegistry ? new ImageDescriptorRegistry() : PHPeclipsePlugin.getImageDescriptorRegistry(); + } + return fRegistry; + } + + + /* (non-Javadoc) + * @see ILabelDecorator#decorateText(String, Object) + */ + public String decorateText(String text, Object element) { + return text; + } + + /* (non-Javadoc) + * @see ILabelDecorator#decorateImage(Image, Object) + */ + public Image decorateImage(Image image, Object element) { + int adornmentFlags= computeAdornmentFlags(element); + if (adornmentFlags != 0) { + ImageDescriptor baseImage= new ImageImageDescriptor(image); + Rectangle bounds= image.getBounds(); + return getRegistry().get(new JavaElementImageDescriptor(baseImage, adornmentFlags, new Point(bounds.width, bounds.height))); + } + return image; + } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ + public int computeAdornmentFlags(Object element) { + if (element instanceof IMethod) { + if (!PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.APPEARANCE_OVERRIDE_INDICATOR)) { + return 0; + } + + try { + IMethod method= (IMethod) element; +// if (!method.getJavaProject().isOnClasspath(method)) { +// return 0; +// } + + int flags= method.getFlags(); + IType type = method.getDeclaringType();//jsurfer INSERT + if (type!=null && type.isClass() && !method.isConstructor() && !Flags.isPrivate(flags) && !Flags.isStatic(flags)) { + return getOverrideIndicators(method); + } + } catch (JavaModelException e) { + if (!e.isDoesNotExist()) { + PHPeclipsePlugin.log(e); + } + } + } + return 0; + } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ + protected int getOverrideIndicators(IMethod method) throws JavaModelException { + IType type= method.getDeclaringType(); +// ITypeHierarchy hierarchy= SuperTypeHierarchyCache.getTypeHierarchy(type); +// if (hierarchy != null) { +// return findInHierarchy(type, hierarchy, method.getElementName(), method.getParameterTypes()); +// } + return 0; + } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ +// protected int findInHierarchy(IType type, ITypeHierarchy hierarchy, String name, String[] paramTypes) throws JavaModelException { +// IMethod impl= JavaModelUtil.findMethodDeclarationInHierarchy(hierarchy, type, name, paramTypes, false); +// if (impl != null) { +// IMethod overridden= JavaModelUtil.findMethodImplementationInHierarchy(hierarchy, type, name, paramTypes, false); +// if (overridden != null) { +// return JavaElementImageDescriptor.OVERRIDES; +// } else { +// return JavaElementImageDescriptor.IMPLEMENTS; +// } +// } +// return 0; +// } + + /* (non-Javadoc) + * @see IBaseLabelProvider#addListener(ILabelProviderListener) + */ + public void addListener(ILabelProviderListener listener) { + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#dispose() + */ + public void dispose() { + if (fRegistry != null && fUseNewRegistry) { + fRegistry.dispose(); + } + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#isLabelProperty(Object, String) + */ + public boolean isLabelProperty(Object element, String property) { + return true; + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#removeListener(ILabelProviderListener) + */ + public void removeListener(ILabelProviderListener listener) { + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILightweightLabelDecorator#decorate(java.lang.Object, org.eclipse.jface.viewers.IDecoration) + */ + public void decorate(Object element, IDecoration decoration) { + int adornmentFlags= computeAdornmentFlags(element); + if (adornmentFlags != 0) { + decoration.addOverlay(PHPUiImages.DESC_OVR_OVERRIDES); + } + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java index 58b13a2..1b6474c 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java @@ -13,6 +13,7 @@ package net.sourceforge.phpdt.ui; import net.sourceforge.phpeclipse.IPreferenceConstants; import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import org.eclipse.jface.action.Action; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; import org.eclipse.jface.resource.JFaceResources; @@ -383,6 +384,36 @@ public class PreferenceConstants { *

        */ public static final String JAVADOC_COMMAND = "command"; //$NON-NLS-1$ + /** + * A named preference that defines the key for the hover modifiers. + * + * @see JavaUI + * @since 2.1 + */ + public static final String EDITOR_TEXT_HOVER_MODIFIERS = "hoverModifiers"; //$NON-NLS-1$ + /** + * The id of the best match hover contributed for extension point + * javaEditorTextHovers. + * + * @since 2.1 + */ + public static String ID_BESTMATCH_HOVER= "net.sourceforge.phpdt.ui.BestMatchHover"; //$NON-NLS-1$ + + /** + * The id of the source code hover contributed for extension point + * javaEditorTextHovers. + * + * @since 2.1 + */ + public static String ID_SOURCE_HOVER= "net.sourceforge.phpdt.ui.JavaSourceHover"; //$NON-NLS-1$ + + /** + * The id of the problem hover contributed for extension point + * javaEditorTextHovers. + * + * @since 2.1 + */ + public static String ID_PROBLEM_HOVER = "net.sourceforge.phpdt.ui.ProblemHover"; //$NON-NLS-1$ /** * A named preference that controls whether bracket matching highlighting is turned on or off. @@ -942,26 +973,25 @@ public class PreferenceConstants { */ public final static String EDITOR_SINGLE_LINE_COMMENT_BOLD = IPreferenceConstants.PHP_SINGLELINE_COMMENT + EDITOR_BOLD_SUFFIX; - /** - * A named preference that holds the color used to render php start and stop tags. - *

        - * Value is of type String. A RGB color value encoded as a string - * using class PreferenceConverter - *

        - * - * @see org.eclipse.jface.resource.StringConverter - * @see org.eclipse.jface.preference.PreferenceConverter - */ - public final static String EDITOR_JAVA_TAG_COLOR = IPreferenceConstants.PHP_TAG; - - /** - * A named preference that controls whether php start and stop tags are rendered in bold. - *

        - * Value is of type Boolean. - *

        - */ - public final static String EDITOR_JAVA_TAG_BOLD = IPreferenceConstants.PHP_TAG + EDITOR_BOLD_SUFFIX; + /** + * A named preference that holds the color used to render php start and stop tags. + *

        + * Value is of type String. A RGB color value encoded as a string + * using class PreferenceConverter + *

        + * + * @see org.eclipse.jface.resource.StringConverter + * @see org.eclipse.jface.preference.PreferenceConverter + */ + public final static String EDITOR_JAVA_TAG_COLOR = IPreferenceConstants.PHP_TAG; + /** + * A named preference that controls whether php start and stop tags are rendered in bold. + *

        + * Value is of type Boolean. + *

        + */ + public final static String EDITOR_JAVA_TAG_BOLD = IPreferenceConstants.PHP_TAG + EDITOR_BOLD_SUFFIX; /** * A named preference that holds the color used to render php keywords. @@ -1667,6 +1697,17 @@ public class PreferenceConstants { */ public static final String EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK = "browserLikeLinksKeyModifierMask"; //$NON-NLS-1$ + /** + * A named preference that defines the key for the hover modifier state masks. + * The value is only used if the value of EDITOR_TEXT_HOVER_MODIFIERS + * cannot be resolved to valid SWT modifier bits. + * + * @see JavaUI + * @see #EDITOR_TEXT_HOVER_MODIFIERS + * @since 2.1.1 + */ + public static final String EDITOR_TEXT_HOVER_MODIFIER_MASKS = "hoverModifierMasks"; //$NON-NLS-1$ + public static void initializeDefaultValues(IPreferenceStore store) { store.setDefault(PreferenceConstants.EDITOR_SHOW_SEGMENTS, false); @@ -1803,9 +1844,9 @@ public class PreferenceConstants { PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_COLOR, new RGB(63, 127, 95)); store.setDefault(PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_BOLD, false); - PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_JAVA_TAG_COLOR, new RGB(255, 0, 128)); - store.setDefault(PreferenceConstants.EDITOR_JAVA_TAG_BOLD, true); - + PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_JAVA_TAG_COLOR, new RGB(255, 0, 128)); + store.setDefault(PreferenceConstants.EDITOR_JAVA_TAG_BOLD, true); + PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_JAVA_KEYWORD_COLOR, new RGB(127, 0, 85)); store.setDefault(PreferenceConstants.EDITOR_JAVA_KEYWORD_BOLD, true); @@ -1882,6 +1923,14 @@ public class PreferenceConstants { store.setDefault(PreferenceConstants.EDITOR_ALT_SHIFT_HOVER, PreferenceConstants.EDITOR_DEFAULT_HOVER_CONFIGURED_ID); store.setDefault(PreferenceConstants.EDITOR_CTRL_ALT_SHIFT_HOVER, PreferenceConstants.EDITOR_DEFAULT_HOVER_CONFIGURED_ID); + String ctrl = Action.findModifierString(SWT.CTRL); + store.setDefault(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS, "net.sourceforge.phpdt.ui.BestMatchHover;0;net.sourceforge.phpdt.ui.JavaSourceHover;" + ctrl); //$NON-NLS-1$ + store.setDefault(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS, "net.sourceforge.phpdt.ui.BestMatchHover;0;net.sourceforge.phpdt.ui.JavaSourceHover;" + SWT.CTRL); //$NON-NLS-1$ + + store.setDefault(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS, true); + store.setDefault(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER, ctrl); + store.setDefault(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK, SWT.CTRL); + // do more complicated stuff // NewJavaProjectPreferencePage.initDefaults(store); } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/ProblemsLabelDecorator.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/ProblemsLabelDecorator.java new file mode 100644 index 0000000..53e172d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/ProblemsLabelDecorator.java @@ -0,0 +1,359 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.ui; + +import java.util.Iterator; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.ISourceRange; +import net.sourceforge.phpdt.core.ISourceReference; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.ui.PHPUiImages; +import net.sourceforge.phpdt.internal.ui.viewsupport.IProblemChangedListener; +import net.sourceforge.phpdt.internal.ui.viewsupport.ImageDescriptorRegistry; +import net.sourceforge.phpdt.internal.ui.viewsupport.ImageImageDescriptor; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.util.ListenerList; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IDecoration; +import org.eclipse.jface.viewers.ILabelDecorator; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ILightweightLabelDecorator; +import org.eclipse.jface.viewers.LabelProviderChangedEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.texteditor.MarkerAnnotation; + +/** + * LabelDecorator that decorates an element's image with error and warning overlays that + * represent the severity of markers attached to the element's underlying resource. To see + * a problem decoration for a marker, the marker needs to be a subtype of IMarker.PROBLEM. + *

        + * Note: Only images for elements in Java projects are currently updated on marker changes. + *

        + * + * @since 2.0 + */ +public class ProblemsLabelDecorator implements ILabelDecorator, ILightweightLabelDecorator { + + /** + * This is a special LabelProviderChangedEvent carring additional + * information whether the event orgins from a maker change. + *

        + * ProblemsLabelChangedEvents are only generated by + * ProblemsLabelDecorators. + *

        + */ + public static class ProblemsLabelChangedEvent extends LabelProviderChangedEvent { + + private boolean fMarkerChange; + + /** + * Note: This constructor is for internal use only. Clients should not call this constructor. + */ + public ProblemsLabelChangedEvent(IBaseLabelProvider source, IResource[] changedResource, boolean isMarkerChange) { + super(source, changedResource); + fMarkerChange= isMarkerChange; + } + + /** + * Returns whether this event origins from marker changes. If false an annotation + * model change is the origin. In this case viewers not displaying working copies can ignore these + * events. + * + * @return if this event origins from a marker change. + */ + public boolean isMarkerChange() { + return fMarkerChange; + } + + } + + private static final int ERRORTICK_WARNING= JavaElementImageDescriptor.WARNING; + private static final int ERRORTICK_ERROR= JavaElementImageDescriptor.ERROR; + + private ImageDescriptorRegistry fRegistry; + private boolean fUseNewRegistry= false; + private IProblemChangedListener fProblemChangedListener; + + private ListenerList fListeners; + + /** + * Creates a new ProblemsLabelDecorator. + */ + public ProblemsLabelDecorator() { + this(null); + fUseNewRegistry= true; + } + + /* + * Creates decorator with a shared image registry. + * + * @param registry The registry to use or null to use the Java plugin's + * image registry. + */ + /** + * Note: This constructor is for internal use only. Clients should not call this constructor. + */ + public ProblemsLabelDecorator(ImageDescriptorRegistry registry) { + fRegistry= registry; + fProblemChangedListener= null; + } + + private ImageDescriptorRegistry getRegistry() { + if (fRegistry == null) { + fRegistry= fUseNewRegistry ? new ImageDescriptorRegistry() : PHPeclipsePlugin.getImageDescriptorRegistry(); + } + return fRegistry; + } + + + /* (non-Javadoc) + * @see ILabelDecorator#decorateText(String, Object) + */ + public String decorateText(String text, Object element) { + return text; + } + + /* (non-Javadoc) + * @see ILabelDecorator#decorateImage(Image, Object) + */ + public Image decorateImage(Image image, Object obj) { + int adornmentFlags= computeAdornmentFlags(obj); + if (adornmentFlags != 0) { + ImageDescriptor baseImage= new ImageImageDescriptor(image); + Rectangle bounds= image.getBounds(); + return getRegistry().get(new JavaElementImageDescriptor(baseImage, adornmentFlags, new Point(bounds.width, bounds.height))); + } + return image; + } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ + protected int computeAdornmentFlags(Object obj) { + try { + if (obj instanceof IJavaElement) { + IJavaElement element= (IJavaElement) obj; + int type= element.getElementType(); + switch (type) { + case IJavaElement.JAVA_PROJECT: + case IJavaElement.PACKAGE_FRAGMENT_ROOT: + return getErrorTicksFromMarkers(element.getResource(), IResource.DEPTH_INFINITE, null); + case IJavaElement.PACKAGE_FRAGMENT: + case IJavaElement.CLASS_FILE: + return getErrorTicksFromMarkers(element.getResource(), IResource.DEPTH_ONE, null); + case IJavaElement.COMPILATION_UNIT: + case IJavaElement.PACKAGE_DECLARATION: + case IJavaElement.IMPORT_DECLARATION: + case IJavaElement.IMPORT_CONTAINER: + case IJavaElement.TYPE: + case IJavaElement.INITIALIZER: + case IJavaElement.METHOD: + case IJavaElement.FIELD: + ICompilationUnit cu= (ICompilationUnit) element.getAncestor(IJavaElement.COMPILATION_UNIT); + if (cu != null) { + ISourceReference ref= (type == IJavaElement.COMPILATION_UNIT) ? null : (ISourceReference) element; + // The assumption is that only source elements in compilation unit can have markers + if (cu.isWorkingCopy()) { + // working copy: look at annotation model + return getErrorTicksFromWorkingCopy((ICompilationUnit) cu.getOriginalElement(), ref); + } + return getErrorTicksFromMarkers(cu.getResource(), IResource.DEPTH_ONE, ref); + } + break; + default: + } + } else if (obj instanceof IResource) { + return getErrorTicksFromMarkers((IResource) obj, IResource.DEPTH_INFINITE, null); + } + } catch (CoreException e) { + if (e instanceof JavaModelException) { + if (((JavaModelException) e).isDoesNotExist()) { + return 0; + } + } + PHPeclipsePlugin.log(e); + } + return 0; + } + + private int getErrorTicksFromMarkers(IResource res, int depth, ISourceReference sourceElement) throws CoreException { + if (res == null || !res.isAccessible()) { + return 0; + } + int info= 0; + + IMarker[] markers= res.findMarkers(IMarker.PROBLEM, true, depth); + if (markers != null) { + for (int i= 0; i < markers.length && (info != ERRORTICK_ERROR); i++) { + IMarker curr= markers[i]; + if (sourceElement == null || isMarkerInRange(curr, sourceElement)) { + int priority= curr.getAttribute(IMarker.SEVERITY, -1); + if (priority == IMarker.SEVERITY_WARNING) { + info= ERRORTICK_WARNING; + } else if (priority == IMarker.SEVERITY_ERROR) { + info= ERRORTICK_ERROR; + } + } + } + } + return info; + } + + private boolean isMarkerInRange(IMarker marker, ISourceReference sourceElement) throws CoreException { + if (marker.isSubtypeOf(IMarker.TEXT)) { + int pos= marker.getAttribute(IMarker.CHAR_START, -1); + return isInside(pos, sourceElement); + } + return false; + } + + + private int getErrorTicksFromWorkingCopy(ICompilationUnit original, ISourceReference sourceElement) throws CoreException { + int info= 0; + FileEditorInput editorInput= new FileEditorInput((IFile) original.getResource()); + IAnnotationModel model= PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider().getAnnotationModel(editorInput); + if (model != null) { + Iterator iter= model.getAnnotationIterator(); + while ((info != ERRORTICK_ERROR) && iter.hasNext()) { + Annotation curr= (Annotation) iter.next(); + IMarker marker= isAnnotationInRange(model, curr, sourceElement); + if (marker != null) { + int priority= marker.getAttribute(IMarker.SEVERITY, -1); + if (priority == IMarker.SEVERITY_WARNING) { + info= ERRORTICK_WARNING; + } else if (priority == IMarker.SEVERITY_ERROR) { + info= ERRORTICK_ERROR; + } + } + } + } + return info; + } + + private IMarker isAnnotationInRange(IAnnotationModel model, Annotation annot, ISourceReference sourceElement) throws CoreException { + if (annot instanceof MarkerAnnotation) { + IMarker marker= ((MarkerAnnotation) annot).getMarker(); + if (marker.exists() && marker.isSubtypeOf(IMarker.PROBLEM)) { + Position pos= model.getPosition(annot); + if (sourceElement == null || isInside(pos.getOffset(), sourceElement)) { + return marker; + } + } + } + return null; + } + + /** + * Tests if a position is inside the source range of an element. + * @param pos Position to be tested. + * @param sourceElement Source element (must be a IJavaElement) + * @return boolean Return true if position is located inside the source element. + * @throws CoreException Exception thrown if element range could not be accessed. + * + * @since 2.1 + */ + protected boolean isInside(int pos, ISourceReference sourceElement) throws CoreException { + ISourceRange range= sourceElement.getSourceRange(); + if (range != null) { + int rangeOffset= range.getOffset(); + return (rangeOffset <= pos && rangeOffset + range.getLength() > pos); + } + return false; + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#dispose() + */ + public void dispose() { + if (fProblemChangedListener != null) { + PHPeclipsePlugin.getDefault().getProblemMarkerManager().removeListener(fProblemChangedListener); + fProblemChangedListener= null; + } + if (fRegistry != null && fUseNewRegistry) { + fRegistry.dispose(); + } + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#isLabelProperty(Object, String) + */ + public boolean isLabelProperty(Object element, String property) { + return true; + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#addListener(ILabelProviderListener) + */ + public void addListener(ILabelProviderListener listener) { + if (fListeners == null) { + fListeners= new ListenerList(); + } + fListeners.add(listener); + if (fProblemChangedListener == null) { + fProblemChangedListener= new IProblemChangedListener() { + public void problemsChanged(IResource[] changedResources, boolean isMarkerChange) { + fireProblemsChanged(changedResources, isMarkerChange); + } + }; + PHPeclipsePlugin.getDefault().getProblemMarkerManager().addListener(fProblemChangedListener); + } + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#removeListener(ILabelProviderListener) + */ + public void removeListener(ILabelProviderListener listener) { + if (fListeners != null) { + fListeners.remove(listener); + if (fListeners.isEmpty() && fProblemChangedListener != null) { + PHPeclipsePlugin.getDefault().getProblemMarkerManager().removeListener(fProblemChangedListener); + fProblemChangedListener= null; + } + } + } + + private void fireProblemsChanged(IResource[] changedResources, boolean isMarkerChange) { + if (fListeners != null && !fListeners.isEmpty()) { + LabelProviderChangedEvent event= new ProblemsLabelChangedEvent(this, changedResources, isMarkerChange); + Object[] listeners= fListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) { + ((ILabelProviderListener) listeners[i]).labelProviderChanged(event); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILightweightLabelDecorator#decorate(java.lang.Object, org.eclipse.jface.viewers.IDecoration) + */ + public void decorate(Object element, IDecoration decoration) { + int adornmentFlags= computeAdornmentFlags(element); + if (adornmentFlags == ERRORTICK_ERROR) { + decoration.addOverlay(PHPUiImages.DESC_OVR_ERROR); + } else if (adornmentFlags == ERRORTICK_WARNING) { + decoration.addOverlay(PHPUiImages.DESC_OVR_WARNING); + } + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/StandardJavaElementContentProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/StandardJavaElementContentProvider.java new file mode 100644 index 0000000..21b7dc1 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/StandardJavaElementContentProvider.java @@ -0,0 +1,449 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.ui; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaElementDelta; +import net.sourceforge.phpdt.core.IJavaModel; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; +import net.sourceforge.phpdt.core.IParent; +import net.sourceforge.phpdt.core.ISourceReference; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil; +import net.sourceforge.phpeclipse.PHPCore; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + + +/** + * A base content provider for Java elements. It provides access to the + * Java element hierarchy without listening to changes in the Java model. + * If updating the presentation on Java model change is required than + * clients have to subclass, listen to Java model changes and have to update + * the UI using corresponding methods provided by the JFace viewers or their + * own UI presentation. + *

        + * The following Java element hierarchy is surfaced by this content provider: + *

        + *

        +Java model (IJavaModel)
        +   Java project (IJavaProject)
        +      package fragment root (IPackageFragmentRoot)
        +         package fragment (IPackageFragment)
        +            compilation unit (ICompilationUnit)
        +            binary class file (IClassFile)
        + * 
        + *

        + *

        + * Note that when the entire Java project is declared to be package fragment root, + * the corresponding package fragment root element that normally appears between the + * Java project and the package fragments is automatically filtered out. + *

        + * This content provider can optionally return working copy elements for members + * below compilation units. If enabled, working copy members are returned for those + * compilation units in the Java element hierarchy for which a shared working copy exists + * in JDT core. + * + * @see org.eclipse.jdt.ui.IWorkingCopyProvider + * @see JavaCore#getSharedWorkingCopies(org.eclipse.jdt.core.IBufferFactory) + * + * @since 2.0 + */ +public class StandardJavaElementContentProvider implements ITreeContentProvider, IWorkingCopyProvider { + + protected static final Object[] NO_CHILDREN= new Object[0]; + + protected boolean fProvideMembers= false; + protected boolean fProvideWorkingCopy= false; + + /** + * Creates a new content provider. The content provider does not + * provide members of compilation units or class files and it does + * not provide working copy elements. + */ + public StandardJavaElementContentProvider() { + } + + /** + * Creates a new StandardJavaElementContentProvider. + * + * @param provideMembers if true members below compilation units + * and class files are provided. + * @param provideWorkingCopy if true the element provider provides + * working copies members of compilation units which have an associated working + * copy in JDT core. Otherwise only original elements are provided. + */ + public StandardJavaElementContentProvider(boolean provideMembers, boolean provideWorkingCopy) { + fProvideMembers= provideMembers; + fProvideWorkingCopy= provideWorkingCopy; + } + + /** + * Returns whether members are provided when asking + * for a compilation units or class file for its children. + * + * @return true if the content provider provides members; + * otherwise false is returned + */ + public boolean getProvideMembers() { + return fProvideMembers; + } + + /** + * Sets whether the content provider is supposed to return members + * when asking a compilation unit or class file for its children. + * + * @param b if true then members are provided. + * If false compilation units and class files are the + * leaves provided by this content provider. + */ + public void setProvideMembers(boolean b) { + fProvideMembers= b; + } + + /** + * Returns whether the provided members are from a working + * copy or the original compilation unit. + * + * @return true if the content provider provides + * working copy members; otherwise false is + * returned + * + * @see #setProvideWorkingCopy(boolean) + */ + public boolean getProvideWorkingCopy() { + return fProvideWorkingCopy; + } + + /** + * Sets whether the members are provided from a shared working copy + * that exists for a original compilation unit in the Java element hierarchy. + * + * @param b if true members are provided from a + * working copy if one exists in JDT core. If false the + * provider always returns original elements. + */ + public void setProvideWorkingCopy(boolean b) { + fProvideWorkingCopy= b; + } + + /* (non-Javadoc) + * @see IWorkingCopyProvider#providesWorkingCopies() + */ + public boolean providesWorkingCopies() { + return fProvideWorkingCopy; + } + + /* (non-Javadoc) + * Method declared on IStructuredContentProvider. + */ + public Object[] getElements(Object parent) { + return getChildren(parent); + } + + /* (non-Javadoc) + * Method declared on IContentProvider. + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + /* (non-Javadoc) + * Method declared on IContentProvider. + */ + public void dispose() { + } + + /* (non-Javadoc) + * Method declared on ITreeContentProvider. + */ + public Object[] getChildren(Object element) { + if (!exists(element)) + return NO_CHILDREN; + + try { + if (element instanceof IJavaModel) + return getJavaProjects((IJavaModel)element); + +// if (element instanceof IJavaProject) +// return getPackageFragmentRoots((IJavaProject)element); +// + if (element instanceof IPackageFragmentRoot) + return getPackageFragments((IPackageFragmentRoot)element); + +// if (element instanceof IPackageFragment) +// return getPackageContents((IPackageFragment)element); + + if (element instanceof IFolder) + return getResources((IFolder)element); + + if (fProvideMembers && element instanceof ISourceReference && element instanceof IParent) { + if (fProvideWorkingCopy && element instanceof ICompilationUnit) { + element= JavaModelUtil.toWorkingCopy((ICompilationUnit) element); + } + return ((IParent)element).getChildren(); + } + } catch (JavaModelException e) { + return NO_CHILDREN; + } + return NO_CHILDREN; + } + + /* (non-Javadoc) + * @see ITreeContentProvider + */ + public boolean hasChildren(Object element) { + if (fProvideMembers) { + // assume CUs and class files are never empty + if (element instanceof ICompilationUnit ){ +// || +// element instanceof IClassFile) { + return true; + } + } else { + // don't allow to drill down into a compilation unit or class file + if (element instanceof ICompilationUnit || +// element instanceof IClassFile || + element instanceof IFile) + return false; + } + + if (element instanceof IJavaProject) { + IJavaProject jp= (IJavaProject)element; + if (!jp.getProject().isOpen()) { + return false; + } + } + + if (element instanceof IParent) { + try { + // when we have Java children return true, else we fetch all the children + if (((IParent)element).hasChildren()) + return true; + } catch(JavaModelException e) { + return true; + } + } + Object[] children= getChildren(element); + return (children != null) && children.length > 0; + } + + /* (non-Javadoc) + * Method declared on ITreeContentProvider. + */ + public Object getParent(Object element) { + if (!exists(element)) + return null; + return internalGetParent(element); + } + + private Object[] getPackageFragments(IPackageFragmentRoot root) throws JavaModelException { + IJavaElement[] fragments= root.getChildren(); +// Object[] nonJavaResources= root.getNonJavaResources(); +// if (nonJavaResources == null) + return fragments; +// return concatenate(fragments, nonJavaResources); + } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ +// protected Object[] getPackageFragmentRoots(IJavaProject project) throws JavaModelException { +// if (!project.getProject().isOpen()) +// return NO_CHILDREN; +// +// IPackageFragmentRoot[] roots= project.getPackageFragmentRoots(); +// List list= new ArrayList(roots.length); +// // filter out package fragments that correspond to projects and +// // replace them with the package fragments directly +// for (int i= 0; i < roots.length; i++) { +// IPackageFragmentRoot root= (IPackageFragmentRoot)roots[i]; +// if (isProjectPackageFragmentRoot(root)) { +// Object[] children= root.getChildren(); +// for (int k= 0; k < children.length; k++) +// list.add(children[k]); +// } +// else if (hasChildren(root)) { +// list.add(root); +// } +// } +// return concatenate(list.toArray(), project.getNonJavaResources()); +// } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ + protected Object[] getJavaProjects(IJavaModel jm) throws JavaModelException { + return jm.getJavaProjects(); + } + +// private Object[] getPackageContents(IPackageFragment fragment) throws JavaModelException { +// if (fragment.getKind() == IPackageFragmentRoot.K_SOURCE) { +// return concatenate(fragment.getCompilationUnits(), fragment.getNonJavaResources()); +// } +// return concatenate(fragment.getClassFiles(), fragment.getNonJavaResources()); +// } + + private Object[] getResources(IFolder folder) { + try { + // filter out folders that are package fragment roots + Object[] members= folder.members(); + List nonJavaResources= new ArrayList(); + for (int i= 0; i < members.length; i++) { + Object o= members[i]; + // A folder can also be a package fragement root in the following case + // Project + // + src <- source folder + // + excluded <- excluded from class path + // + included <- a new source folder. + // Included is a member of excluded, but since it is rendered as a source + // folder we have to exclude it as a normal child. + if (o instanceof IFolder) { + IJavaElement element= PHPCore.create((IFolder)o); + if (element instanceof IPackageFragmentRoot && element.exists()) { + continue; + } + } + nonJavaResources.add(o); + } + return nonJavaResources.toArray(); + } catch(CoreException e) { + return NO_CHILDREN; + } + } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ + protected boolean isClassPathChange(IJavaElementDelta delta) { + + // need to test the flags only for package fragment roots + if (delta.getElement().getElementType() != IJavaElement.PACKAGE_FRAGMENT_ROOT) + return false; + + int flags= delta.getFlags(); + return (delta.getKind() == IJavaElementDelta.CHANGED && + ((flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) != 0) || + ((flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0) || + ((flags & IJavaElementDelta.F_REORDER) != 0)); + } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ + protected Object skipProjectPackageFragmentRoot(IPackageFragmentRoot root) { + try { + if (isProjectPackageFragmentRoot(root)) + return root.getParent(); + return root; + } catch(JavaModelException e) { + return root; + } + } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ + protected boolean isPackageFragmentEmpty(IJavaElement element) throws JavaModelException { + if (element instanceof IPackageFragment) { + IPackageFragment fragment= (IPackageFragment)element; + if (!(fragment.hasChildren() ) ) +// || +// fragment.getNonJavaResources().length > 0) && fragment.hasSubpackages()) + return true; + } + return false; + } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ + protected boolean isProjectPackageFragmentRoot(IPackageFragmentRoot root) throws JavaModelException { + IResource resource= root.getResource(); + return (resource instanceof IProject); + } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ + protected boolean exists(Object element) { + if (element == null) { + return false; + } + if (element instanceof IResource) { + return ((IResource)element).exists(); + } + if (element instanceof IJavaElement) { + return ((IJavaElement)element).exists(); + } + return true; + } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ + protected Object internalGetParent(Object element) { + if (element instanceof IJavaProject) { + return ((IJavaProject)element).getJavaModel(); + } + // try to map resources to the containing package fragment + if (element instanceof IResource) { + IResource parent= ((IResource)element).getParent(); + IJavaElement jParent= PHPCore.create(parent); + // http://bugs.eclipse.org/bugs/show_bug.cgi?id=31374 + if (jParent != null && jParent.exists()) + return jParent; + return parent; + } + + // for package fragments that are contained in a project package fragment + // we have to skip the package fragment root as the parent. + if (element instanceof IPackageFragment) { + IPackageFragmentRoot parent= (IPackageFragmentRoot)((IPackageFragment)element).getParent(); + return skipProjectPackageFragmentRoot(parent); + } + if (element instanceof IJavaElement) { + IJavaElement candidate= ((IJavaElement)element).getParent(); + // If the parent is a CU we might have shown working copy elements below CU level. If so + // return the original element instead of the working copy. + if (candidate != null && candidate.getElementType() == IJavaElement.COMPILATION_UNIT) { + candidate= JavaModelUtil.toOriginal((ICompilationUnit) candidate); + } + return candidate; + } + return null; + } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ + protected static Object[] concatenate(Object[] a1, Object[] a2) { + int a1Len= a1.length; + int a2Len= a2.length; + Object[] res= new Object[a1Len + a2Len]; + System.arraycopy(a1, 0, res, 0, a1Len); + System.arraycopy(a2, 0, res, a1Len, a2Len); + return res; + } + + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/MemberFilterActionGroup.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/MemberFilterActionGroup.java new file mode 100644 index 0000000..48815ed --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/MemberFilterActionGroup.java @@ -0,0 +1,273 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.ui.actions; + +import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds; +import net.sourceforge.phpdt.internal.ui.PHPUiImages; +import net.sourceforge.phpdt.internal.ui.actions.ActionMessages; +import net.sourceforge.phpdt.internal.ui.viewsupport.MemberFilter; +import net.sourceforge.phpdt.internal.ui.viewsupport.MemberFilterAction; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.actions.ActionGroup; + +/** + * Action Group that contributes filter buttons for a view parts showing + * methods and fields. Contributed filters are: hide fields, hide static + * members and hide non-public members. + *

        + * The action group installs a filter on a structured viewer. The filter is connected + * to the actions installed in the view part's toolbar menu and is updated when the + * state of the buttons changes. + * + *

        + * This class may be instantiated; it is not intended to be subclassed. + *

        + * + * @since 2.0 + */ +public class MemberFilterActionGroup extends ActionGroup { + + public static final int FILTER_NONPUBLIC= MemberFilter.FILTER_NONPUBLIC; + public static final int FILTER_STATIC= MemberFilter.FILTER_STATIC; + public static final int FILTER_FIELDS= MemberFilter.FILTER_FIELDS; + + private static final String TAG_HIDEFIELDS= "hidefields"; //$NON-NLS-1$ + private static final String TAG_HIDESTATIC= "hidestatic"; //$NON-NLS-1$ + private static final String TAG_HIDENONPUBLIC= "hidenonpublic"; //$NON-NLS-1$ + + private MemberFilterAction[] fFilterActions; + private MemberFilter fFilter; + + private StructuredViewer fViewer; + private String fViewerId; + private boolean fInViewMenu; + + + /** + * Creates a new MemberFilterActionGroup. + * + * @param viewer the viewer to be filtered + * @param viewerId a unique id of the viewer. Used as a key to to store + * the last used filter settings in the preference store + */ + public MemberFilterActionGroup(StructuredViewer viewer, String viewerId) { + this(viewer, viewerId, false); + } + + /** + * Creates a new MemberFilterActionGroup. + * + * @param viewer the viewer to be filtered + * @param viewerId a unique id of the viewer. Used as a key to to store + * the last used filter settings in the preference store + * @param inViewMenu if true the actions are added to the view + * menu. If false they are added to the toobar. + * + * @since 2.1 + */ + public MemberFilterActionGroup(StructuredViewer viewer, String viewerId, boolean inViewMenu) { + fViewer= viewer; + fViewerId= viewerId; + fInViewMenu= inViewMenu; + + // get initial values + IPreferenceStore store= PHPeclipsePlugin.getDefault().getPreferenceStore(); + boolean doHideFields= store.getBoolean(getPreferenceKey(FILTER_FIELDS)); + boolean doHideStatic= store.getBoolean(getPreferenceKey(FILTER_STATIC)); + boolean doHidePublic= store.getBoolean(getPreferenceKey(FILTER_NONPUBLIC)); + + fFilter= new MemberFilter(); + if (doHideFields) + fFilter.addFilter(FILTER_FIELDS); + if (doHideStatic) + fFilter.addFilter(FILTER_STATIC); + if (doHidePublic) + fFilter.addFilter(FILTER_NONPUBLIC); + + // fields + String title= ActionMessages.getString("MemberFilterActionGroup.hide_fields.label"); //$NON-NLS-1$ + String helpContext= IJavaHelpContextIds.FILTER_FIELDS_ACTION; + MemberFilterAction hideFields= new MemberFilterAction(this, title, FILTER_FIELDS, helpContext, doHideFields); + hideFields.setDescription(ActionMessages.getString("MemberFilterActionGroup.hide_fields.description")); //$NON-NLS-1$ + hideFields.setToolTipText(ActionMessages.getString("MemberFilterActionGroup.hide_fields.tooltip")); //$NON-NLS-1$ + PHPUiImages.setLocalImageDescriptors(hideFields, "fields_co.gif"); //$NON-NLS-1$ + + // static + title= ActionMessages.getString("MemberFilterActionGroup.hide_static.label"); //$NON-NLS-1$ + helpContext= IJavaHelpContextIds.FILTER_STATIC_ACTION; + MemberFilterAction hideStatic= new MemberFilterAction(this, title, FILTER_STATIC, helpContext, doHideStatic); + hideStatic.setDescription(ActionMessages.getString("MemberFilterActionGroup.hide_static.description")); //$NON-NLS-1$ + hideStatic.setToolTipText(ActionMessages.getString("MemberFilterActionGroup.hide_static.tooltip")); //$NON-NLS-1$ + PHPUiImages.setLocalImageDescriptors(hideStatic, "static_co.gif"); //$NON-NLS-1$ + + // non-public + title= ActionMessages.getString("MemberFilterActionGroup.hide_nonpublic.label"); //$NON-NLS-1$ + helpContext= IJavaHelpContextIds.FILTER_PUBLIC_ACTION; + MemberFilterAction hideNonPublic= new MemberFilterAction(this, title, FILTER_NONPUBLIC, helpContext, doHidePublic); + hideNonPublic.setDescription(ActionMessages.getString("MemberFilterActionGroup.hide_nonpublic.description")); //$NON-NLS-1$ + hideNonPublic.setToolTipText(ActionMessages.getString("MemberFilterActionGroup.hide_nonpublic.tooltip")); //$NON-NLS-1$ + PHPUiImages.setLocalImageDescriptors(hideNonPublic, "public_co.gif"); //$NON-NLS-1$ + + // order corresponds to order in toolbar + fFilterActions= new MemberFilterAction[] { hideFields, hideStatic, hideNonPublic }; + + fViewer.addFilter(fFilter); + } + + private String getPreferenceKey(int filterProperty) { + return "MemberFilterActionGroup." + fViewerId + '.' + String.valueOf(filterProperty); //$NON-NLS-1$ + } + + /** + * Sets the member filters. + * + * @param filterProperty the filter to be manipulated. Valid values are FILTER_FIELDS, + * FILTER_PUBLIC, and FILTER_PRIVATE as defined by this action + * group + * @param set if true the given filter is installed. If false the + * given filter is removed + * . + */ + public void setMemberFilter(int filterProperty, boolean set) { + setMemberFilters(new int[] {filterProperty}, new boolean[] {set}, true); + } + + private void setMemberFilters(int[] propertyKeys, boolean[] propertyValues, boolean refresh) { + if (propertyKeys.length == 0) + return; + Assert.isTrue(propertyKeys.length == propertyValues.length); + + for (int i= 0; i < propertyKeys.length; i++) { + int filterProperty= propertyKeys[i]; + boolean set= propertyValues[i]; + if (set) { + fFilter.addFilter(filterProperty); + } else { + fFilter.removeFilter(filterProperty); + } + IPreferenceStore store= PHPeclipsePlugin.getDefault().getPreferenceStore(); + + for (int j= 0; j < fFilterActions.length; j++) { + int currProperty= fFilterActions[j].getFilterProperty(); + if (currProperty == filterProperty) { + fFilterActions[j].setChecked(set); + } + store.setValue(getPreferenceKey(currProperty), hasMemberFilter(currProperty)); + } + } + if (refresh) { + fViewer.getControl().setRedraw(false); + BusyIndicator.showWhile(fViewer.getControl().getDisplay(), new Runnable() { + public void run() { + fViewer.refresh(); + } + }); + fViewer.getControl().setRedraw(true); + } + } + + /** + * Returns true if the given filter is installed. + * + * @param filterProperty the filter to be tested. Valid values are FILTER_FIELDS, + * FILTER_PUBLIC, and FILTER_PRIVATE as defined by this action + * group + */ + public boolean hasMemberFilter(int filterProperty) { + return fFilter.hasFilter(filterProperty); + } + + /** + * Saves the state of the filter actions in a memento. + * + * @param memento the memento to which the state is saved + */ + public void saveState(IMemento memento) { + memento.putString(TAG_HIDEFIELDS, String.valueOf(hasMemberFilter(FILTER_FIELDS))); + memento.putString(TAG_HIDESTATIC, String.valueOf(hasMemberFilter(FILTER_STATIC))); + memento.putString(TAG_HIDENONPUBLIC, String.valueOf(hasMemberFilter(FILTER_NONPUBLIC))); + } + + /** + * Restores the state of the filter actions from a memento. + *

        + * Note: This method does not refresh the viewer. + *

        + * @param memento the memento from which the state is restored + */ + public void restoreState(IMemento memento) { + setMemberFilters( + new int[] {FILTER_FIELDS, FILTER_STATIC, FILTER_NONPUBLIC}, + new boolean[] { + Boolean.valueOf(memento.getString(TAG_HIDEFIELDS)).booleanValue(), + Boolean.valueOf(memento.getString(TAG_HIDESTATIC)).booleanValue(), + Boolean.valueOf(memento.getString(TAG_HIDENONPUBLIC)).booleanValue() + }, false); + } + + /* (non-Javadoc) + * @see ActionGroup#fillActionBars(IActionBars) + */ + public void fillActionBars(IActionBars actionBars) { + contributeToToolBar(actionBars.getToolBarManager()); + }; + + /** + * Adds the filter actions to the given tool bar + * + * @param tbm the tool bar to which the actions are added + */ + public void contributeToToolBar(IToolBarManager tbm) { + if (fInViewMenu) + return; + tbm.add(fFilterActions[0]); // fields + tbm.add(fFilterActions[1]); // static + tbm.add(fFilterActions[2]); // public + } + + /** + * Adds the filter actions to the given menu manager. + * + * @param menu the menu manager to which the actions are added + * @since 2.1 + */ + public void contributeToViewMenu(IMenuManager menu) { + if (!fInViewMenu) + return; + final String filters= "filters"; //$NON-NLS-1$ + if (menu.find(filters) != null) { + menu.prependToGroup(filters, fFilterActions[0]); // fields + menu.prependToGroup(filters, fFilterActions[1]); // static + menu.prependToGroup(filters, fFilterActions[2]); // public + } else { + menu.add(fFilterActions[0]); // fields + menu.add(fFilterActions[1]); // static + menu.add(fFilterActions[2]); // public + } + } + + /* (non-Javadoc) + * @see ActionGroup#dispose() + */ + public void dispose() { + super.dispose(); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/JavaTextTools.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/JavaTextTools.java index 6d4f394..4bad7d2 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/JavaTextTools.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/JavaTextTools.java @@ -10,10 +10,13 @@ import net.sourceforge.phpdt.internal.ui.text.JavaColorManager; import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCodeScanner; import net.sourceforge.phpeclipse.IPreferenceConstants; import net.sourceforge.phpeclipse.phpeditor.php.HTMLCodeScanner; +import net.sourceforge.phpeclipse.phpeditor.php.IPHPPartitionScannerConstants; import net.sourceforge.phpeclipse.phpeditor.php.PHPCodeScanner; +import net.sourceforge.phpeclipse.phpeditor.php.PHPPartitionScanner; import net.sourceforge.phpeclipse.phpeditor.php.SmartyCodeScanner; import net.sourceforge.phpeclipse.phpeditor.php.SmartyDocCodeScanner; +import org.eclipse.core.runtime.Preferences; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.IDocumentPartitioner; import org.eclipse.jface.text.rules.DefaultPartitioner; @@ -40,10 +43,35 @@ import org.eclipse.jface.util.PropertyChangeEvent; */ public class JavaTextTools { - private class PreferenceListener implements IPropertyChangeListener { + private static PHPPartitionScanner HTML_PARTITION_SCANNER = null; + + private static PHPPartitionScanner PHP_PARTITION_SCANNER = null; + private static PHPPartitionScanner SMARTY_PARTITION_SCANNER = null; + + // private final static String[] TYPES= new String[] { PHPPartitionScanner.PHP, PHPPartitionScanner.JAVA_DOC, PHPPartitionScanner.JAVA_MULTILINE_COMMENT }; + private final static String[] TYPES = + new String[] { + IPHPPartitionScannerConstants.PHP, + IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT, + IPHPPartitionScannerConstants.HTML, + IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT, + IPHPPartitionScannerConstants.JAVASCRIPT, + IPHPPartitionScannerConstants.CSS, + IPHPPartitionScannerConstants.SMARTY, + IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT }; + private static PHPPartitionScanner XML_PARTITION_SCANNER = null; + + /** + * This tools' preference listener. + */ + private class PreferenceListener implements IPropertyChangeListener, Preferences.IPropertyChangeListener { public void propertyChange(PropertyChangeEvent event) { adaptToPreferenceChange(event); } + public void propertyChange(Preferences.PropertyChangeEvent event) { + adaptToPreferenceChange( + new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event.getNewValue())); + } }; /** The color manager */ @@ -69,6 +97,11 @@ public class JavaTextTools { /** The preference store */ private IPreferenceStore fPreferenceStore; + /** + * The core preference store. + * @since 2.1 + */ + private Preferences fCorePreferenceStore; /** The preference change listener */ private PreferenceListener fPreferenceListener = new PreferenceListener(); @@ -100,6 +133,42 @@ public class JavaTextTools { } /** + * Creates a new Java text tools collection. + * + * @param store the preference store to initialize the text tools. The text tool + * instance installs a listener on the passed preference store to adapt itself to + * changes in the preference store. In general PreferenceConstants. + * getPreferenceStore() shoould be used to initialize the text tools. + * @param coreStore optional preference store to initialize the text tools. The text tool + * instance installs a listener on the passed preference store to adapt itself to + * changes in the preference store. + * @param autoDisposeOnDisplayDispose if true the color manager + * automatically disposes all managed colors when the current display gets disposed + * and all calls to {@link org.eclipse.jface.text.source.ISharedTextColors#dispose()} are ignored. + * @see org.eclipse.jdt.ui.PreferenceConstants#getPreferenceStore() + * @since 2.1 + */ + public JavaTextTools(IPreferenceStore store, Preferences coreStore, boolean autoDisposeOnDisplayDispose) { + fPreferenceStore = store; + fPreferenceStore.addPropertyChangeListener(fPreferenceListener); + + fCorePreferenceStore = coreStore; + if (fCorePreferenceStore != null) + fCorePreferenceStore.addPropertyChangeListener(fPreferenceListener); + + fColorManager = new JavaColorManager(autoDisposeOnDisplayDispose); + fCodeScanner = new PHPCodeScanner(fColorManager, store); + fMultilineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_MULTILINE_COMMENT); + fSinglelineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_SINGLELINE_COMMENT); + fStringScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_STRING); + fPHPDocScanner = new PHPDocCodeScanner(fColorManager, store); + fHTMLScanner = new HTMLCodeScanner(fColorManager, store); + fSmartyScanner = new SmartyCodeScanner(fColorManager, store); + fSmartyDocScanner = new SmartyDocCodeScanner(fColorManager, store); + fPartitionScanner = new FastJavaPartitionScanner(); + } + + /** * Disposes all the individual tools of this tools collection. */ public void dispose() { @@ -119,6 +188,12 @@ public class JavaTextTools { if (fPreferenceStore != null) { fPreferenceStore.removePropertyChangeListener(fPreferenceListener); fPreferenceStore = null; + + if (fCorePreferenceStore != null) { + fCorePreferenceStore.removePropertyChangeListener(fPreferenceListener); + fCorePreferenceStore = null; + } + fPreferenceListener = null; } } @@ -230,22 +305,60 @@ public class JavaTextTools { } /** - * Factory method for creating a Java-specific document partitioner + * Factory method for creating a PHP-specific document partitioner * using this object's partitions scanner. This method is a * convenience method. * * @return a newly created Java document partitioner */ public IDocumentPartitioner createDocumentPartitioner() { + return createDocumentPartitioner(".php"); + } - String[] types = - new String[] { - FastJavaPartitionScanner.JAVA_DOC, - FastJavaPartitionScanner.JAVA_MULTI_LINE_COMMENT, - FastJavaPartitionScanner.JAVA_SINGLE_LINE_COMMENT, - FastJavaPartitionScanner.JAVA_STRING }; + /** + * Factory method for creating a PHP-specific document partitioner + * using this object's partitions scanner. This method is a + * convenience method. + * + * @return a newly created Java document partitioner + */ + public IDocumentPartitioner createDocumentPartitioner(String extension) { - return new DefaultPartitioner(getPartitionScanner(), types); + // String[] types = + // new String[] { + // FastJavaPartitionScanner.JAVA_DOC, + // FastJavaPartitionScanner.JAVA_MULTI_LINE_COMMENT, + // FastJavaPartitionScanner.JAVA_SINGLE_LINE_COMMENT, + // FastJavaPartitionScanner.JAVA_STRING }; + // + // return new DefaultPartitioner(getPartitionScanner(), types); + IDocumentPartitioner partitioner = null; + // System.out.println(extension); + if (extension.equalsIgnoreCase(".html") || extension.equalsIgnoreCase(".htm")) { + // html + partitioner = createHTMLPartitioner(); + } else if (extension.equalsIgnoreCase(".xml")) { + // xml + partitioner = createXMLPartitioner(); + } else if (extension.equalsIgnoreCase(".js")) { + // javascript + partitioner = createJavaScriptPartitioner(); + } else if (extension.equalsIgnoreCase(".css")) { + // cascading style sheets + partitioner = createCSSPartitioner(); + } else if (extension.equalsIgnoreCase(".tpl")) { + // smarty ? + partitioner = createSmartyPartitioner(); + } else if (extension.equalsIgnoreCase(".inc")) { + // php include files ? + partitioner = createIncludePartitioner(); + } + + if (partitioner == null) { + partitioner = createPHPPartitioner(); + } + + return partitioner; } /** @@ -297,4 +410,73 @@ public class JavaTextTools { if (fPHPDocScanner.affectsBehavior(event)) fPHPDocScanner.adaptToPreferenceChange(event); } + + /** + * Return a partitioner for .html files. + */ + private static IDocumentPartitioner createHTMLPartitioner() { + return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES); + } + + private static IDocumentPartitioner createIncludePartitioner() { + return new DefaultPartitioner(getPHPPartitionScanner(), TYPES); + } + + private static IDocumentPartitioner createJavaScriptPartitioner() { + return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES); + } + + /** + * Return a partitioner for .php files. + */ + private static IDocumentPartitioner createPHPPartitioner() { + return new DefaultPartitioner(getPHPPartitionScanner(), TYPES); + } + + private static IDocumentPartitioner createSmartyPartitioner() { + return new DefaultPartitioner(getSmartyPartitionScanner(), TYPES); + } + + private static IDocumentPartitioner createXMLPartitioner() { + return new DefaultPartitioner(getXMLPartitionScanner(), TYPES); + } + + private static IDocumentPartitioner createCSSPartitioner() { + return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES); + } + /** + * Return a scanner for creating html partitions. + */ + private static PHPPartitionScanner getHTMLPartitionScanner() { + if (HTML_PARTITION_SCANNER == null) + HTML_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.HTML_FILE); + return HTML_PARTITION_SCANNER; + } + /** + * Return a scanner for creating php partitions. + */ + private static PHPPartitionScanner getPHPPartitionScanner() { + if (PHP_PARTITION_SCANNER == null) + PHP_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.PHP_FILE); + return PHP_PARTITION_SCANNER; + } + + /** + * Return a scanner for creating smarty partitions. + */ + private static PHPPartitionScanner getSmartyPartitionScanner() { + if (SMARTY_PARTITION_SCANNER == null) + SMARTY_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.SMARTY_FILE); + return SMARTY_PARTITION_SCANNER; + } + + /** + * Return a scanner for creating xml partitions. + */ + private static PHPPartitionScanner getXMLPartitionScanner() { + if (XML_PARTITION_SCANNER == null) + XML_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.XML_FILE); + return XML_PARTITION_SCANNER; + } + } \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/java/hover/IJavaEditorTextHover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/java/hover/IJavaEditorTextHover.java new file mode 100644 index 0000000..337a481 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/java/hover/IJavaEditorTextHover.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.ui.text.java.hover; + +import org.eclipse.jface.text.ITextHover; + +import org.eclipse.ui.IEditorPart; + +/** + * Provides a hover popup which appears on top of an editor with relevant + * display information. If the text hover does not provide information no + * hover popup is shown. + *

        + * Clients may implement this interface.

        + * + * @see org.eclipse.ui.IEditorPart + * @see org.eclipse.jface.text.ITextHover + * + * @since 2.0 + */ +public interface IJavaEditorTextHover extends ITextHover { + + /** + * Sets the editor on which the hover is shown. + * + * @param editor the editor on which the hover popup should be shown + */ + void setEditor(IEditorPart editor); + +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/java/hover/package.html b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/java/hover/package.html new file mode 100644 index 0000000..7cfda13 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/java/hover/package.html @@ -0,0 +1,16 @@ + + + + + + + Package-level Javadoc + + +Application programming interfaces for interaction with the PHPeclipse PHP Editor. +

        +Package Specification

        +Support for presenting text hovers in PHP editors. The interface IJavaEditorTextHover +defines the programming interface for a text hover. + + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewContainerWizardPage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewContainerWizardPage.java index 4460b0b..7dddc0f 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewContainerWizardPage.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewContainerWizardPage.java @@ -13,7 +13,6 @@ package net.sourceforge.phpdt.ui.wizards; import net.sourceforge.phpdt.core.IJavaElement; import net.sourceforge.phpdt.core.IJavaProject; import net.sourceforge.phpdt.core.IPackageFragmentRoot; -import net.sourceforge.phpdt.core.JavaCore; import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.externaltools.internal.ui.StatusInfo; import net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider; @@ -23,6 +22,7 @@ import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IDialogFieldListen import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IStringButtonAdapter; import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil; import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.StringButtonDialogField; +import net.sourceforge.phpeclipse.PHPCore; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import org.eclipse.core.resources.IProject; @@ -141,7 +141,7 @@ public abstract class NewContainerWizardPage extends NewElementWizardPage { jelem= (IJavaElement) resource.getAdapter(IJavaElement.class); } if (jelem == null) { - jelem= JavaCore.create(resource); // java project + jelem= PHPCore.create(resource); // java project } } } @@ -163,7 +163,7 @@ public abstract class NewContainerWizardPage extends NewElementWizardPage { if (jelem == null || jelem.getElementType() == IJavaElement.JAVA_MODEL) { try { - IJavaProject[] projects= JavaCore.create(getWorkspaceRoot()).getJavaProjects(); + IJavaProject[] projects= PHPCore.create(getWorkspaceRoot()).getJavaProjects(); if (projects.length == 1) { jelem= projects[0]; } @@ -270,7 +270,7 @@ public abstract class NewContainerWizardPage extends NewElementWizardPage { status.setError(NewWizardMessages.getFormattedString("NewContainerWizardPage.error.ProjectClosed", proj.getFullPath().toString())); //$NON-NLS-1$ return status; } - IJavaProject jproject= JavaCore.create(proj); + IJavaProject jproject= PHPCore.create(proj); // fCurrRoot= jproject.getPackageFragmentRoot(res); // if (res.exists()) { // try { diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/IPreferenceConstants.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/IPreferenceConstants.java index 5d5ef64..d0ebcf4 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/IPreferenceConstants.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/IPreferenceConstants.java @@ -113,13 +113,13 @@ public interface IPreferenceConstants { // public static final String PHPDOC_DEFAULT= "_php_doc_default"; //$NON-NLS-1$ /*Language stuff - under dev*/ - public static final String RESOURCE_BUNDLE = "_php_editor_res_bundle"; //$NON-NLS-1$ - public static final String LANGUAGE_DEFAULT = "net.sourceforge.phpeclipse.newPHPPreferencesMessages_en_GB"; - public static final String RESOURCE_BUNDLE_DE = "net.sourceforge.phpeclipse.newPHPPreferencesMessages_DE"; - public static final String RESOURCE_BUNDLE_FR = "net.sourceforge.phpeclipse.newPHPPreferencesMessages_FR"; - public static final String RESOURCE_BUNDLE_ES = "net.sourceforge.phpeclipse.newPHPPreferencesMessages_es_ES"; - public static final String RESOURCE_BUNDLE_EN_GB = "net.sourceforge.phpeclipse.newPHPPreferencesMessages_en_GB"; - public static final String RESOURCE_BUNDLE_JA = "net.sourceforge.phpeclipse.newPHPPreferencesMessages_JA"; +// public static final String RESOURCE_BUNDLE = "_php_editor_res_bundle"; //$NON-NLS-1$ +// public static final String LANGUAGE_DEFAULT = "net.sourceforge.phpeclipse.newPHPPreferencesMessages_en_GB"; +// public static final String RESOURCE_BUNDLE_DE = "net.sourceforge.phpeclipse.newPHPPreferencesMessages_DE"; +// public static final String RESOURCE_BUNDLE_FR = "net.sourceforge.phpeclipse.newPHPPreferencesMessages_FR"; +// public static final String RESOURCE_BUNDLE_ES = "net.sourceforge.phpeclipse.newPHPPreferencesMessages_es_ES"; +// public static final String RESOURCE_BUNDLE_EN_GB = "net.sourceforge.phpeclipse.newPHPPreferencesMessages_en_GB"; +// public static final String RESOURCE_BUNDLE_JA = "net.sourceforge.phpeclipse.newPHPPreferencesMessages_JA"; //public static final String FORMATTER_TAB_SIZE = "_formatter_tab_size"; //public static final String SPACES_FOR_TABS = "_formatter_tab_size"; diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPCore.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPCore.java index a7e866e..aff160f 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPCore.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPCore.java @@ -1,35 +1,64 @@ package net.sourceforge.phpeclipse; +import java.io.File; import java.util.ArrayList; +import java.util.Collection; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.List; +import java.util.Map; +import net.sourceforge.phpdt.core.ClasspathVariableInitializer; +import net.sourceforge.phpdt.core.ElementChangedEvent; +import net.sourceforge.phpdt.core.IBufferFactory; +import net.sourceforge.phpdt.core.IClasspathEntry; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IElementChangedListener; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModel; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IMember; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; +import net.sourceforge.phpdt.core.IRegion; +import net.sourceforge.phpdt.core.IWorkingCopy; +import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.internal.core.BatchOperation; -import net.sourceforge.phpeclipse.resourcesview.PHPFile; -import net.sourceforge.phpeclipse.resourcesview.PHPProject; +import net.sourceforge.phpdt.internal.core.BufferManager; +import net.sourceforge.phpdt.internal.core.ClasspathEntry; +import net.sourceforge.phpdt.internal.core.JavaModel; +import net.sourceforge.phpdt.internal.core.JavaModelManager; +import net.sourceforge.phpdt.internal.core.Region; +import net.sourceforge.phpdt.internal.corext.Assert; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Preferences; public class PHPCore { - public static HashSet OptionNames = new HashSet(20); +// public static HashSet OptionNames = new HashSet(20); /** * The plug-in identifier of the Java core support * (value "org.phpeclipse.phpdt.core"). */ - public static final String PLUGIN_ID = "net.sourceforge.phpeclipse.core"; //$NON-NLS-1$ - +// public static final String PLUGIN_ID = "net.sourceforge.phpeclipse.core"; //$NON-NLS-1$ + public static final String PLUGIN_ID = PHPeclipsePlugin.PLUGIN_ID; /** * Possible configurable option ID. * @see #getDefaultOptions @@ -160,6 +189,406 @@ public class PHPCore { public static final String CLEAN = "clean"; //$NON-NLS-1$ /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String COMPILER_TASK_TAGS = PLUGIN_ID + ".compiler.taskTags"; //$NON-NLS-1$ + + /** + * Name of the handle id attribute in a Java marker. + */ + protected static final String ATT_HANDLE_ID = + "net.sourceforge.phpdt.internal.core.JavaModelManager.handleId" ; //$NON-NLS-1$ + + // *************** Possible IDs for configurable options. ******************** + + /** + * Possible configurable option ID. + * @see #getDefaultOptions() + */ + public static final String COMPILER_LOCAL_VARIABLE_ATTR = PLUGIN_ID + ".compiler.debug.localVariable"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions() + */ + public static final String COMPILER_LINE_NUMBER_ATTR = PLUGIN_ID + ".compiler.debug.lineNumber"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + */ + public static final String COMPILER_SOURCE_FILE_ATTR = PLUGIN_ID + ".compiler.debug.sourceFile"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + */ + public static final String COMPILER_CODEGEN_UNUSED_LOCAL = PLUGIN_ID + ".compiler.codegen.unusedLocal"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + */ + public static final String COMPILER_CODEGEN_TARGET_PLATFORM = PLUGIN_ID + ".compiler.codegen.targetPlatform"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + */ + public static final String COMPILER_PB_UNREACHABLE_CODE = PLUGIN_ID + ".compiler.problem.unreachableCode"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + */ + public static final String COMPILER_PB_INVALID_IMPORT = PLUGIN_ID + ".compiler.problem.invalidImport"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + */ + public static final String COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD = PLUGIN_ID + ".compiler.problem.overridingPackageDefaultMethod"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + */ + public static final String COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME = PLUGIN_ID + ".compiler.problem.methodWithConstructorName"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + */ + public static final String COMPILER_PB_DEPRECATION = PLUGIN_ID + ".compiler.problem.deprecation"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE = PLUGIN_ID + ".compiler.problem.deprecationInDeprecatedCode"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + */ + public static final String COMPILER_PB_HIDDEN_CATCH_BLOCK = PLUGIN_ID + ".compiler.problem.hiddenCatchBlock"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + */ + public static final String COMPILER_PB_UNUSED_LOCAL = PLUGIN_ID + ".compiler.problem.unusedLocal"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + */ + public static final String COMPILER_PB_UNUSED_PARAMETER = PLUGIN_ID + ".compiler.problem.unusedParameter"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String COMPILER_PB_UNUSED_PARAMETER_WHEN_IMPLEMENTING_ABSTRACT = PLUGIN_ID + ".compiler.problem.unusedParameterWhenImplementingAbstract"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String COMPILER_PB_UNUSED_PARAMETER_WHEN_OVERRIDING_CONCRETE = PLUGIN_ID + ".compiler.problem.unusedParameterWhenOverridingConcrete"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.0 + */ + public static final String COMPILER_PB_UNUSED_IMPORT = PLUGIN_ID + ".compiler.problem.unusedImport"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + */ + public static final String COMPILER_PB_SYNTHETIC_ACCESS_EMULATION = PLUGIN_ID + ".compiler.problem.syntheticAccessEmulation"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.0 + */ + public static final String COMPILER_PB_NON_NLS_STRING_LITERAL = PLUGIN_ID + ".compiler.problem.nonExternalizedStringLiteral"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.0 + */ + public static final String COMPILER_PB_ASSERT_IDENTIFIER = PLUGIN_ID + ".compiler.problem.assertIdentifier"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String COMPILER_PB_STATIC_ACCESS_RECEIVER = PLUGIN_ID + ".compiler.problem.staticAccessReceiver"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String COMPILER_PB_NO_EFFECT_ASSIGNMENT = PLUGIN_ID + ".compiler.problem.noEffectAssignment"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String COMPILER_PB_INCOMPATIBLE_NON_INHERITED_INTERFACE_METHOD = PLUGIN_ID + ".compiler.problem.incompatibleNonInheritedInterfaceMethod"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String COMPILER_PB_UNUSED_PRIVATE_MEMBER = PLUGIN_ID + ".compiler.problem.unusedPrivateMember"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String COMPILER_PB_CHAR_ARRAY_IN_STRING_CONCATENATION = PLUGIN_ID + ".compiler.problem.noImplicitStringConversion"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.0 + */ + public static final String COMPILER_PB_MAX_PER_UNIT = PLUGIN_ID + ".compiler.maxProblemPerUnit"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.0 + */ + public static final String COMPILER_SOURCE = PLUGIN_ID + ".compiler.source"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.0 + */ + public static final String COMPILER_COMPLIANCE = PLUGIN_ID + ".compiler.compliance"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String COMPILER_TASK_PRIORITIES = PLUGIN_ID + ".compiler.taskPriorities"; //$NON-NLS-1$ + /** + * Possible configurable option value for COMPILER_TASK_PRIORITIES. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String COMPILER_TASK_PRIORITY_HIGH = "HIGH"; //$NON-NLS-1$ + /** + * Possible configurable option value for COMPILER_TASK_PRIORITIES. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String COMPILER_TASK_PRIORITY_LOW = "LOW"; //$NON-NLS-1$ + /** + * Possible configurable option value for COMPILER_TASK_PRIORITIES. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String COMPILER_TASK_PRIORITY_NORMAL = "NORMAL"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + */ + public static final String CORE_JAVA_BUILD_ORDER = PLUGIN_ID + ".computeJavaBuildOrder"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.0 + */ + public static final String CORE_JAVA_BUILD_RESOURCE_COPY_FILTER = PLUGIN_ID + ".builder.resourceCopyExclusionFilter"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String CORE_JAVA_BUILD_DUPLICATE_RESOURCE = PLUGIN_ID + ".builder.duplicateResourceTask"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER = PLUGIN_ID + ".builder.cleanOutputFolder"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String CORE_INCOMPLETE_CLASSPATH = PLUGIN_ID + ".incompleteClasspath"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String CORE_CIRCULAR_CLASSPATH = PLUGIN_ID + ".circularClasspath"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.0 + */ + public static final String CORE_JAVA_BUILD_INVALID_CLASSPATH = PLUGIN_ID + ".builder.invalidClasspath"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS = PLUGIN_ID + ".classpath.exclusionPatterns"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS = PLUGIN_ID + ".classpath.multipleOutputLocations"; //$NON-NLS-1$ + /** + * Default task tag + * @since 2.1 + */ + public static final String DEFAULT_TASK_TAG = "TODO"; //$NON-NLS-1$ + /** + * Default task priority + * @since 2.1 + */ + public static final String DEFAULT_TASK_PRIORITY = "NORMAL"; //$NON-NLS-1$ + /** + * Possible configurable option ID + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String FORMATTER_SPACE_CASTEXPRESSION = PLUGIN_ID + ".formatter.space.castexpression"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.0 + */ + public static final String CODEASSIST_VISIBILITY_CHECK = PLUGIN_ID + ".codeComplete.visibilityCheck"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.0 + */ + public static final String CODEASSIST_IMPLICIT_QUALIFICATION = PLUGIN_ID + ".codeComplete.forceImplicitQualification"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String CODEASSIST_FIELD_PREFIXES = PLUGIN_ID + ".codeComplete.fieldPrefixes"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String CODEASSIST_STATIC_FIELD_PREFIXES = PLUGIN_ID + ".codeComplete.staticFieldPrefixes"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String CODEASSIST_LOCAL_PREFIXES = PLUGIN_ID + ".codeComplete.localPrefixes"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String CODEASSIST_ARGUMENT_PREFIXES = PLUGIN_ID + ".codeComplete.argumentPrefixes"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String CODEASSIST_FIELD_SUFFIXES = PLUGIN_ID + ".codeComplete.fieldSuffixes"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String CODEASSIST_STATIC_FIELD_SUFFIXES = PLUGIN_ID + ".codeComplete.staticFieldSuffixes"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String CODEASSIST_LOCAL_SUFFIXES = PLUGIN_ID + ".codeComplete.localSuffixes"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions + * @since 2.1 + */ + public static final String CODEASSIST_ARGUMENT_SUFFIXES = PLUGIN_ID + ".codeComplete.argumentSuffixes"; //$NON-NLS-1$ + + // *************** Possible values for configurable options. ******************** + + /** + * Possible configurable option value. + * @see #getDefaultOptions + */ + public static final String GENERATE = "generate"; //$NON-NLS-1$ + /** + * Possible configurable option value. + * @see #getDefaultOptions + */ + public static final String DO_NOT_GENERATE = "do not generate"; //$NON-NLS-1$ + /** + * Possible configurable option value. + * @see #getDefaultOptions + */ + public static final String PRESERVE = "preserve"; //$NON-NLS-1$ + /** + * Possible configurable option value. + * @see #getDefaultOptions + */ + public static final String OPTIMIZE_OUT = "optimize out"; //$NON-NLS-1$ + /** + * Possible configurable option value. + * @see #getDefaultOptions + */ + public static final String VERSION_1_1 = "1.1"; //$NON-NLS-1$ + /** + * Possible configurable option value. + * @see #getDefaultOptions + */ + public static final String VERSION_1_2 = "1.2"; //$NON-NLS-1$ + /** + * Possible configurable option value. + * @see #getDefaultOptions + * @since 2.0 + */ + public static final String VERSION_1_3 = "1.3"; //$NON-NLS-1$ + /** + * Possible configurable option value. + * @see #getDefaultOptions + * @since 2.0 + */ + public static final String VERSION_1_4 = "1.4"; //$NON-NLS-1$ + /** + * Possible configurable option value. + * @see #getDefaultOptions + * @since 2.0 + */ + public static final String ABORT = "abort"; //$NON-NLS-1$ + /** + * Possible configurable option value. + * @see #getDefaultOptions + */ + public static final String ERROR = "error"; //$NON-NLS-1$ + /** + * Possible configurable option value. + * @see #getDefaultOptions + */ + public static final String WARNING = "warning"; //$NON-NLS-1$ + /** + * Possible configurable option value. + * @see #getDefaultOptions + */ + public static final String IGNORE = "ignore"; //$NON-NLS-1$ + /** + * Possible configurable option value. + * @see #getDefaultOptions + */ + public static final String COMPUTE = "compute"; //$NON-NLS-1$ + /** + * Possible configurable option value. + * @see #getDefaultOptions + * @since 2.0 + */ + + + /** * Returns a table of all known configurable options with their default values. * These options allow to configure the behaviour of the underlying components. * The client may safely use the result as a template that they can modify and @@ -347,7 +776,6 @@ public class PHPCore { * - option id: "org.phpeclipse.phpdt.core.compiler.taskTags" * - possible values: { "[,]*" } where is a String without any wild-card * - default: "" - * * COMPILER / Define the Automatic Task Priorities * In parallel with the Automatic Task Tags, this list defines the priorities (high, normal or low) * of the task markers issued by the compiler. @@ -540,35 +968,35 @@ public class PHPCore { * (key type: String; value type: String) * @see #setOptions */ - public static Hashtable getDefaultOptions() { - - Hashtable defaultOptions = new Hashtable(10); - - // see #initializeDefaultPluginPreferences() for changing default settings - Preferences preferences = getPlugin().getPluginPreferences(); - HashSet optionNames = OptionNames; - - // get preferences set to their default - String[] defaultPropertyNames = preferences.defaultPropertyNames(); - for (int i = 0; i < defaultPropertyNames.length; i++) { - String propertyName = defaultPropertyNames[i]; - if (optionNames.contains(propertyName)) { - defaultOptions.put(propertyName, preferences.getDefaultString(propertyName)); - } - } - // get preferences not set to their default - String[] propertyNames = preferences.propertyNames(); - for (int i = 0; i < propertyNames.length; i++) { - String propertyName = propertyNames[i]; - if (optionNames.contains(propertyName)) { - defaultOptions.put(propertyName, preferences.getDefaultString(propertyName)); - } - } - // get encoding through resource plugin - defaultOptions.put(CORE_ENCODING, ResourcesPlugin.getEncoding()); - - return defaultOptions; - } +// public static Hashtable getDefaultOptions() { +// +// Hashtable defaultOptions = new Hashtable(10); +// +// // see #initializeDefaultPluginPreferences() for changing default settings +// Preferences preferences = getPlugin().getPluginPreferences(); +// HashSet optionNames = OptionNames; +// +// // get preferences set to their default +// String[] defaultPropertyNames = preferences.defaultPropertyNames(); +// for (int i = 0; i < defaultPropertyNames.length; i++) { +// String propertyName = defaultPropertyNames[i]; +// if (optionNames.contains(propertyName)) { +// defaultOptions.put(propertyName, preferences.getDefaultString(propertyName)); +// } +// } +// // get preferences not set to their default +// String[] propertyNames = preferences.propertyNames(); +// for (int i = 0; i < propertyNames.length; i++) { +// String propertyName = propertyNames[i]; +// if (optionNames.contains(propertyName)) { +// defaultOptions.put(propertyName, preferences.getDefaultString(propertyName)); +// } +// } +// // get encoding through resource plugin +// defaultOptions.put(CORE_ENCODING, ResourcesPlugin.getEncoding()); +// +// return defaultOptions; +// } /** * Helper method for returning one option value only. Equivalent to (String)JavaCore.getOptions().get(optionName) * Note that it may answer null if this option does not exist. @@ -581,17 +1009,17 @@ public class PHPCore { * @see JavaCore#getDefaultOptions * @since 2.0 */ - public static String getOption(String optionName) { - - if (CORE_ENCODING.equals(optionName)) { - return ResourcesPlugin.getEncoding(); - } - if (OptionNames.contains(optionName)) { - Preferences preferences = getPlugin().getPluginPreferences(); - return preferences.getString(optionName).trim(); - } - return null; - } +// public static String getOption(String optionName) { +// +// if (CORE_ENCODING.equals(optionName)) { +// return ResourcesPlugin.getEncoding(); +// } +// if (OptionNames.contains(optionName)) { +// Preferences preferences = getPlugin().getPluginPreferences(); +// return preferences.getString(optionName).trim(); +// } +// return null; +// } /** * Returns the table of the current options. Initially, all options have their default values, @@ -604,37 +1032,37 @@ public class PHPCore { * (key type: String; value type: String) * @see JavaCore#getDefaultOptions */ - public static Hashtable getOptions() { - - Hashtable options = new Hashtable(10); - - // see #initializeDefaultPluginPreferences() for changing default settings - Plugin plugin = getPlugin(); - if (plugin != null) { - Preferences preferences = getPlugin().getPluginPreferences(); - HashSet optionNames = OptionNames; - - // get preferences set to their default - String[] defaultPropertyNames = preferences.defaultPropertyNames(); - for (int i = 0; i < defaultPropertyNames.length; i++) { - String propertyName = defaultPropertyNames[i]; - if (optionNames.contains(propertyName)) { - options.put(propertyName, preferences.getDefaultString(propertyName)); - } - } - // get preferences not set to their default - String[] propertyNames = preferences.propertyNames(); - for (int i = 0; i < propertyNames.length; i++) { - String propertyName = propertyNames[i]; - if (optionNames.contains(propertyName)) { - options.put(propertyName, preferences.getString(propertyName).trim()); - } - } - // get encoding through resource plugin - options.put(CORE_ENCODING, ResourcesPlugin.getEncoding()); - } - return options; - } +// public static Hashtable getOptions() { +// +// Hashtable options = new Hashtable(10); +// +// // see #initializeDefaultPluginPreferences() for changing default settings +// Plugin plugin = getPlugin(); +// if (plugin != null) { +// Preferences preferences = getPlugin().getPluginPreferences(); +// HashSet optionNames = OptionNames; +// +// // get preferences set to their default +// String[] defaultPropertyNames = preferences.defaultPropertyNames(); +// for (int i = 0; i < defaultPropertyNames.length; i++) { +// String propertyName = defaultPropertyNames[i]; +// if (optionNames.contains(propertyName)) { +// options.put(propertyName, preferences.getDefaultString(propertyName)); +// } +// } +// // get preferences not set to their default +// String[] propertyNames = preferences.propertyNames(); +// for (int i = 0; i < propertyNames.length; i++) { +// String propertyName = propertyNames[i]; +// if (optionNames.contains(propertyName)) { +// options.put(propertyName, preferences.getString(propertyName).trim()); +// } +// } +// // get encoding through resource plugin +// options.put(CORE_ENCODING, ResourcesPlugin.getEncoding()); +// } +// return options; +// } /** * Sets the current table of options. All and only the options explicitly included in the given table * are remembered; all previous option settings are forgotten, including ones not explicitly @@ -647,28 +1075,28 @@ public class PHPCore { * or null to reset all options to their default values * @see JavaCore#getDefaultOptions */ - public static void setOptions(Hashtable newOptions) { - - // see #initializeDefaultPluginPreferences() for changing default settings - Preferences preferences = getPlugin().getPluginPreferences(); - - if (newOptions == null) { - newOptions = getDefaultOptions(); - } - Enumeration keys = newOptions.keys(); - while (keys.hasMoreElements()) { - String key = (String) keys.nextElement(); - if (!OptionNames.contains(key)) - continue; // unrecognized option - if (key.equals(CORE_ENCODING)) - continue; // skipped, contributed by resource prefs - String value = (String) newOptions.get(key); - preferences.setValue(key, value); - } - - // persist options - getPlugin().savePluginPreferences(); - } +// public static void setOptions(Hashtable newOptions) { +// +// // see #initializeDefaultPluginPreferences() for changing default settings +// Preferences preferences = getPlugin().getPluginPreferences(); +// +// if (newOptions == null) { +// newOptions = getDefaultOptions(); +// } +// Enumeration keys = newOptions.keys(); +// while (keys.hasMoreElements()) { +// String key = (String) keys.nextElement(); +// if (!OptionNames.contains(key)) +// continue; // unrecognized option +// if (key.equals(CORE_ENCODING)) +// continue; // skipped, contributed by resource prefs +// String value = (String) newOptions.get(key); +// preferences.setValue(key, value); +// } +// +// // persist options +// getPlugin().savePluginPreferences(); +// } public static IProject[] getPHPProjects() { List phpProjectsList = new ArrayList(); IProject[] workspaceProjects = PHPeclipsePlugin.getWorkspace().getRoot().getProjects(); @@ -683,15 +1111,15 @@ public class PHPCore { return (IProject[]) phpProjectsList.toArray(phpProjects); } - public static PHPProject getPHPProject(String name) { - IProject aProject = PHPeclipsePlugin.getWorkspace().getRoot().getProject(name); - if (isPHPProject(aProject)) { - PHPProject thePHPProject = new PHPProject(); - thePHPProject.setProject(aProject); - return thePHPProject; - } - return null; - } +// public static PHPProject getPHPProject(String name) { +// IProject aProject = PHPeclipsePlugin.getWorkspace().getRoot().getProject(name); +// if (isPHPProject(aProject)) { +// PHPProject thePHPProject = new PHPProject(); +// thePHPProject.setProject(aProject); +// return thePHPProject; +// } +// return null; +// } public static boolean isPHPProject(IProject aProject) { try { @@ -702,36 +1130,37 @@ public class PHPCore { return false; } - public static PHPFile create(IFile aFile) { - if (PHPFile.EXTENSION.equalsIgnoreCase(aFile.getFileExtension())) - return new PHPFile(aFile); - if (PHPFile.EXTENSION1.equalsIgnoreCase(aFile.getFileExtension())) - return new PHPFile(aFile); - if (PHPFile.EXTENSION2.equalsIgnoreCase(aFile.getFileExtension())) - return new PHPFile(aFile); - if (PHPFile.EXTENSION3.equalsIgnoreCase(aFile.getFileExtension())) - return new PHPFile(aFile); - if (PHPFile.EXTENSION4.equalsIgnoreCase(aFile.getFileExtension())) - return new PHPFile(aFile); - if (PHPFile.EXTENSION5.equalsIgnoreCase(aFile.getFileExtension())) - return new PHPFile(aFile); - - return null; - } +// public static PHPFile create(IFile aFile) { +// if (PHPFile.EXTENSION.equalsIgnoreCase(aFile.getFileExtension())) +// return new PHPFile(aFile); +// if (PHPFile.EXTENSION1.equalsIgnoreCase(aFile.getFileExtension())) +// return new PHPFile(aFile); +// if (PHPFile.EXTENSION2.equalsIgnoreCase(aFile.getFileExtension())) +// return new PHPFile(aFile); +// if (PHPFile.EXTENSION3.equalsIgnoreCase(aFile.getFileExtension())) +// return new PHPFile(aFile); +// if (PHPFile.EXTENSION4.equalsIgnoreCase(aFile.getFileExtension())) +// return new PHPFile(aFile); +// if (PHPFile.EXTENSION5.equalsIgnoreCase(aFile.getFileExtension())) +// return new PHPFile(aFile); +// +// return null; +// } - public static PHPProject create(IProject aProject) { - try { - if (aProject.hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) { - PHPProject project = new PHPProject(); - project.setProject(aProject); - return project; - } - } catch (CoreException e) { - System.err.println("Exception occurred in PHPCore#create(IProject): " + e.toString()); - } - - return null; - } +// public static PHPProject create(IProject aProject) { +// +// try { +// if (aProject.hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) { +// PHPProject project = new PHPProject(); +// project.setProject(aProject); +// return project; +// } +// } catch (CoreException e) { +// System.err.println("Exception occurred in PHPCore#create(IProject): " + e.toString()); +// } +// +// return null; +// } public static void addPHPNature(IProject project, IProgressMonitor monitor) throws CoreException { if (!project.hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) { @@ -757,173 +1186,7 @@ public class PHPCore { /** * Initializes the default preferences settings for this plug-in. */ - protected static void initializeDefaultPluginPreferences() { - - Preferences preferences = PHPeclipsePlugin.getDefault().getPluginPreferences(); - HashSet optionNames = OptionNames; - - // // Compiler settings - // preferences.setDefault(COMPILER_LOCAL_VARIABLE_ATTR, GENERATE); - // optionNames.add(COMPILER_LOCAL_VARIABLE_ATTR); - // - // preferences.setDefault(COMPILER_LINE_NUMBER_ATTR, GENERATE); - // optionNames.add(COMPILER_LINE_NUMBER_ATTR); - // - // preferences.setDefault(COMPILER_SOURCE_FILE_ATTR, GENERATE); - // optionNames.add(COMPILER_SOURCE_FILE_ATTR); - // - // preferences.setDefault(COMPILER_CODEGEN_UNUSED_LOCAL, PRESERVE); - // optionNames.add(COMPILER_CODEGEN_UNUSED_LOCAL); - // - // preferences.setDefault(COMPILER_CODEGEN_TARGET_PLATFORM, VERSION_1_1); - // optionNames.add(COMPILER_CODEGEN_TARGET_PLATFORM); - // - // preferences.setDefault(COMPILER_PB_UNREACHABLE_CODE, ERROR); - // optionNames.add(COMPILER_PB_UNREACHABLE_CODE); - // - // preferences.setDefault(COMPILER_PB_INVALID_IMPORT, ERROR); - // optionNames.add(COMPILER_PB_INVALID_IMPORT); - // - // preferences.setDefault(COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD, WARNING); - // optionNames.add(COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD); - // - // preferences.setDefault(COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME, WARNING); - // optionNames.add(COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME); - // - // preferences.setDefault(COMPILER_PB_DEPRECATION, WARNING); - // optionNames.add(COMPILER_PB_DEPRECATION); - // - // preferences.setDefault(COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE, DISABLED); - // optionNames.add(COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE); - // - // preferences.setDefault(COMPILER_PB_HIDDEN_CATCH_BLOCK, WARNING); - // optionNames.add(COMPILER_PB_HIDDEN_CATCH_BLOCK); - // - // preferences.setDefault(COMPILER_PB_UNUSED_LOCAL, IGNORE); - // optionNames.add(COMPILER_PB_UNUSED_LOCAL); - // - // preferences.setDefault(COMPILER_PB_UNUSED_PARAMETER, IGNORE); - // optionNames.add(COMPILER_PB_UNUSED_PARAMETER); - // - // preferences.setDefault(COMPILER_PB_UNUSED_IMPORT, WARNING); - // optionNames.add(COMPILER_PB_UNUSED_IMPORT); - // - // preferences.setDefault(COMPILER_PB_SYNTHETIC_ACCESS_EMULATION, IGNORE); - // optionNames.add(COMPILER_PB_SYNTHETIC_ACCESS_EMULATION); - // - // preferences.setDefault(COMPILER_PB_NON_NLS_STRING_LITERAL, IGNORE); - // optionNames.add(COMPILER_PB_NON_NLS_STRING_LITERAL); - // - // preferences.setDefault(COMPILER_PB_ASSERT_IDENTIFIER, IGNORE); - // optionNames.add(COMPILER_PB_ASSERT_IDENTIFIER); - // - // preferences.setDefault(COMPILER_PB_STATIC_ACCESS_RECEIVER, WARNING); - // optionNames.add(COMPILER_PB_STATIC_ACCESS_RECEIVER); - // - // preferences.setDefault(COMPILER_PB_NO_EFFECT_ASSIGNMENT, WARNING); - // optionNames.add(COMPILER_PB_NO_EFFECT_ASSIGNMENT); - // - // preferences.setDefault(COMPILER_TASK_TAGS, ""); //$NON-NLS-1$ - // optionNames.add(COMPILER_TASK_TAGS); - // - // preferences.setDefault(COMPILER_TASK_PRIORITIES, ""); //$NON-NLS-1$ - // optionNames.add(COMPILER_TASK_PRIORITIES); - // - // preferences.setDefault(COMPILER_SOURCE, VERSION_1_3); - // optionNames.add(COMPILER_SOURCE); - // - // preferences.setDefault(COMPILER_COMPLIANCE, VERSION_1_3); - // optionNames.add(COMPILER_COMPLIANCE); - // - // preferences.setDefault(COMPILER_PB_MAX_PER_UNIT, "100"); //$NON-NLS-1$ - // optionNames.add(COMPILER_PB_MAX_PER_UNIT); - // - // // Builder settings - // preferences.setDefault(CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, ""); //$NON-NLS-1$ - // optionNames.add(CORE_JAVA_BUILD_RESOURCE_COPY_FILTER); - // - // preferences.setDefault(CORE_JAVA_BUILD_INVALID_CLASSPATH, ABORT); - // optionNames.add(CORE_JAVA_BUILD_INVALID_CLASSPATH); - // - // preferences.setDefault(CORE_JAVA_BUILD_DUPLICATE_RESOURCE, WARNING); - // optionNames.add(CORE_JAVA_BUILD_DUPLICATE_RESOURCE); - // - // preferences.setDefault(CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, CLEAN); - // optionNames.add(CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER); - // - // // JavaCore settings - // preferences.setDefault(CORE_JAVA_BUILD_ORDER, IGNORE); - // optionNames.add(CORE_JAVA_BUILD_ORDER); - // - // preferences.setDefault(CORE_CIRCULAR_CLASSPATH, ERROR); - // optionNames.add(CORE_CIRCULAR_CLASSPATH); - // - // preferences.setDefault(CORE_INCOMPLETE_CLASSPATH, ERROR); - // optionNames.add(CORE_INCOMPLETE_CLASSPATH); - - // encoding setting comes from resource plug-in - optionNames.add(CORE_ENCODING); - - // Formatter settings - preferences.setDefault(FORMATTER_NEWLINE_OPENING_BRACE, DO_NOT_INSERT); - optionNames.add(FORMATTER_NEWLINE_OPENING_BRACE); - - preferences.setDefault(FORMATTER_NEWLINE_CONTROL, DO_NOT_INSERT); - optionNames.add(FORMATTER_NEWLINE_CONTROL); - - preferences.setDefault(FORMATTER_CLEAR_BLANK_LINES, PRESERVE_ONE); - optionNames.add(FORMATTER_CLEAR_BLANK_LINES); - - preferences.setDefault(FORMATTER_NEWLINE_ELSE_IF, DO_NOT_INSERT); - optionNames.add(FORMATTER_NEWLINE_ELSE_IF); - - preferences.setDefault(FORMATTER_NEWLINE_EMPTY_BLOCK, INSERT); - optionNames.add(FORMATTER_NEWLINE_EMPTY_BLOCK); - - preferences.setDefault(FORMATTER_LINE_SPLIT, "80"); //$NON-NLS-1$ - optionNames.add(FORMATTER_LINE_SPLIT); - - preferences.setDefault(FORMATTER_COMPACT_ASSIGNMENT, NORMAL); - optionNames.add(FORMATTER_COMPACT_ASSIGNMENT); - - preferences.setDefault(FORMATTER_TAB_CHAR, TAB); - optionNames.add(FORMATTER_TAB_CHAR); - - preferences.setDefault(FORMATTER_TAB_SIZE, "4"); //$NON-NLS-1$ - optionNames.add(FORMATTER_TAB_SIZE); - - // CodeAssist settings - // preferences.setDefault(CODEASSIST_VISIBILITY_CHECK, DISABLED); //$NON-NLS-1$ - // optionNames.add(CODEASSIST_VISIBILITY_CHECK); - // - // preferences.setDefault(CODEASSIST_IMPLICIT_QUALIFICATION, DISABLED); //$NON-NLS-1$ - // optionNames.add(CODEASSIST_IMPLICIT_QUALIFICATION); - // - // preferences.setDefault(CODEASSIST_FIELD_PREFIXES, ""); //$NON-NLS-1$ - // optionNames.add(CODEASSIST_FIELD_PREFIXES); - // - // preferences.setDefault(CODEASSIST_STATIC_FIELD_PREFIXES, ""); //$NON-NLS-1$ - // optionNames.add(CODEASSIST_STATIC_FIELD_PREFIXES); - // - // preferences.setDefault(CODEASSIST_LOCAL_PREFIXES, ""); //$NON-NLS-1$ - // optionNames.add(CODEASSIST_LOCAL_PREFIXES); - // - // preferences.setDefault(CODEASSIST_ARGUMENT_PREFIXES, ""); //$NON-NLS-1$ - // optionNames.add(CODEASSIST_ARGUMENT_PREFIXES); - // - // preferences.setDefault(CODEASSIST_FIELD_SUFFIXES, ""); //$NON-NLS-1$ - // optionNames.add(CODEASSIST_FIELD_SUFFIXES); - // - // preferences.setDefault(CODEASSIST_STATIC_FIELD_SUFFIXES, ""); //$NON-NLS-1$ - // optionNames.add(CODEASSIST_STATIC_FIELD_SUFFIXES); - // - // preferences.setDefault(CODEASSIST_LOCAL_SUFFIXES, ""); //$NON-NLS-1$ - // optionNames.add(CODEASSIST_LOCAL_SUFFIXES); - // - // preferences.setDefault(CODEASSIST_ARGUMENT_SUFFIXES, ""); //$NON-NLS-1$ - // optionNames.add(CODEASSIST_ARGUMENT_SUFFIXES); - - } + /** * Runs the given action as an atomic Java model operation. *

        @@ -961,4 +1224,2557 @@ public class PHPCore { workspace.run(new BatchOperation(action), monitor); } } + +/** + * Adds the given listener for changes to Java elements. + * Has no effect if an identical listener is already registered. + * + * This listener will only be notified during the POST_CHANGE resource change notification + * and any reconcile operation (POST_RECONCILE). + * For finer control of the notification, use addElementChangedListener(IElementChangedListener,int), + * which allows to specify a different eventMask. + * + * @see ElementChangedEvent + * @param listener the listener + */ +public static void addElementChangedListener(IElementChangedListener listener) { + addElementChangedListener(listener, ElementChangedEvent.POST_CHANGE | ElementChangedEvent.POST_RECONCILE); +} + +/** + * Adds the given listener for changes to Java elements. + * Has no effect if an identical listener is already registered. + * After completion of this method, the given listener will be registered for exactly + * the specified events. If they were previously registered for other events, they + * will be deregistered. + *

        + * Once registered, a listener starts receiving notification of changes to + * java elements in the model. The listener continues to receive + * notifications until it is replaced or removed. + *

        + *

        + * Listeners can listen for several types of event as defined in ElementChangeEvent. + * Clients are free to register for any number of event types however if they register + * for more than one, it is their responsibility to ensure they correctly handle the + * case where the same java element change shows up in multiple notifications. + * Clients are guaranteed to receive only the events for which they are registered. + *

        + * + * @param listener the listener + * @param eventMask the bit-wise OR of all event types of interest to the listener + * @see IElementChangedListener + * @see ElementChangedEvent + * @see #removeElementChangedListener(IElementChangedListener) + * @since 2.0 + */ +public static void addElementChangedListener(IElementChangedListener listener, int eventMask) { + JavaModelManager.getJavaModelManager().addElementChangedListener(listener, eventMask); +} + +/** + * Configures the given marker attribute map for the given Java element. + * Used for markers, which denote a Java element rather than a resource. + * + * @param attributes the mutable marker attribute map (key type: String, + * value type: String) + * @param element the Java element for which the marker needs to be configured + */ +public static void addJavaElementMarkerAttributes( + Map attributes, + IJavaElement element) { +// if (element instanceof IMember) +// element = ((IMember) element).getClassFile(); + if (attributes != null && element != null) + attributes.put(ATT_HANDLE_ID, element.getHandleIdentifier()); +} + +/** + * Configures the given marker for the given Java element. + * Used for markers, which denote a Java element rather than a resource. + * + * @param marker the marker to be configured + * @param element the Java element for which the marker needs to be configured + * @exception CoreException if the IMarker.setAttribute on the marker fails + */ +public void configureJavaElementMarker(IMarker marker, IJavaElement element) + throws CoreException { +// if (element instanceof IMember) +// element = ((IMember) element).getClassFile(); + if (marker != null && element != null) + marker.setAttribute(ATT_HANDLE_ID, element.getHandleIdentifier()); +} + +/** + * Returns the Java model element corresponding to the given handle identifier + * generated by IJavaElement.getHandleIdentifier(), or + * null if unable to create the associated element. + */ +public static IJavaElement create(String handleIdentifier) { + if (handleIdentifier == null) { + return null; + } + try { + return JavaModelManager.getJavaModelManager().getHandleFromMemento(handleIdentifier); + } catch (JavaModelException e) { + return null; + } +} +/** + * Returns the Java element corresponding to the given file, or + * null if unable to associate the given file + * with a Java element. + * + *

        The file must be one of:

          + *
        • a .java file - the element returned is the corresponding ICompilationUnit
        • + *
        • a .class file - the element returned is the corresponding IClassFile
        • + *
        • a .jar file - the element returned is the corresponding IPackageFragmentRoot
        • + *
        + *

        + * Creating a Java element has the side effect of creating and opening all of the + * element's parents if they are not yet open. + * + * @param the given file + * @return the Java element corresponding to the given file, or + * null if unable to associate the given file + * with a Java element + */ +public static IJavaElement create(IFile file) { + return JavaModelManager.create(file, null); +} +/** + * Returns the package fragment or package fragment root corresponding to the given folder, or + * null if unable to associate the given folder with a Java element. + *

        + * Note that a package fragment root is returned rather than a default package. + *

        + * Creating a Java element has the side effect of creating and opening all of the + * element's parents if they are not yet open. + * + * @param the given folder + * @return the package fragment or package fragment root corresponding to the given folder, or + * null if unable to associate the given folder with a Java element + */ +public static IJavaElement create(IFolder folder) { + return JavaModelManager.create(folder, null); +} +/** + * Returns the Java project corresponding to the given project. + *

        + * Creating a Java Project has the side effect of creating and opening all of the + * project's parents if they are not yet open. + *

        + * Note that no check is done at this time on the existence or the java nature of this project. + * + * @param project the given project + * @return the Java project corresponding to the given project, null if the given project is null + */ +public static IJavaProject create(IProject project) { + if (project == null) { + return null; + } + JavaModel javaModel = JavaModelManager.getJavaModelManager().getJavaModel(); + return javaModel.getJavaProject(project); +} +/** + * Returns the Java element corresponding to the given resource, or + * null if unable to associate the given resource + * with a Java element. + *

        + * The resource must be one of:

          + *
        • a project - the element returned is the corresponding IJavaProject
        • + *
        • a .java file - the element returned is the corresponding ICompilationUnit
        • + *
        • a .class file - the element returned is the corresponding IClassFile
        • + *
        • a .jar file - the element returned is the corresponding IPackageFragmentRoot
        • + *
        • a folder - the element returned is the corresponding IPackageFragmentRoot + * or IPackageFragment
        • + *
        • the workspace root resource - the element returned is the IJavaModel
        • + *
        + *

        + * Creating a Java element has the side effect of creating and opening all of the + * element's parents if they are not yet open. + * + * @param resource the given resource + * @return the Java element corresponding to the given resource, or + * null if unable to associate the given resource + * with a Java element + */ +public static IJavaElement create(IResource resource) { + return JavaModelManager.create(resource, null); +} +/** + * Returns the Java model. + * + * @param root the given root + * @return the Java model, or null if the root is null + */ +public static IJavaModel create(IWorkspaceRoot root) { + if (root == null) { + return null; + } + return JavaModelManager.getJavaModelManager().getJavaModel(); +} +/** + * Creates and returns a class file element for + * the given .class file. Returns null if unable + * to recognize the class file. + * + * @param file the given .class file + * @return a class file element for the given .class file, or null if unable + * to recognize the class file + */ +//public static IClassFile createClassFileFrom(IFile file) { +// return JavaModelManager.createClassFileFrom(file, null); +//} +/** + * Creates and returns a compilation unit element for + * the given .java file. Returns null if unable + * to recognize the compilation unit. + * + * @param file the given .java file + * @return a compilation unit element for the given .java file, or null if unable + * to recognize the compilation unit + */ +public static ICompilationUnit createCompilationUnitFrom(IFile file) { + return JavaModelManager.createCompilationUnitFrom(file, null); +} +/** + * Creates and returns a handle for the given JAR file. + * The Java model associated with the JAR's project may be + * created as a side effect. + * + * @param file the given JAR file + * @return a handle for the given JAR file, or null if unable to create a JAR package fragment root. + * (for example, if the JAR file represents a non-Java resource) + */ +//public static IPackageFragmentRoot createJarPackageFragmentRootFrom(IFile file) { +// return JavaModelManager.createJarPackageFragmentRootFrom(file, null); +//} + +/** + * Answers the project specific value for a given classpath container. + * In case this container path could not be resolved, then will answer null. + * Both the container path and the project context are supposed to be non-null. + *

        + * The containerPath is a formed by a first ID segment followed with extra segments, which can be + * used as additional hints for resolution. If no container was ever recorded for this container path + * onto this project (using setClasspathContainer, then a + * ClasspathContainerInitializer will be activated if any was registered for this container + * ID onto the extension point "org.eclipse.jdt.core.classpathContainerInitializer". + *

        + * There is no assumption that the returned container must answer the exact same containerPath + * when requested IClasspathContainer#getPath. + * Indeed, the containerPath is just an indication for resolving it to an actual container object. + *

        + * Classpath container values are persisted locally to the workspace, but + * are not preserved from a session to another. It is thus highly recommended to register a + * ClasspathContainerInitializer for each referenced container + * (through the extension point "org.eclipse.jdt.core.ClasspathContainerInitializer"). + *

        + * @param containerPath the name of the container, which needs to be resolved + * @param project a specific project in which the container is being resolved + * @return the corresponding classpath container or null if unable to find one. + * + * @exception JavaModelException if an exception occurred while resolving the container, or if the resolved container + * contains illegal entries (contains CPE_CONTAINER entries or null entries). + * + * @see ClasspathContainerInitializer + * @see IClasspathContainer + * @see #setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], IProgressMonitor) + * @since 2.0 + */ +//public static IClasspathContainer getClasspathContainer(final IPath containerPath, final IJavaProject project) throws JavaModelException { +// +// IClasspathContainer container = JavaModelManager.containerGet(project, containerPath); +// if (container == JavaModelManager.ContainerInitializationInProgress) return null; // break cycle +// +// if (container == null){ +// final ClasspathContainerInitializer initializer = JavaCore.getClasspathContainerInitializer(containerPath.segment(0)); +// if (initializer != null){ +// if (JavaModelManager.CP_RESOLVE_VERBOSE){ +// System.out.println("CPContainer INIT - triggering initialization of: ["+project.getElementName()+"] " + containerPath + " using initializer: "+ initializer); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ +// new Exception("FAKE exception for dumping current CPContainer (["+project.getElementName()+"] "+ containerPath+ ")INIT invocation stack trace").printStackTrace(); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ +// } +// JavaModelManager.containerPut(project, containerPath, JavaModelManager.ContainerInitializationInProgress); // avoid initialization cycles +// boolean ok = false; +// try { +// // wrap initializer call with Safe runnable in case initializer would be causing some grief +// Platform.run(new ISafeRunnable() { +// public void handleException(Throwable exception) { +// Util.log(exception, "Exception occurred in classpath container initializer: "+initializer); //$NON-NLS-1$ +// } +// public void run() throws Exception { +// initializer.initialize(containerPath, project); +// } +// }); +// +// // retrieve value (if initialization was successful) +// container = JavaModelManager.containerGet(project, containerPath); +// if (container == JavaModelManager.ContainerInitializationInProgress) return null; // break cycle +// ok = true; +// } finally { +// if (!ok) JavaModelManager.containerPut(project, containerPath, null); // flush cache +// } +// if (JavaModelManager.CP_RESOLVE_VERBOSE){ +// System.out.print("CPContainer INIT - after resolution: ["+project.getElementName()+"] " + containerPath + " --> "); //$NON-NLS-2$//$NON-NLS-1$//$NON-NLS-3$ +// if (container != null){ +// System.out.print("container: "+container.getDescription()+" {"); //$NON-NLS-2$//$NON-NLS-1$ +// IClasspathEntry[] entries = container.getClasspathEntries(); +// if (entries != null){ +// for (int i = 0; i < entries.length; i++){ +// if (i > 0) System.out.println(", ");//$NON-NLS-1$ +// System.out.println(entries[i]); +// } +// } +// System.out.println("}");//$NON-NLS-1$ +// } else { +// System.out.println("{unbound}");//$NON-NLS-1$ +// } +// } +// } else { +// if (JavaModelManager.CP_RESOLVE_VERBOSE){ +// System.out.println("CPContainer INIT - no initializer found for: "+project.getElementName()+"] " + containerPath); //$NON-NLS-1$ //$NON-NLS-2$ +// } +// } +// } +// return container; +//} + +/** + * Helper method finding the classpath container initializer registered for a given classpath container ID + * or null if none was found while iterating over the contributions to extension point to + * the extension point "org.eclipse.jdt.core.classpathContainerInitializer". + *

        + * A containerID is the first segment of any container path, used to identify the registered container initializer. + *

        + * @param String - a containerID identifying a registered initializer + * @return ClasspathContainerInitializer - the registered classpath container initializer or null if + * none was found. + * @since 2.1 + */ +//public static ClasspathContainerInitializer getClasspathContainerInitializer(String containerID){ +// +// Plugin jdtCorePlugin = JavaCore.getPlugin(); +// if (jdtCorePlugin == null) return null; +// +// IExtensionPoint extension = jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.CPCONTAINER_INITIALIZER_EXTPOINT_ID); +// if (extension != null) { +// IExtension[] extensions = extension.getExtensions(); +// for(int i = 0; i < extensions.length; i++){ +// IConfigurationElement [] configElements = extensions[i].getConfigurationElements(); +// for(int j = 0; j < configElements.length; j++){ +// String initializerID = configElements[j].getAttribute("id"); //$NON-NLS-1$ +// if (initializerID != null && initializerID.equals(containerID)){ +// if (JavaModelManager.CP_RESOLVE_VERBOSE) { +// System.out.println("CPContainer INIT - found initializer: "+containerID +" --> " + configElements[j].getAttribute("class"));//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$ +// } +// try { +// Object execExt = configElements[j].createExecutableExtension("class"); //$NON-NLS-1$ +// if (execExt instanceof ClasspathContainerInitializer){ +// return (ClasspathContainerInitializer)execExt; +// } +// } catch(CoreException e) { +// } +// } +// } +// } +// } +// return null; +//} + +/** + * Returns the path held in the given classpath variable. + * Returns null if unable to bind. + *

        + * Classpath variable values are persisted locally to the workspace, and + * are preserved from session to session. + *

        + * Note that classpath variables can be contributed registered initializers for, + * using the extension point "org.eclipse.jdt.core.classpathVariableInitializer". + * If an initializer is registered for a variable, its persisted value will be ignored: + * its initializer will thus get the opportunity to rebind the variable differently on + * each session. + * + * @param variableName the name of the classpath variable + * @return the path, or null if none + * @see #setClasspathVariable + */ +public static IPath getClasspathVariable(final String variableName) { + + IPath variablePath = JavaModelManager.variableGet(variableName); + if (variablePath == JavaModelManager.VariableInitializationInProgress) return null; // break cycle + + if (variablePath != null) { + return variablePath; + } + + // even if persisted value exists, initializer is given priority, only if no initializer is found the persisted value is reused +// final ClasspathVariableInitializer initializer = PHPCore.getClasspathVariableInitializer(variableName); +// if (initializer != null){ +// if (JavaModelManager.CP_RESOLVE_VERBOSE){ +// System.out.println("CPVariable INIT - triggering initialization of: " + variableName+ " using initializer: "+ initializer); //$NON-NLS-1$ //$NON-NLS-2$ +// new Exception("FAKE exception for dumping current CPVariable ("+variableName+ ")INIT invocation stack trace").printStackTrace(); //$NON-NLS-1$//$NON-NLS-2$ +// } +// JavaModelManager.variablePut(variableName, JavaModelManager.VariableInitializationInProgress); // avoid initialization cycles +// boolean ok = false; +// try { +// // wrap initializer call with Safe runnable in case initializer would be causing some grief +// Platform.run(new ISafeRunnable() { +// public void handleException(Throwable exception) { +// Util.log(exception, "Exception occurred in classpath variable initializer: "+initializer+" while initializing variable: "+variableName); //$NON-NLS-1$ //$NON-NLS-2$ +// } +// public void run() throws Exception { +// initializer.initialize(variableName); +// } +// }); +// variablePath = (IPath) JavaModelManager.variableGet(variableName); // initializer should have performed side-effect +// if (variablePath == JavaModelManager.VariableInitializationInProgress) return null; // break cycle (initializer did not init or reentering call) +// if (JavaModelManager.CP_RESOLVE_VERBOSE){ +// System.out.println("CPVariable INIT - after initialization: " + variableName + " --> " + variablePath); //$NON-NLS-2$//$NON-NLS-1$ +// } +// ok = true; +// } finally { +// if (!ok) JavaModelManager.variablePut(variableName, null); // flush cache +// } +// } else { +// if (JavaModelManager.CP_RESOLVE_VERBOSE){ +// System.out.println("CPVariable INIT - no initializer found for: " + variableName); //$NON-NLS-1$ +// } +// } + return variablePath; +} + +/** + * Helper method finding the classpath variable initializer registered for a given classpath variable name + * or null if none was found while iterating over the contributions to extension point to + * the extension point "org.eclipse.jdt.core.classpathVariableInitializer". + *

        + * @param the given variable + * @return ClasspathVariableInitializer - the registered classpath variable initializer or null if + * none was found. + * @since 2.1 + */ +public static ClasspathVariableInitializer getClasspathVariableInitializer(String variable){ + + Plugin jdtCorePlugin = PHPCore.getPlugin(); + if (jdtCorePlugin == null) return null; + +// IExtensionPoint extension = jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.CPVARIABLE_INITIALIZER_EXTPOINT_ID); +// if (extension != null) { +// IExtension[] extensions = extension.getExtensions(); +// for(int i = 0; i < extensions.length; i++){ +// IConfigurationElement [] configElements = extensions[i].getConfigurationElements(); +// for(int j = 0; j < configElements.length; j++){ +// try { +// String varAttribute = configElements[j].getAttribute("variable"); //$NON-NLS-1$ +// if (variable.equals(varAttribute)) { +// if (JavaModelManager.CP_RESOLVE_VERBOSE) { +// System.out.println("CPVariable INIT - found initializer: "+variable+" --> " + configElements[j].getAttribute("class"));//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$ +// } +// Object execExt = configElements[j].createExecutableExtension("class"); //$NON-NLS-1$ +// if (execExt instanceof ClasspathVariableInitializer){ +// return (ClasspathVariableInitializer)execExt; +// } +// } +// } catch(CoreException e){ +// } +// } +// } +// } + return null; +} + +/** + * Returns the names of all known classpath variables. + *

        + * Classpath variable values are persisted locally to the workspace, and + * are preserved from session to session. + *

        + * + * @return the list of classpath variable names + * @see #setClasspathVariable + */ +//public static String[] getClasspathVariableNames() { +// return JavaModelManager.variableNames(); +//} + +/** + * Returns a table of all known configurable options with their default values. + * These options allow to configure the behaviour of the underlying components. + * The client may safely use the result as a template that they can modify and + * then pass to setOptions. + * + * Helper constants have been defined on JavaCore for each of the option ID and + * their possible constant values. + * + * Note: more options might be added in further releases. + *

        + * RECOGNIZED OPTIONS:
        + * COMPILER / Generating Local Variable Debug Attribute
        + *    When generated, this attribute will enable local variable names 
        + *    to be displayed in debugger, only in place where variables are 
        + *    definitely assigned (.class file is then bigger)
        + *     - option id:         "org.eclipse.jdt.core.compiler.debug.localVariable"
        + *     - possible values:   { "generate", "do not generate" }
        + *     - default:           "generate"
        + *
        + * COMPILER / Generating Line Number Debug Attribute 
        + *    When generated, this attribute will enable source code highlighting in debugger 
        + *    (.class file is then bigger).
        + *     - option id:         "org.eclipse.jdt.core.compiler.debug.lineNumber"
        + *     - possible values:   { "generate", "do not generate" }
        + *     - default:           "generate"
        + *    
        + * COMPILER / Generating Source Debug Attribute 
        + *    When generated, this attribute will enable the debugger to present the 
        + *    corresponding source code.
        + *     - option id:         "org.eclipse.jdt.core.compiler.debug.sourceFile"
        + *     - possible values:   { "generate", "do not generate" }
        + *     - default:           "generate"
        + *    
        + * COMPILER / Preserving Unused Local Variables
        + *    Unless requested to preserve unused local variables (that is, never read), the 
        + *    compiler will optimize them out, potentially altering debugging
        + *     - option id:         "org.eclipse.jdt.core.compiler.codegen.unusedLocal"
        + *     - possible values:   { "preserve", "optimize out" }
        + *     - default:           "preserve"
        + * 
        + * COMPILER / Defining Target Java Platform
        + *    For binary compatibility reason, .class files can be tagged to with certain VM versions and later.
        + *    Note that "1.4" target require to toggle compliance mode to "1.4" too.
        + *     - option id:         "org.eclipse.jdt.core.compiler.codegen.targetPlatform"
        + *     - possible values:   { "1.1", "1.2", "1.3", "1.4" }
        + *     - default:           "1.1"
        + *
        + * COMPILER / Reporting Unreachable Code
        + *    Unreachable code can optionally be reported as an error, warning or simply 
        + *    ignored. The bytecode generation will always optimized it out.
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.unreachableCode"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "error"
        + *
        + * COMPILER / Reporting Invalid Import
        + *    An import statement that cannot be resolved might optionally be reported 
        + *    as an error, as a warning or ignored.
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.invalidImport"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "error"
        + *
        + * COMPILER / Reporting Attempt to Override Package-Default Method
        + *    A package default method is not visible in a different package, and thus 
        + *    cannot be overridden. When enabling this option, the compiler will signal 
        + *    such scenarii either as an error or a warning.
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "warning"
        + *
        + * COMPILER / Reporting Method With Constructor Name
        + *    Naming a method with a constructor name is generally considered poor 
        + *    style programming. When enabling this option, the compiler will signal such 
        + *    scenarii either as an error or a warning.
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.methodWithConstructorName"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "warning"
        + *
        + * COMPILER / Reporting Deprecation
        + *    When enabled, the compiler will signal use of deprecated API either as an 
        + *    error or a warning.
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.deprecation"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "warning"
        + *
        + * COMPILER / Reporting Deprecation Inside Deprecated Code
        + *    When enabled, the compiler will signal use of deprecated API inside deprecated code.
        + *    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.deprecation".
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode"
        + *     - possible values:   { "enabled", "disabled" }
        + *     - default:           "disabled"
        + *
        + * COMPILER / Reporting Hidden Catch Block
        + *    Locally to a try statement, some catch blocks may hide others . For example,
        + *      try {  throw new java.io.CharConversionException();
        + *      } catch (java.io.CharConversionException e) {
        + *      } catch (java.io.IOException e) {}. 
        + *    When enabling this option, the compiler will issue an error or a warning for hidden 
        + *    catch blocks corresponding to checked exceptions
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "warning"
        + *
        + * COMPILER / Reporting Unused Local
        + *    When enabled, the compiler will issue an error or a warning for unused local 
        + *    variables (that is, variables never read from)
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedLocal"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "ignore"
        + *
        + * COMPILER / Reporting Unused Parameter
        + *    When enabled, the compiler will issue an error or a warning for unused method 
        + *    parameters (that is, parameters never read from)
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedParameter"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "ignore"
        + *
        + * COMPILER / Reporting Unused Parameter if Implementing Abstract Method
        + *    When enabled, the compiler will signal unused parameters in abstract method implementations.
        + *    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.unusedParameter".
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract"
        + *     - possible values:   { "enabled", "disabled" }
        + *     - default:           "disabled"
        + *
        + * COMPILER / Reporting Unused Parameter if Overriding Concrete Method
        + *    When enabled, the compiler will signal unused parameters in methods overriding concrete ones.
        + *    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.unusedParameter".
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete"
        + *     - possible values:   { "enabled", "disabled" }
        + *     - default:           "disabled"
        + *
        + * COMPILER / Reporting Unused Import
        + *    When enabled, the compiler will issue an error or a warning for unused import 
        + *    reference 
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedImport"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "warning"
        + *
        + * COMPILER / Reporting Unused Private Members
        + *    When enabled, the compiler will issue an error or a warning whenever a private 
        + *    method or field is declared but never used within the same unit.
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedPrivateMember"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "ignore"
        + *
        + * COMPILER / Reporting Synthetic Access Emulation
        + *    When enabled, the compiler will issue an error or a warning whenever it emulates 
        + *    access to a non-accessible member of an enclosing type. Such access can have
        + *    performance implications.
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "ignore"
        + *
        + * COMPILER / Reporting Non-Externalized String Literal
        + *    When enabled, the compiler will issue an error or a warning for non externalized 
        + *    String literal (that is, not tagged with //$NON-NLS-$). 
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "ignore"
        + * 
        + * COMPILER / Reporting Usage of 'assert' Identifier
        + *    When enabled, the compiler will issue an error or a warning whenever 'assert' is 
        + *    used as an identifier (reserved keyword in 1.4)
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.assertIdentifier"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "ignore"
        + * 
        + * COMPILER / Reporting Non-Static Reference to a Static Member
        + *    When enabled, the compiler will issue an error or a warning whenever a static field
        + *    or method is accessed with an expression receiver. A reference to a static member should
        + *    be qualified with a type name.
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.staticAccessReceiver"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "warning"
        + * 
        + * COMPILER / Reporting Assignment with no Effect
        + *    When enabled, the compiler will issue an error or a warning whenever an assignment
        + *    has no effect (e.g 'x = x').
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.noEffectAssignment"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "warning"
        + * 
        + * COMPILER / Reporting Interface Method not Compatible with non-Inherited Methods
        + *    When enabled, the compiler will issue an error or a warning whenever an interface
        + *    defines a method incompatible with a non-inherited Object method. Until this conflict
        + *    is resolved, such an interface cannot be implemented, For example, 
        + *      interface I { 
        + *         int clone();
        + *      } 
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "warning"
        + * 
        + * COMPILER / Reporting Usage of char[] Expressions in String Concatenations
        + *    When enabled, the compiler will issue an error or a warning whenever a char[] expression
        + *    is used in String concatenations (for example, "hello" + new char[]{'w','o','r','l','d'}).
        + *     - option id:         "org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion"
        + *     - possible values:   { "error", "warning", "ignore" }
        + *     - default:           "warning"
        + *
        + * COMPILER / Setting Source Compatibility Mode
        + *    Specify whether source is 1.3 or 1.4 compatible. From 1.4 on, 'assert' is a keyword
        + *    reserved for assertion support. Also note, than when toggling to 1.4 mode, the target VM
        + *   level should be set to "1.4" and the compliance mode should be "1.4".
        + *     - option id:         "org.eclipse.jdt.core.compiler.source"
        + *     - possible values:   { "1.3", "1.4" }
        + *     - default:           "1.3"
        + * 
        + * COMPILER / Setting Compliance Level
        + *    Select the compliance level for the compiler. In "1.3" mode, source and target settings
        + *    should not go beyond "1.3" level.
        + *     - option id:         "org.eclipse.jdt.core.compiler.compliance"
        + *     - possible values:   { "1.3", "1.4" }
        + *     - default:           "1.3"
        + * 
        + * COMPILER / Maximum number of problems reported per compilation unit
        + *    Specify the maximum number of problems reported on each compilation unit.
        + *     - option id:         "org.eclipse.jdt.core.compiler.maxProblemPerUnit"
        + *     - possible values:	"" where  is zero or a positive integer (if zero then all problems are reported).
        + *     - default:           "100"
        + * 
        + * COMPILER / Define the Automatic Task Tags
        + *    When the tag list is not empty, the compiler will issue a task marker whenever it encounters
        + *    one of the corresponding tag inside any comment in Java source code.
        + *    Generated task messages will include the tag, and range until the next line separator or comment ending.
        + *    Note that tasks messages are trimmed.
        + *     - option id:         "org.eclipse.jdt.core.compiler.taskTags"
        + *     - possible values:   { "[,]*" } where  is a String without any wild-card or leading/trailing spaces 
        + *     - default:           ""
        + * 
        + * COMPILER / Define the Automatic Task Priorities
        + *    In parallel with the Automatic Task Tags, this list defines the priorities (high, normal or low)
        + *    of the task markers issued by the compiler.
        + *    If the default is specified, the priority of each task marker is "NORMAL".
        + *     - option id:         "org.eclipse.jdt.core.compiler.taskPriorities"
        + *     - possible values:   { "[,]*" } where  is one of "HIGH", "NORMAL" or "LOW"
        + *     - default:           ""
        + *
        + * BUILDER / Specifying Filters for Resource Copying Control
        + *    Allow to specify some filters to control the resource copy process.
        + *     - option id:         "org.eclipse.jdt.core.builder.resourceCopyExclusionFilter"
        + *     - possible values:   { "[,]* } where  is a file name pattern (* and ? wild-cards allowed)
        + *       or the name of a folder which ends with '/'
        + *     - default:           ""
        + * 
        + * BUILDER / Abort if Invalid Classpath
        + *    Allow to toggle the builder to abort if the classpath is invalid
        + *     - option id:         "org.eclipse.jdt.core.builder.invalidClasspath"
        + *     - possible values:   { "abort", "ignore" }
        + *     - default:           "abort"
        + * 
        + * BUILDER / Cleaning Output Folder(s)
        + *    Indicate whether the JavaBuilder is allowed to clean the output folders
        + *    when performing full build operations.
        + *     - option id:         "org.eclipse.jdt.core.builder.cleanOutputFolder"
        + *     - possible values:   { "clean", "ignore" }
        + *     - default:           "clean"
        + * 
        + * BUILDER / Reporting Duplicate Resources
        + *    Indicate the severity of the problem reported when more than one occurrence
        + *    of a resource is to be copied into the output location.
        + *     - option id:         "org.eclipse.jdt.core.builder.duplicateResourceTask"
        + *     - possible values:   { "error", "warning" }
        + *     - default:           "warning"
        + * 
        + * JAVACORE / Computing Project Build Order
        + *    Indicate whether JavaCore should enforce the project build order to be based on
        + *    the classpath prerequisite chain. When requesting to compute, this takes over
        + *    the platform default order (based on project references).
        + *     - option id:         "org.eclipse.jdt.core.computeJavaBuildOrder"
        + *     - possible values:   { "compute", "ignore" }
        + *     - default:           "ignore"	 
        + * 
        + * JAVACORE / Specify Default Source Encoding Format
        + *    Get the encoding format for compiled sources. This setting is read-only, it is equivalent
        + *    to 'ResourcesPlugin.getEncoding()'.
        + *     - option id:         "org.eclipse.jdt.core.encoding"
        + *     - possible values:   { any of the supported encoding name}.
        + *     - default:           
        + * 
        + * JAVACORE / Reporting Incomplete Classpath
        + *    Indicate the severity of the problem reported when an entry on the classpath does not exist, 
        + *    is not legite or is not visible (for example, a referenced project is closed).
        + *     - option id:         "org.eclipse.jdt.core.incompleteClasspath"
        + *     - possible values:   { "error", "warning"}
        + *     - default:           "error"
        + * 
        + * JAVACORE / Reporting Classpath Cycle
        + *    Indicate the severity of the problem reported when a project is involved in a cycle.
        + *     - option id:         "org.eclipse.jdt.core.circularClasspath"
        + *     - possible values:   { "error", "warning" }
        + *     - default:           "error"
        + * 
        + * JAVACORE / Enabling Usage of Classpath Exclusion Patterns
        + *    When disabled, no entry on a project classpath can be associated with
        + *    an exclusion pattern.
        + *     - option id:         "org.eclipse.jdt.core.classpath.exclusionPatterns"
        + *     - possible values:   { "enabled", "disabled" }
        + *     - default:           "enabled"
        + * 
        + * JAVACORE / Enabling Usage of Classpath Multiple Output Locations
        + *    When disabled, no entry on a project classpath can be associated with
        + *    a specific output location, preventing thus usage of multiple output locations.
        + *     - option id:         "org.eclipse.jdt.core.classpath.multipleOutputLocations"
        + *     - possible values:   { "enabled", "disabled" }
        + *     - default:           "enabled"
        + * 
        + *	FORMATTER / Inserting New Line Before Opening Brace
        + *    When Insert, a new line is inserted before an opening brace, otherwise nothing
        + *    is inserted
        + *     - option id:         "org.eclipse.jdt.core.formatter.newline.openingBrace"
        + *     - possible values:   { "insert", "do not insert" }
        + *     - default:           "do not insert"
        + * 
        + *	FORMATTER / Inserting New Line Inside Control Statement
        + *    When Insert, a new line is inserted between } and following else, catch, finally
        + *     - option id:         "org.eclipse.jdt.core.formatter.newline.controlStatement"
        + *     - possible values:   { "insert", "do not insert" }
        + *     - default:           "do not insert"
        + * 
        + *	FORMATTER / Clearing Blank Lines
        + *    When Clear all, all blank lines are removed. When Preserve one, only one is kept
        + *    and all others removed.
        + *     - option id:         "org.eclipse.jdt.core.formatter.newline.clearAll"
        + *     - possible values:   { "clear all", "preserve one" }
        + *     - default:           "preserve one"
        + * 
        + *	FORMATTER / Inserting New Line Between Else/If 
        + *    When Insert, a blank line is inserted between an else and an if when they are 
        + *    contiguous. When choosing to not insert, else-if will be kept on the same
        + *    line when possible.
        + *     - option id:         "org.eclipse.jdt.core.formatter.newline.elseIf"
        + *     - possible values:   { "insert", "do not insert" }
        + *     - default:           "do not insert"
        + * 
        + *	FORMATTER / Inserting New Line In Empty Block
        + *    When insert, a line break is inserted between contiguous { and }, if } is not followed
        + *    by a keyword.
        + *     - option id:         "org.eclipse.jdt.core.formatter.newline.emptyBlock"
        + *     - possible values:   { "insert", "do not insert" }
        + *     - default:           "insert"
        + * 
        + *	FORMATTER / Splitting Lines Exceeding Length
        + *    Enable splitting of long lines (exceeding the configurable length). Length of 0 will
        + *    disable line splitting
        + *     - option id:         "org.eclipse.jdt.core.formatter.lineSplit"
        + *     - possible values:	"", where n is zero or a positive integer
        + *     - default:           "80"
        + * 
        + *	FORMATTER / Compacting Assignment
        + *    Assignments can be formatted asymmetrically, for example 'int x= 2;', when Normal, a space
        + *    is inserted before the assignment operator
        + *     - option id:         "org.eclipse.jdt.core.formatter.style.assignment"
        + *     - possible values:   { "compact", "normal" }
        + *     - default:           "normal"
        + * 
        + *	FORMATTER / Defining Indentation Character
        + *    Either choose to indent with tab characters or spaces
        + *     - option id:         "org.eclipse.jdt.core.formatter.tabulation.char"
        + *     - possible values:   { "tab", "space" }
        + *     - default:           "tab"
        + * 
        + *	FORMATTER / Defining Space Indentation Length
        + *    When using spaces, set the amount of space characters to use for each 
        + *    indentation mark.
        + *     - option id:         "org.eclipse.jdt.core.formatter.tabulation.size"
        + *     - possible values:	"", where n is a positive integer
        + *     - default:           "4"
        + * 
        + *	FORMATTER / Inserting space in cast expression
        + *    When Insert, a space is added between the type and the expression in a cast expression.
        + *     - option id:         "org.eclipse.jdt.core.formatter.space.castexpression"
        + *     - possible values:   { "insert", "do not insert" }
        + *     - default:           "insert"
        + * 
        + *	CODEASSIST / Activate Visibility Sensitive Completion
        + *    When active, completion doesn't show that you can not see
        + *    (for example, you can not see private methods of a super class).
        + *     - option id:         "org.eclipse.jdt.core.codeComplete.visibilityCheck"
        + *     - possible values:   { "enabled", "disabled" }
        + *     - default:           "disabled"
        + * 
        + *	CODEASSIST / Automatic Qualification of Implicit Members
        + *    When active, completion automatically qualifies completion on implicit
        + *    field references and message expressions.
        + *     - option id:         "org.eclipse.jdt.core.codeComplete.forceImplicitQualification"
        + *     - possible values:   { "enabled", "disabled" }
        + *     - default:           "disabled"
        + * 
        + *  CODEASSIST / Define the Prefixes for Field Name
        + *    When the prefixes is non empty, completion for field name will begin with
        + *    one of the proposed prefixes.
        + *     - option id:         "org.eclipse.jdt.core.codeComplete.fieldPrefixes"
        + *     - possible values:   { "[,]*" } where  is a String without any wild-card 
        + *     - default:           ""
        + * 
        + *  CODEASSIST / Define the Prefixes for Static Field Name
        + *    When the prefixes is non empty, completion for static field name will begin with
        + *    one of the proposed prefixes.
        + *     - option id:         "org.eclipse.jdt.core.codeComplete.staticFieldPrefixes"
        + *     - possible values:   { "[,]*" } where  is a String without any wild-card 
        + *     - default:           ""
        + * 
        + *  CODEASSIST / Define the Prefixes for Local Variable Name
        + *    When the prefixes is non empty, completion for local variable name will begin with
        + *    one of the proposed prefixes.
        + *     - option id:         "org.eclipse.jdt.core.codeComplete.localPrefixes"
        + *     - possible values:   { "[,]*" } where  is a String without any wild-card 
        + *     - default:           ""
        + * 
        + *  CODEASSIST / Define the Prefixes for Argument Name
        + *    When the prefixes is non empty, completion for argument name will begin with
        + *    one of the proposed prefixes.
        + *     - option id:         "org.eclipse.jdt.core.codeComplete.argumentPrefixes"
        + *     - possible values:   { "[,]*" } where  is a String without any wild-card 
        + *     - default:           ""
        + * 
        + *  CODEASSIST / Define the Suffixes for Field Name
        + *    When the suffixes is non empty, completion for field name will end with
        + *    one of the proposed suffixes.
        + *     - option id:         "org.eclipse.jdt.core.codeComplete.fieldSuffixes"
        + *     - possible values:   { "[,]*" } where  is a String without any wild-card 
        + *     - default:           ""
        + * 
        + *  CODEASSIST / Define the Suffixes for Static Field Name
        + *    When the suffixes is non empty, completion for static field name will end with
        + *    one of the proposed suffixes.
        + *     - option id:         "org.eclipse.jdt.core.codeComplete.staticFieldSuffixes"
        + *     - possible values:   { "[,]*" } where  is a String without any wild-card 
        + *     - default:           ""
        + * 
        + *  CODEASSIST / Define the Suffixes for Local Variable Name
        + *    When the suffixes is non empty, completion for local variable name will end with
        + *    one of the proposed suffixes.
        + *     - option id:         "org.eclipse.jdt.core.codeComplete.localSuffixes"
        + *     - possible values:   { "[,]*" } where  is a String without any wild-card 
        + *     - default:           ""
        + * 
        + *  CODEASSIST / Define the Suffixes for Argument Name
        + *    When the suffixes is non empty, completion for argument name will end with
        + *    one of the proposed suffixes.
        + *     - option id:         "org.eclipse.jdt.core.codeComplete.argumentSuffixes"
        + *     - possible values:   { "[,]*" } where  is a String without any wild-card 
        + *     - default:           ""
        + * 
        + * + * @return a mutable table containing the default settings of all known options + * (key type: String; value type: String) + * @see #setOptions + */ +public static Hashtable getDefaultOptions(){ + + Hashtable defaultOptions = new Hashtable(10); + + // see #initializeDefaultPluginPreferences() for changing default settings + Preferences preferences = getPlugin().getPluginPreferences(); + HashSet optionNames = JavaModelManager.OptionNames; + + // get preferences set to their default + String[] defaultPropertyNames = preferences.defaultPropertyNames(); + for (int i = 0; i < defaultPropertyNames.length; i++){ + String propertyName = defaultPropertyNames[i]; + if (optionNames.contains(propertyName)) { + defaultOptions.put(propertyName, preferences.getDefaultString(propertyName)); + } + } + // get preferences not set to their default + String[] propertyNames = preferences.propertyNames(); + for (int i = 0; i < propertyNames.length; i++){ + String propertyName = propertyNames[i]; + if (optionNames.contains(propertyName)) { + defaultOptions.put(propertyName, preferences.getDefaultString(propertyName)); + } + } + // get encoding through resource plugin + defaultOptions.put(CORE_ENCODING, ResourcesPlugin.getEncoding()); + + return defaultOptions; +} + +/** + * Returns the single instance of the Java core plug-in runtime class. + * Equivalent to (JavaCore) getPlugin(). + * + * @return the single instance of the Java core plug-in runtime class + */ +public static PHPeclipsePlugin getJavaCore() { + return (PHPeclipsePlugin) getPlugin(); +} + +/** + * Helper method for returning one option value only. Equivalent to (String)JavaCore.getOptions().get(optionName) + * Note that it may answer null if this option does not exist. + *

        + * For a complete description of the configurable options, see getDefaultOptions. + *

        + * + * @param optionName the name of an option + * @return the String value of a given option + * @see JavaCore#getDefaultOptions + * @since 2.0 + */ +public static String getOption(String optionName) { + + if (CORE_ENCODING.equals(optionName)){ + return ResourcesPlugin.getEncoding(); + } + if (JavaModelManager.OptionNames.contains(optionName)){ + Preferences preferences = getPlugin().getPluginPreferences(); + return preferences.getString(optionName).trim(); + } + return null; +} + +/** + * Returns the table of the current options. Initially, all options have their default values, + * and this method returns a table that includes all known options. + *

        + * For a complete description of the configurable options, see getDefaultOptions. + *

        + * + * @return table of current settings of all options + * (key type: String; value type: String) + * @see JavaCore#getDefaultOptions + */ +public static Hashtable getOptions() { + + Hashtable options = new Hashtable(10); + + // see #initializeDefaultPluginPreferences() for changing default settings + Plugin plugin = getPlugin(); + if (plugin != null) { + Preferences preferences = getPlugin().getPluginPreferences(); + HashSet optionNames = JavaModelManager.OptionNames; + + // get preferences set to their default + String[] defaultPropertyNames = preferences.defaultPropertyNames(); + for (int i = 0; i < defaultPropertyNames.length; i++){ + String propertyName = defaultPropertyNames[i]; + if (optionNames.contains(propertyName)){ + options.put(propertyName, preferences.getDefaultString(propertyName)); + } + } + // get preferences not set to their default + String[] propertyNames = preferences.propertyNames(); + for (int i = 0; i < propertyNames.length; i++){ + String propertyName = propertyNames[i]; + if (optionNames.contains(propertyName)){ + options.put(propertyName, preferences.getString(propertyName).trim()); + } + } + // get encoding through resource plugin + options.put(CORE_ENCODING, ResourcesPlugin.getEncoding()); + } + return options; +} + +/** + * This is a helper method, which returns the resolved classpath entry denoted + * by a given entry (if it is a variable entry). It is obtained by resolving the variable + * reference in the first segment. Returns null if unable to resolve using + * the following algorithm: + *
          + *
        • if variable segment cannot be resolved, returns null
        • + *
        • finds a project, JAR or binary folder in the workspace at the resolved path location
        • + *
        • if none finds an external JAR file or folder outside the workspace at the resolved path location
        • + *
        • if none returns null
        • + *
        + *

        + * Variable source attachment path and root path are also resolved and recorded in the resulting classpath entry. + *

        + * NOTE: This helper method does not handle classpath containers, for which should rather be used + * JavaCore#getClasspathContainer(IPath, IJavaProject). + *

        + * + * @param entry the given variable entry + * @return the resolved library or project classpath entry, or null + * if the given variable entry could not be resolved to a valid classpath entry + */ +public static IClasspathEntry getResolvedClasspathEntry(IClasspathEntry entry) { + + if (entry.getEntryKind() != IClasspathEntry.CPE_VARIABLE) + return entry; + + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + IPath resolvedPath = PHPCore.getResolvedVariablePath(entry.getPath()); + if (resolvedPath == null) + return null; + + Object target = JavaModel.getTarget(workspaceRoot, resolvedPath, false); + if (target == null) + return null; + + // inside the workspace + if (target instanceof IResource) { + IResource resolvedResource = (IResource) target; + if (resolvedResource != null) { + switch (resolvedResource.getType()) { + + case IResource.PROJECT : + // internal project + return PHPCore.newProjectEntry(resolvedPath, entry.isExported()); + + case IResource.FILE : +// if (Util.isArchiveFileName(resolvedResource.getName())) { +// // internal binary archive +// return JavaCore.newLibraryEntry( +// resolvedPath, +// getResolvedVariablePath(entry.getSourceAttachmentPath()), +// getResolvedVariablePath(entry.getSourceAttachmentRootPath()), +// entry.isExported()); +// } + break; + + case IResource.FOLDER : + // internal binary folder +// return JavaCore.newLibraryEntry( +// resolvedPath, +// getResolvedVariablePath(entry.getSourceAttachmentPath()), +// getResolvedVariablePath(entry.getSourceAttachmentRootPath()), +// entry.isExported()); + break; + } + } + } + // outside the workspace + if (target instanceof File) { + File externalFile = (File) target; + if (externalFile.isFile()) { + String fileName = externalFile.getName().toLowerCase(); +// if (fileName.endsWith(".jar" //$NON-NLS-1$ +// ) || fileName.endsWith(".zip" //$NON-NLS-1$ +// )) { // external binary archive +// return JavaCore.newLibraryEntry( +// resolvedPath, +// getResolvedVariablePath(entry.getSourceAttachmentPath()), +// getResolvedVariablePath(entry.getSourceAttachmentRootPath()), +// entry.isExported()); +// } + } else { // external binary folder + if (resolvedPath.isAbsolute()){ +// return JavaCore.newLibraryEntry( +// resolvedPath, +// getResolvedVariablePath(entry.getSourceAttachmentPath()), +// getResolvedVariablePath(entry.getSourceAttachmentRootPath()), +// entry.isExported()); + } + } + } + return null; +} + + +/** + * Resolve a variable path (helper method). + * + * @param variablePath the given variable path + * @return the resolved variable path or null if none + */ +public static IPath getResolvedVariablePath(IPath variablePath) { + + if (variablePath == null) + return null; + int count = variablePath.segmentCount(); + if (count == 0) + return null; + + // lookup variable + String variableName = variablePath.segment(0); + IPath resolvedPath = PHPCore.getClasspathVariable(variableName); + if (resolvedPath == null) + return null; + + // append path suffix + if (count > 1) { + resolvedPath = resolvedPath.append(variablePath.removeFirstSegments(1)); + } + return resolvedPath; +} + +/** + * Answers the shared working copies currently registered for this buffer factory. + * Working copies can be shared by several clients using the same buffer factory,see + * IWorkingCopy.getSharedWorkingCopy. + * + * @param factory the given buffer factory + * @return the list of shared working copies for a given buffer factory + * @see IWorkingCopy + * @since 2.0 + */ +public static IWorkingCopy[] getSharedWorkingCopies(IBufferFactory factory){ + + // if factory is null, default factory must be used + if (factory == null) factory = BufferManager.getDefaultBufferManager().getDefaultBufferFactory(); + Map sharedWorkingCopies = JavaModelManager.getJavaModelManager().sharedWorkingCopies; + + Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory); + if (perFactoryWorkingCopies == null) return JavaModelManager.NoWorkingCopy; + Collection copies = perFactoryWorkingCopies.values(); + IWorkingCopy[] result = new IWorkingCopy[copies.size()]; + copies.toArray(result); + return result; +} + +/** + * Initializes the default preferences settings for this plug-in. + */ +protected static void initializeDefaultPluginPreferences() { + + Preferences preferences = PHPeclipsePlugin.getDefault().getPluginPreferences(); + HashSet optionNames = JavaModelManager.OptionNames; + + // Compiler settings + preferences.setDefault(COMPILER_LOCAL_VARIABLE_ATTR, GENERATE); + optionNames.add(COMPILER_LOCAL_VARIABLE_ATTR); + + preferences.setDefault(COMPILER_LINE_NUMBER_ATTR, GENERATE); + optionNames.add(COMPILER_LINE_NUMBER_ATTR); + + preferences.setDefault(COMPILER_SOURCE_FILE_ATTR, GENERATE); + optionNames.add(COMPILER_SOURCE_FILE_ATTR); + + preferences.setDefault(COMPILER_CODEGEN_UNUSED_LOCAL, PRESERVE); + optionNames.add(COMPILER_CODEGEN_UNUSED_LOCAL); + + preferences.setDefault(COMPILER_CODEGEN_TARGET_PLATFORM, VERSION_1_1); + optionNames.add(COMPILER_CODEGEN_TARGET_PLATFORM); + + preferences.setDefault(COMPILER_PB_UNREACHABLE_CODE, ERROR); + optionNames.add(COMPILER_PB_UNREACHABLE_CODE); + + preferences.setDefault(COMPILER_PB_INVALID_IMPORT, ERROR); + optionNames.add(COMPILER_PB_INVALID_IMPORT); + + preferences.setDefault(COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD, WARNING); + optionNames.add(COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD); + + preferences.setDefault(COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME, WARNING); + optionNames.add(COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME); + + preferences.setDefault(COMPILER_PB_DEPRECATION, WARNING); + optionNames.add(COMPILER_PB_DEPRECATION); + + preferences.setDefault(COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE, DISABLED); + optionNames.add(COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE); + + preferences.setDefault(COMPILER_PB_HIDDEN_CATCH_BLOCK, WARNING); + optionNames.add(COMPILER_PB_HIDDEN_CATCH_BLOCK); + + preferences.setDefault(COMPILER_PB_UNUSED_LOCAL, IGNORE); + optionNames.add(COMPILER_PB_UNUSED_LOCAL); + + preferences.setDefault(COMPILER_PB_UNUSED_PARAMETER, IGNORE); + optionNames.add(COMPILER_PB_UNUSED_PARAMETER); + + preferences.setDefault(COMPILER_PB_UNUSED_PARAMETER_WHEN_IMPLEMENTING_ABSTRACT, DISABLED); + optionNames.add(COMPILER_PB_UNUSED_PARAMETER_WHEN_IMPLEMENTING_ABSTRACT); + + preferences.setDefault(COMPILER_PB_UNUSED_PARAMETER_WHEN_OVERRIDING_CONCRETE, DISABLED); + optionNames.add(COMPILER_PB_UNUSED_PARAMETER_WHEN_OVERRIDING_CONCRETE); + + preferences.setDefault(COMPILER_PB_UNUSED_IMPORT, WARNING); + optionNames.add(COMPILER_PB_UNUSED_IMPORT); + + preferences.setDefault(COMPILER_PB_UNUSED_PRIVATE_MEMBER, IGNORE); + optionNames.add(COMPILER_PB_UNUSED_PRIVATE_MEMBER); + + preferences.setDefault(COMPILER_PB_SYNTHETIC_ACCESS_EMULATION, IGNORE); + optionNames.add(COMPILER_PB_SYNTHETIC_ACCESS_EMULATION); + + preferences.setDefault(COMPILER_PB_NON_NLS_STRING_LITERAL, IGNORE); + optionNames.add(COMPILER_PB_NON_NLS_STRING_LITERAL); + + preferences.setDefault(COMPILER_PB_ASSERT_IDENTIFIER, IGNORE); + optionNames.add(COMPILER_PB_ASSERT_IDENTIFIER); + + preferences.setDefault(COMPILER_PB_STATIC_ACCESS_RECEIVER, WARNING); + optionNames.add(COMPILER_PB_STATIC_ACCESS_RECEIVER); + + preferences.setDefault(COMPILER_PB_NO_EFFECT_ASSIGNMENT, WARNING); + optionNames.add(COMPILER_PB_NO_EFFECT_ASSIGNMENT); + + preferences.setDefault(COMPILER_PB_INCOMPATIBLE_NON_INHERITED_INTERFACE_METHOD, WARNING); + optionNames.add(COMPILER_PB_INCOMPATIBLE_NON_INHERITED_INTERFACE_METHOD); + + preferences.setDefault(COMPILER_PB_CHAR_ARRAY_IN_STRING_CONCATENATION, WARNING); + optionNames.add(COMPILER_PB_CHAR_ARRAY_IN_STRING_CONCATENATION); + + preferences.setDefault(COMPILER_TASK_TAGS, DEFAULT_TASK_TAG); //$NON-NLS-1$ + optionNames.add(COMPILER_TASK_TAGS); + + preferences.setDefault(COMPILER_TASK_PRIORITIES, DEFAULT_TASK_PRIORITY); //$NON-NLS-1$ + optionNames.add(COMPILER_TASK_PRIORITIES); + + preferences.setDefault(COMPILER_SOURCE, VERSION_1_3); + optionNames.add(COMPILER_SOURCE); + + preferences.setDefault(COMPILER_COMPLIANCE, VERSION_1_3); + optionNames.add(COMPILER_COMPLIANCE); + + preferences.setDefault(COMPILER_PB_MAX_PER_UNIT, "100"); //$NON-NLS-1$ + optionNames.add(COMPILER_PB_MAX_PER_UNIT); + + // Builder settings + preferences.setDefault(CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, ""); //$NON-NLS-1$ + optionNames.add(CORE_JAVA_BUILD_RESOURCE_COPY_FILTER); + + preferences.setDefault(CORE_JAVA_BUILD_INVALID_CLASSPATH, ABORT); + optionNames.add(CORE_JAVA_BUILD_INVALID_CLASSPATH); + + preferences.setDefault(CORE_JAVA_BUILD_DUPLICATE_RESOURCE, WARNING); + optionNames.add(CORE_JAVA_BUILD_DUPLICATE_RESOURCE); + + preferences.setDefault(CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, CLEAN); + optionNames.add(CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER); + + // JavaCore settings + preferences.setDefault(CORE_JAVA_BUILD_ORDER, IGNORE); + optionNames.add(CORE_JAVA_BUILD_ORDER); + + preferences.setDefault(CORE_CIRCULAR_CLASSPATH, ERROR); + optionNames.add(CORE_CIRCULAR_CLASSPATH); + + preferences.setDefault(CORE_INCOMPLETE_CLASSPATH, ERROR); + optionNames.add(CORE_INCOMPLETE_CLASSPATH); + + preferences.setDefault(CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, ENABLED); + optionNames.add(CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS); + + preferences.setDefault(CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, ENABLED); + optionNames.add(CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS); + + // encoding setting comes from resource plug-in + optionNames.add(CORE_ENCODING); + + // Formatter settings + preferences.setDefault(FORMATTER_NEWLINE_OPENING_BRACE, DO_NOT_INSERT); + optionNames.add(FORMATTER_NEWLINE_OPENING_BRACE); + + preferences.setDefault(FORMATTER_NEWLINE_CONTROL, DO_NOT_INSERT); + optionNames.add(FORMATTER_NEWLINE_CONTROL); + + preferences.setDefault(FORMATTER_CLEAR_BLANK_LINES, PRESERVE_ONE); + optionNames.add(FORMATTER_CLEAR_BLANK_LINES); + + preferences.setDefault(FORMATTER_NEWLINE_ELSE_IF, DO_NOT_INSERT); + optionNames.add(FORMATTER_NEWLINE_ELSE_IF); + + preferences.setDefault(FORMATTER_NEWLINE_EMPTY_BLOCK, INSERT); + optionNames.add(FORMATTER_NEWLINE_EMPTY_BLOCK); + + preferences.setDefault(FORMATTER_LINE_SPLIT, "80"); //$NON-NLS-1$ + optionNames.add(FORMATTER_LINE_SPLIT); + + preferences.setDefault(FORMATTER_COMPACT_ASSIGNMENT, NORMAL); + optionNames.add(FORMATTER_COMPACT_ASSIGNMENT); + + preferences.setDefault(FORMATTER_TAB_CHAR, TAB); + optionNames.add(FORMATTER_TAB_CHAR); + + preferences.setDefault(FORMATTER_TAB_SIZE, "4"); //$NON-NLS-1$ + optionNames.add(FORMATTER_TAB_SIZE); + + preferences.setDefault(FORMATTER_SPACE_CASTEXPRESSION, INSERT); //$NON-NLS-1$ + optionNames.add(FORMATTER_SPACE_CASTEXPRESSION); + + // CodeAssist settings + preferences.setDefault(CODEASSIST_VISIBILITY_CHECK, DISABLED); //$NON-NLS-1$ + optionNames.add(CODEASSIST_VISIBILITY_CHECK); + + preferences.setDefault(CODEASSIST_IMPLICIT_QUALIFICATION, DISABLED); //$NON-NLS-1$ + optionNames.add(CODEASSIST_IMPLICIT_QUALIFICATION); + + preferences.setDefault(CODEASSIST_FIELD_PREFIXES, ""); //$NON-NLS-1$ + optionNames.add(CODEASSIST_FIELD_PREFIXES); + + preferences.setDefault(CODEASSIST_STATIC_FIELD_PREFIXES, ""); //$NON-NLS-1$ + optionNames.add(CODEASSIST_STATIC_FIELD_PREFIXES); + + preferences.setDefault(CODEASSIST_LOCAL_PREFIXES, ""); //$NON-NLS-1$ + optionNames.add(CODEASSIST_LOCAL_PREFIXES); + + preferences.setDefault(CODEASSIST_ARGUMENT_PREFIXES, ""); //$NON-NLS-1$ + optionNames.add(CODEASSIST_ARGUMENT_PREFIXES); + + preferences.setDefault(CODEASSIST_FIELD_SUFFIXES, ""); //$NON-NLS-1$ + optionNames.add(CODEASSIST_FIELD_SUFFIXES); + + preferences.setDefault(CODEASSIST_STATIC_FIELD_SUFFIXES, ""); //$NON-NLS-1$ + optionNames.add(CODEASSIST_STATIC_FIELD_SUFFIXES); + + preferences.setDefault(CODEASSIST_LOCAL_SUFFIXES, ""); //$NON-NLS-1$ + optionNames.add(CODEASSIST_LOCAL_SUFFIXES); + + preferences.setDefault(CODEASSIST_ARGUMENT_SUFFIXES, ""); //$NON-NLS-1$ + optionNames.add(CODEASSIST_ARGUMENT_SUFFIXES); +} + +/** + * Returns whether the given marker references the given Java element. + * Used for markers, which denote a Java element rather than a resource. + * + * @param element the element + * @param marker the marker + * @return true if the marker references the element, false otherwise + * @exception CoreException if the IMarker.getAttribute on the marker fails + */ +public static boolean isReferencedBy(IJavaElement element, IMarker marker) throws CoreException { + + // only match units or classfiles + if (element instanceof IMember){ + IMember member = (IMember) element; + if (member.isBinary()){ + element = null; //member.getClassFile(); + } else { + element = member.getCompilationUnit(); + } + } + if (element == null) return false; + if (marker == null) return false; + + String markerHandleId = (String)marker.getAttribute(ATT_HANDLE_ID); + if (markerHandleId == null) return false; + + IJavaElement markerElement = PHPCore.create(markerHandleId); +// while (true){ + if (element.equals(markerElement)) return true; // external elements may still be equal with different handleIDs. + + // cycle through enclosing types in case marker is associated with a classfile (15568) +// if (markerElement instanceof IClassFile){ +// IType enclosingType = ((IClassFile)markerElement).getType().getDeclaringType(); +// if (enclosingType != null){ +// markerElement = enclosingType.getClassFile(); // retry with immediate enclosing classfile +// continue; +// } +// } +// break; +// } + return false; +} + +/** + * Returns whether the given marker delta references the given Java element. + * Used for markers deltas, which denote a Java element rather than a resource. + * + * @param element the element + * @param markerDelta the marker delta + * @return true if the marker delta references the element + * @exception CoreException if the IMarkerDelta.getAttribute on the marker delta fails + */ +public static boolean isReferencedBy(IJavaElement element, IMarkerDelta markerDelta) throws CoreException { + + // only match units or classfiles + if (element instanceof IMember){ + IMember member = (IMember) element; + if (member.isBinary()){ + element = null; //member.getClassFile(); + } else { + element = member.getCompilationUnit(); + } + } + if (element == null) return false; + if (markerDelta == null) return false; + + String markerDeltarHandleId = (String)markerDelta.getAttribute(ATT_HANDLE_ID); + if (markerDeltarHandleId == null) return false; + + IJavaElement markerElement = PHPCore.create(markerDeltarHandleId); +// while (true){ + if (element.equals(markerElement)) return true; // external elements may still be equal with different handleIDs. + + // cycle through enclosing types in case marker is associated with a classfile (15568) +// if (markerElement instanceof IClassFile){ +// IType enclosingType = ((IClassFile)markerElement).getType().getDeclaringType(); +// if (enclosingType != null){ +// markerElement = enclosingType.getClassFile(); // retry with immediate enclosing classfile +// continue; +// } +// } +// break; +// } + return false; +} + +/** + * Creates and returns a new classpath entry of kind CPE_CONTAINER + * for the given path. The path of the container will be used during resolution so as to map this + * container entry to a set of other classpath entries the container is acting for. + *

        + * A container entry allows to express indirect references to a set of libraries, projects and variable entries, + * which can be interpreted differently for each Java project where it is used. + * A classpath container entry can be resolved using JavaCore.getResolvedClasspathContainer, + * and updated with JavaCore.classpathContainerChanged + *

        + * A container is exclusively resolved by a ClasspathContainerInitializer registered onto the + * extension point "org.eclipse.jdt.core.classpathContainerInitializer". + *

        + * A container path must be formed of at least one segment, where:

          + *
        • the first segment is a unique ID identifying the target container, there must be a container initializer registered + * onto this ID through the extension point "org.eclipse.jdt.core.classpathContainerInitializer".
        • + *
        • the remaining segments will be passed onto the initializer, and can be used as additional + * hints during the initialization phase.
        • + *
        + *

        + * Example of an ClasspathContainerInitializer for a classpath container denoting a default JDK container: + * + * containerEntry = JavaCore.newContainerEntry(new Path("MyProvidedJDK/default")); + * + * + * + *

        + * Note that this operation does not attempt to validate classpath containers + * or access the resources at the given paths. + *

        + * The resulting entry is not exported to dependent projects. This method is equivalent to + * newContainerEntry(-,false). + *

        + * @param containerPath the path identifying the container, it must be formed of two + * segments + * @return a new container classpath entry + * + * @see JavaCore#getClasspathContainer(IPath, IJavaProject) + * @see JavaCore#newContainerEntry(IPath, boolean) + * @since 2.0 + */ +public static IClasspathEntry newContainerEntry(IPath containerPath) { + + return newContainerEntry(containerPath, false); +} + +/** + * Creates and returns a new classpath entry of kind CPE_CONTAINER + * for the given path. The path of the container will be used during resolution so as to map this + * container entry to a set of other classpath entries the container is acting for. + *

        + * A container entry allows to express indirect references to a set of libraries, projects and variable entries, + * which can be interpreted differently for each Java project where it is used. + * A classpath container entry can be resolved using JavaCore.getResolvedClasspathContainer, + * and updated with JavaCore.classpathContainerChanged + *

        + * A container is exclusively resolved by a ClasspathContainerInitializer registered onto the + * extension point "org.eclipse.jdt.core.classpathContainerInitializer". + *

        + * A container path must be formed of at least one segment, where:

          + *
        • the first segment is a unique ID identifying the target container, there must be a container initializer registered + * onto this ID through the extension point "org.eclipse.jdt.core.classpathContainerInitializer".
        • + *
        • the remaining segments will be passed onto the initializer, and can be used as additional + * hints during the initialization phase.
        • + *
        + *

        + * Example of an ClasspathContainerInitializer for a classpath container denoting a default JDK container: + * + * containerEntry = JavaCore.newContainerEntry(new Path("MyProvidedJDK/default")); + * + * + * + *

        + * Note that this operation does not attempt to validate classpath containers + * or access the resources at the given paths. + *

        + * @param containerPath the path identifying the container, it must be formed of at least + * one segment (ID+hints) + * @param isExported a boolean indicating whether this entry is contributed to dependent + * projects in addition to the output location + * @return a new container classpath entry + * + * @see JavaCore#getClasspathContainer(IPath, IJavaProject) + * @see JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], IProgressMonitor) + * @see JavaCore#newContainerEntry(IPath, boolean) + * @since 2.0 + */ +public static IClasspathEntry newContainerEntry(IPath containerPath, boolean isExported) { + + if (containerPath == null || containerPath.segmentCount() < 1) { + Assert.isTrue( + false, + "Illegal classpath container path: \'" + containerPath.makeRelative().toString() + "\', must have at least one segment (containerID+hints)"); //$NON-NLS-1$//$NON-NLS-2$ + } + return new ClasspathEntry( + IPackageFragmentRoot.K_SOURCE, + IClasspathEntry.CPE_CONTAINER, + containerPath, + ClasspathEntry.NO_EXCLUSION_PATTERNS, + null, // source attachment + null, // source attachment root + null, // specific output folder + isExported); +} + +/** + * Creates and returns a new non-exported classpath entry of kind CPE_LIBRARY for the + * JAR or folder identified by the given absolute path. This specifies that all package fragments + * within the root will have children of type IClassFile. + *

        + * A library entry is used to denote a prerequisite JAR or root folder containing binaries. + * The target JAR or folder can either be defined internally to the workspace (absolute path relative + * to the workspace root) or externally to the workspace (absolute path in the file system). + *

        + * e.g. Here are some examples of binary path usage

          + *
        • "c:/jdk1.2.2/jre/lib/rt.jar" - reference to an external JAR
        • + *
        • "/Project/someLib.jar" - reference to an internal JAR
        • + *
        • "c:/classes/" - reference to an external binary folder
        • + *
        + * Note that this operation does not attempt to validate or access the + * resources at the given paths. + *

        + * The resulting entry is not exported to dependent projects. This method is equivalent to + * newLibraryEntry(-,-,-,false). + *

        + * + * @param path the absolute path of the binary archive + * @param sourceAttachmentPath the absolute path of the corresponding source archive or folder, + * or null if none + * @param sourceAttachmentRootPath the location of the root within the source archive or folder + * or null if this location should be automatically detected. + * @return a new library classpath entry + * + * @see #newLibraryEntry(IPath, IPath, IPath, boolean) + */ +//public static IClasspathEntry newLibraryEntry( +// IPath path, +// IPath sourceAttachmentPath, +// IPath sourceAttachmentRootPath) { +// +// return newLibraryEntry(path, sourceAttachmentPath, sourceAttachmentRootPath, false); +//} + +/** + * Creates and returns a new classpath entry of kind CPE_LIBRARY for the JAR or folder + * identified by the given absolute path. This specifies that all package fragments within the root + * will have children of type IClassFile. + *

        + * A library entry is used to denote a prerequisite JAR or root folder containing binaries. + * The target JAR or folder can either be defined internally to the workspace (absolute path relative + * to the workspace root) or externally to the workspace (absolute path in the file system). + *

        + * e.g. Here are some examples of binary path usage

          + *
        • "c:/jdk1.2.2/jre/lib/rt.jar" - reference to an external JAR
        • + *
        • "/Project/someLib.jar" - reference to an internal JAR
        • + *
        • "c:/classes/" - reference to an external binary folder
        • + *
        + * Note that this operation does not attempt to validate or access the + * resources at the given paths. + *

        + * + * @param path the absolute path of the binary archive + * @param sourceAttachmentPath the absolute path of the corresponding source archive or folder, + * or null if none + * @param sourceAttachmentRootPath the location of the root within the source archive or folder + * or null if this location should be automatically detected. + * @param isExported indicates whether this entry is contributed to dependent + * projects in addition to the output location + * @return a new library classpath entry + * @since 2.0 + */ +//public static IClasspathEntry newLibraryEntry( +// IPath path, +// IPath sourceAttachmentPath, +// IPath sourceAttachmentRootPath, +// boolean isExported) { +// +// if (!path.isAbsolute()) Assert.isTrue(false, "Path for IClasspathEntry must be absolute"); //$NON-NLS-1$ +// +// return new ClasspathEntry( +// IPackageFragmentRoot.K_BINARY, +// IClasspathEntry.CPE_LIBRARY, +// JavaProject.canonicalizedPath(path), +// ClasspathEntry.NO_EXCLUSION_PATTERNS, +// sourceAttachmentPath, +// sourceAttachmentRootPath, +// null, // specific output folder +// isExported); +//} + +/** + * Creates and returns a new non-exported classpath entry of kind CPE_PROJECT + * for the project identified by the given absolute path. + *

        + * A project entry is used to denote a prerequisite project on a classpath. + * The referenced project will be contributed as a whole, either as sources (in the Java Model, it + * contributes all its package fragment roots) or as binaries (when building, it contributes its + * whole output location). + *

        + * A project reference allows to indirect through another project, independently from its internal layout. + *

        + * The prerequisite project is referred to using an absolute path relative to the workspace root. + *

        + * The resulting entry is not exported to dependent projects. This method is equivalent to + * newProjectEntry(_,false). + *

        + * + * @param path the absolute path of the binary archive + * @return a new project classpath entry + * + * @see JavaCore#newProjectEntry(IPath, boolean) + */ +public static IClasspathEntry newProjectEntry(IPath path) { + return newProjectEntry(path, false); +} + +/** + * Creates and returns a new classpath entry of kind CPE_PROJECT + * for the project identified by the given absolute path. + *

        + * A project entry is used to denote a prerequisite project on a classpath. + * The referenced project will be contributed as a whole, either as sources (in the Java Model, it + * contributes all its package fragment roots) or as binaries (when building, it contributes its + * whole output location). + *

        + * A project reference allows to indirect through another project, independently from its internal layout. + *

        + * The prerequisite project is referred to using an absolute path relative to the workspace root. + *

        + * + * @param path the absolute path of the prerequisite project + * @param isExported indicates whether this entry is contributed to dependent + * projects in addition to the output location + * @return a new project classpath entry + * @since 2.0 + */ +public static IClasspathEntry newProjectEntry(IPath path, boolean isExported) { + + if (!path.isAbsolute()) Assert.isTrue(false, "Path for IClasspathEntry must be absolute"); //$NON-NLS-1$ + + return new ClasspathEntry( + IPackageFragmentRoot.K_SOURCE, + IClasspathEntry.CPE_PROJECT, + path, + ClasspathEntry.NO_EXCLUSION_PATTERNS, + null, // source attachment + null, // source attachment root + null, // specific output folder + isExported); +} + +/** + * Returns a new empty region. + * + * @return a new empty region + */ +public static IRegion newRegion() { + return new Region(); +} + +/** + * Creates and returns a new classpath entry of kind CPE_SOURCE + * for the project's source folder identified by the given absolute + * workspace-relative path. This specifies that all package fragments + * within the root will have children of type ICompilationUnit. + *

        + * The source folder is referred to using an absolute path relative to the + * workspace root, e.g. /Project/src. A project's source + * folders are located with that project. That is, a source classpath + * entry specifying the path /P1/src is only usable for + * project P1. + *

        + *

        + * The source classpath entry created by this method includes all source + * files below the given workspace-relative path. To selectively exclude + * some of these source files, use the factory method + * JavaCore.newSourceEntry(IPath,IPath[]) instead. + *

        + *

        + * Note that all sources/binaries inside a project are contributed as a whole through + * a project entry (see JavaCore.newProjectEntry). Particular + * source entries cannot be selectively exported. + *

        + * + * @param path the absolute workspace-relative path of a source folder + * @return a new source classpath entry with not exclusion patterns + * + * @see #newSourceEntry(org.eclipse.core.runtime.IPath,org.eclipse.core.runtime.IPath[]) + */ +public static IClasspathEntry newSourceEntry(IPath path) { + + return newSourceEntry(path, ClasspathEntry.NO_EXCLUSION_PATTERNS, null /*output location*/); +} + +/** + * Creates and returns a new classpath entry of kind CPE_SOURCE + * for the project's source folder identified by the given absolute + * workspace-relative path but excluding all source files with paths + * matching any of the given patterns. This specifies that all package + * fragments within the root will have children of type + * ICompilationUnit. + *

        + * The source folder is referred to using an absolute path relative to the + * workspace root, e.g. /Project/src. A project's source + * folders are located with that project. That is, a source classpath + * entry specifying the path /P1/src is only usable for + * project P1. + *

        + *

        + * The source classpath entry created by this method includes all source + * files below the given workspace-relative path except for those matched + * by one (or more) of the given exclusion patterns. Each exclusion pattern + * is represented by a relative path, which is interpreted as relative to + * the source folder. For example, if the source folder path is + * /Project/src and the exclusion pattern is + * com/xyz/tests/**, then source files + * like /Project/src/com/xyz/Foo.java + * and /Project/src/com/xyz/utils/Bar.java would be included, + * whereas /Project/src/com/xyz/tests/T1.java + * and /Project/src/com/xyz/tests/quick/T2.java would be + * excluded. Exclusion patterns can contain can contain '**', '*' or '?' + * wildcards; see IClasspathEntry.getExclusionPatterns + * for the full description of the syntax and semantics of exclusion + * patterns. + *

        + * If the empty list of exclusion patterns is specified, the source folder + * will automatically include all resources located inside the source + * folder. In that case, the result is entirely equivalent to using the + * factory method JavaCore.newSourceEntry(IPath). + *

        + *

        + * Note that all sources/binaries inside a project are contributed as a whole through + * a project entry (see JavaCore.newProjectEntry). Particular + * source entries cannot be selectively exported. + *

        + * + * @param path the absolute workspace-relative path of a source folder + * @param exclusionPatterns the possibly empty list of exclusion patterns + * represented as relative paths + * @return a new source classpath entry with the given exclusion patterns + * @see #newSourceEntry(org.eclipse.core.runtime.IPath) + * @see IClasspathEntry#getExclusionPatterns + * + * @since 2.1 + */ +public static IClasspathEntry newSourceEntry(IPath path, IPath[] exclusionPatterns) { + + return newSourceEntry(path, exclusionPatterns, null /*output location*/); +} + +/** + * Creates and returns a new classpath entry of kind CPE_SOURCE + * for the project's source folder identified by the given absolute + * workspace-relative path but excluding all source files with paths + * matching any of the given patterns, and associated with a specific output location + * (that is, ".class" files are not going to the project default output location). + * All package fragments within the root will have children of type + * ICompilationUnit. + *

        + * The source folder is referred to using an absolute path relative to the + * workspace root, e.g. /Project/src. A project's source + * folders are located with that project. That is, a source classpath + * entry specifying the path /P1/src is only usable for + * project P1. + *

        + *

        + * The source classpath entry created by this method includes all source + * files below the given workspace-relative path except for those matched + * by one (or more) of the given exclusion patterns. Each exclusion pattern + * is represented by a relative path, which is interpreted as relative to + * the source folder. For example, if the source folder path is + * /Project/src and the exclusion pattern is + * com/xyz/tests/**, then source files + * like /Project/src/com/xyz/Foo.java + * and /Project/src/com/xyz/utils/Bar.java would be included, + * whereas /Project/src/com/xyz/tests/T1.java + * and /Project/src/com/xyz/tests/quick/T2.java would be + * excluded. Exclusion patterns can contain can contain '**', '*' or '?' + * wildcards; see IClasspathEntry.getExclusionPatterns + * for the full description of the syntax and semantics of exclusion + * patterns. + *

        + * If the empty list of exclusion patterns is specified, the source folder + * will automatically include all resources located inside the source + * folder. In that case, the result is entirely equivalent to using the + * factory method JavaCore.newSourceEntry(IPath). + *

        + *

        + * Additionally, a source entry can be associated with a specific output location. + * By doing so, the Java builder will ensure that the generated ".class" files will + * be issued inside this output location, as opposed to be generated into the + * project default output location (when output location is null). + * Note that multiple source entries may target the same output location. + * The output location is referred to using an absolute path relative to the + * workspace root, e.g. "/Project/bin", it must be located inside + * the same project as the source folder. + *

        + *

        + * Also note that all sources/binaries inside a project are contributed as a whole through + * a project entry (see JavaCore.newProjectEntry). Particular + * source entries cannot be selectively exported. + *

        + * + * @param path the absolute workspace-relative path of a source folder + * @param exclusionPatterns the possibly empty list of exclusion patterns + * represented as relative paths + * @param outputLocation the specific output location for this source entry (null if using project default ouput location) + * @return a new source classpath entry with the given exclusion patterns + * @see #newSourceEntry(org.eclipse.core.runtime.IPath) + * @see IClasspathEntry#getExclusionPatterns + * @see IClasspathEntry#getOutputLocation() + * + * @since 2.1 + */ +public static IClasspathEntry newSourceEntry(IPath path, IPath[] exclusionPatterns, IPath specificOutputLocation) { + + if (!path.isAbsolute()) Assert.isTrue(false, "Path for IClasspathEntry must be absolute"); //$NON-NLS-1$ + if (exclusionPatterns == null) Assert.isTrue(false, "Exclusion pattern set cannot be null"); //$NON-NLS-1$ + + return new ClasspathEntry( + IPackageFragmentRoot.K_SOURCE, + IClasspathEntry.CPE_SOURCE, + path, + exclusionPatterns, + null, // source attachment + null, // source attachment root + specificOutputLocation, // custom output location + false); +} + +/** + * Creates and returns a new non-exported classpath entry of kind CPE_VARIABLE + * for the given path. The first segment of the path is the name of a classpath variable. + * The trailing segments of the path will be appended to resolved variable path. + *

        + * A variable entry allows to express indirect references on a classpath to other projects or libraries, + * depending on what the classpath variable is referring. + *

        + * It is possible to register an automatic initializer (ClasspathVariableInitializer), + * which will be invoked through the extension point "org.eclipse.jdt.core.classpathVariableInitializer". + * After resolution, a classpath variable entry may either correspond to a project or a library entry.

      • + *

        + * e.g. Here are some examples of variable path usage

          + *
        • "JDTCORE" where variable JDTCORE is + * bound to "c:/jars/jdtcore.jar". The resolved classpath entry is denoting the library "c:\jars\jdtcore.jar"
        • + *
        • "JDTCORE" where variable JDTCORE is + * bound to "/Project_JDTCORE". The resolved classpath entry is denoting the project "/Project_JDTCORE"
        • + *
        • "PLUGINS/com.example/example.jar" where variable PLUGINS + * is bound to "c:/eclipse/plugins". The resolved classpath entry is denoting the library "c:/eclipse/plugins/com.example/example.jar"
        • + *
        + * Note that this operation does not attempt to validate classpath variables + * or access the resources at the given paths. + *

        + * The resulting entry is not exported to dependent projects. This method is equivalent to + * newVariableEntry(-,-,-,false). + *

        + * + * @param variablePath the path of the binary archive; first segment is the + * name of a classpath variable + * @param variableSourceAttachmentPath the path of the corresponding source archive, + * or null if none; if present, the first segment is the + * name of a classpath variable (not necessarily the same variable + * as the one that begins variablePath) + * @param sourceAttachmentRootPath the location of the root within the source archive + * or null if archivePath is also null + * @return a new library classpath entry + * + * @see JavaCore#newVariableEntry(IPath, IPath, IPath, boolean) + */ +//public static IClasspathEntry newVariableEntry( +// IPath variablePath, +// IPath variableSourceAttachmentPath, +// IPath sourceAttachmentRootPath) { +// +// return newVariableEntry(variablePath, variableSourceAttachmentPath, sourceAttachmentRootPath, false); +//} + +/** + * Creates and returns a new non-exported classpath entry of kind CPE_VARIABLE + * for the given path. The first segment of the path is the name of a classpath variable. + * The trailing segments of the path will be appended to resolved variable path. + *

        + * A variable entry allows to express indirect references on a classpath to other projects or libraries, + * depending on what the classpath variable is referring. + *

        + * It is possible to register an automatic initializer (ClasspathVariableInitializer), + * which will be invoked through the extension point "org.eclipse.jdt.core.classpathVariableInitializer". + * After resolution, a classpath variable entry may either correspond to a project or a library entry. + *

        + * e.g. Here are some examples of variable path usage

          + *
        • "JDTCORE" where variable JDTCORE is + * bound to "c:/jars/jdtcore.jar". The resolved classpath entry is denoting the library "c:\jars\jdtcore.jar"
        • + *
        • "JDTCORE" where variable JDTCORE is + * bound to "/Project_JDTCORE". The resolved classpath entry is denoting the project "/Project_JDTCORE"
        • + *
        • "PLUGINS/com.example/example.jar" where variable PLUGINS + * is bound to "c:/eclipse/plugins". The resolved classpath entry is denoting the library "c:/eclipse/plugins/com.example/example.jar"
        • + *
        + * Note that this operation does not attempt to validate classpath variables + * or access the resources at the given paths. + *

        + * + * @param variablePath the path of the binary archive; first segment is the + * name of a classpath variable + * @param variableSourceAttachmentPath the path of the corresponding source archive, + * or null if none; if present, the first segment is the + * name of a classpath variable (not necessarily the same variable + * as the one that begins variablePath) + * @param sourceAttachmentRootPath the location of the root within the source archive + * or null if archivePath is also null + * @param isExported indicates whether this entry is contributed to dependent + * projects in addition to the output location + * @return a new variable classpath entry + * @since 2.0 + */ +//public static IClasspathEntry newVariableEntry( +// IPath variablePath, +// IPath variableSourceAttachmentPath, +// IPath variableSourceAttachmentRootPath, +// boolean isExported) { +// +// if (variablePath == null || variablePath.segmentCount() < 1) { +// Assert.isTrue( +// false, +// "Illegal classpath variable path: \'" + variablePath.makeRelative().toString() + "\', must have at least one segment"); //$NON-NLS-1$//$NON-NLS-2$ +// } +// +// return new ClasspathEntry( +// IPackageFragmentRoot.K_SOURCE, +// IClasspathEntry.CPE_VARIABLE, +// variablePath, +// ClasspathEntry.NO_EXCLUSION_PATTERNS, +// variableSourceAttachmentPath, // source attachment +// variableSourceAttachmentRootPath, // source attachment root +// null, // specific output folder +// isExported); +//} + +/** + * Removed the given classpath variable. Does nothing if no value was + * set for this classpath variable. + *

        + * This functionality cannot be used while the resource tree is locked. + *

        + * Classpath variable values are persisted locally to the workspace, and + * are preserved from session to session. + *

        + * + * @param variableName the name of the classpath variable + * @see #setClasspathVariable + * + * @deprecated - use version with extra IProgressMonitor + */ +//public static void removeClasspathVariable(String variableName) { +// removeClasspathVariable(variableName, null); +//} + +/** + * Removed the given classpath variable. Does nothing if no value was + * set for this classpath variable. + *

        + * This functionality cannot be used while the resource tree is locked. + *

        + * Classpath variable values are persisted locally to the workspace, and + * are preserved from session to session. + *

        + * + * @param variableName the name of the classpath variable + * @param monitor the progress monitor to report progress + * @see #setClasspathVariable + */ +//public static void removeClasspathVariable( +// String variableName, +// IProgressMonitor monitor) { +// +// try { +// updateVariableValues(new String[]{ variableName}, new IPath[]{ null }, monitor); +// } catch (JavaModelException e) { +// } +//} + +/** + * Removes the given element changed listener. + * Has no affect if an identical listener is not registered. + * + * @param listener the listener + */ +public static void removeElementChangedListener(IElementChangedListener listener) { + JavaModelManager.getJavaModelManager().removeElementChangedListener(listener); +} + +/** + * Bind a container reference path to some actual containers (IClasspathContainer). + * This API must be invoked whenever changes in container need to be reflected onto the JavaModel. + * Containers can have distinct values in different projects, therefore this API considers a + * set of projects with their respective containers. + *

        + * containerPath is the path under which these values can be referenced through + * container classpath entries (IClasspathEntry#CPE_CONTAINER). A container path + * is formed by a first ID segment followed with extra segments, which can be used as additional hints + * for the resolution. The container ID is used to identify a ClasspathContainerInitializer + * registered on the extension point "org.eclipse.jdt.core.classpathContainerInitializer". + *

        + * There is no assumption that each individual container value passed in argument + * (respectiveContainers) must answer the exact same path when requested + * IClasspathContainer#getPath. + * Indeed, the containerPath is just an indication for resolving it to an actual container object. It can be + * delegated to a ClasspathContainerInitializer, which can be activated through the extension + * point "org.eclipse.jdt.core.ClasspathContainerInitializer"). + *

        + * In reaction to changing container values, the JavaModel will be updated to reflect the new + * state of the updated container. + *

        + * This functionality cannot be used while the resource tree is locked. + *

        + * Classpath container values are persisted locally to the workspace, but + * are not preserved from a session to another. It is thus highly recommended to register a + * ClasspathContainerInitializer for each referenced container + * (through the extension point "org.eclipse.jdt.core.ClasspathContainerInitializer"). + *

        + * Note: setting a container to null will cause it to be lazily resolved again whenever + * its value is required. In particular, this will cause a registered initializer to be invoked + * again. + *

        + * @param containerPath - the name of the container reference, which is being updated + * @param affectedProjects - the set of projects for which this container is being bound + * @param respectiveContainers - the set of respective containers for the affected projects + * @param monitor a monitor to report progress + * + * @see ClasspathContainerInitializer + * @see #getClasspathContainer(IPath, IJavaProject) + * @see IClasspathContainer + * @since 2.0 + */ +//public static void setClasspathContainer(final IPath containerPath, IJavaProject[] affectedProjects, IClasspathContainer[] respectiveContainers, IProgressMonitor monitor) throws JavaModelException { +// +// if (affectedProjects.length != respectiveContainers.length) Assert.isTrue(false, "Projects and containers collections should have the same size"); //$NON-NLS-1$ +// +// if (monitor != null && monitor.isCanceled()) return; +// +// if (JavaModelManager.CP_RESOLVE_VERBOSE){ +// System.out.println("CPContainer SET - setting container: ["+containerPath+"] for projects: {" //$NON-NLS-1$ //$NON-NLS-2$ +// + (Util.toString(affectedProjects, +// new Util.Displayable(){ +// public String displayString(Object o) { return ((IJavaProject) o).getElementName(); } +// })) +// + "} with values: " //$NON-NLS-1$ +// + (Util.toString(respectiveContainers, +// new Util.Displayable(){ +// public String displayString(Object o) { return ((IClasspathContainer) o).getDescription(); } +// })) +// ); +// } +// +// final int projectLength = affectedProjects.length; +// final IJavaProject[] modifiedProjects; +// System.arraycopy(affectedProjects, 0, modifiedProjects = new IJavaProject[projectLength], 0, projectLength); +// final IClasspathEntry[][] oldResolvedPaths = new IClasspathEntry[projectLength][]; +// +// // filter out unmodified project containers +// int remaining = 0; +// for (int i = 0; i < projectLength; i++){ +// +// if (monitor != null && monitor.isCanceled()) return; +// +// IJavaProject affectedProject = affectedProjects[i]; +// IClasspathContainer newContainer = respectiveContainers[i]; +// if (newContainer == null) newContainer = JavaModelManager.ContainerInitializationInProgress; // 30920 - prevent infinite loop +// boolean found = false; +// if (JavaProject.hasJavaNature(affectedProject.getProject())){ +// IClasspathEntry[] rawClasspath = affectedProject.getRawClasspath(); +// for (int j = 0, cpLength = rawClasspath.length; j + * This functionality cannot be used while the resource tree is locked. + *

        + * Classpath variable values are persisted locally to the workspace, and + * are preserved from session to session. + *

        + * + * @param variableName the name of the classpath variable + * @param path the path + * @see #getClasspathVariable + * + * @deprecated - use API with IProgressMonitor + */ +//public static void setClasspathVariable(String variableName, IPath path) +// throws JavaModelException { +// +// setClasspathVariable(variableName, path, null); +//} + +/** + * Sets the value of the given classpath variable. + * The path must not be null. + *

        + * This functionality cannot be used while the resource tree is locked. + *

        + * Classpath variable values are persisted locally to the workspace, and + * are preserved from session to session. + *

        + * Updating a variable with the same value has no effect. + * + * @param variableName the name of the classpath variable + * @param path the path + * @param monitor a monitor to report progress + * @see #getClasspathVariable + */ +//public static void setClasspathVariable( +// String variableName, +// IPath path, +// IProgressMonitor monitor) +// throws JavaModelException { +// +// if (path == null) Assert.isTrue(false, "Variable path cannot be null"); //$NON-NLS-1$ +// setClasspathVariables(new String[]{variableName}, new IPath[]{ path }, monitor); +//} + +/** + * Sets the values of all the given classpath variables at once. + * Null paths can be used to request corresponding variable removal. + *

        + * This functionality cannot be used while the resource tree is locked. + *

        + * Classpath variable values are persisted locally to the workspace, and + * are preserved from session to session. + *

        + * Updating a variable with the same value has no effect. + * + * @param variableNames an array of names for the updated classpath variables + * @param paths an array of path updates for the modified classpath variables (null + * meaning that the corresponding value will be removed + * @param monitor a monitor to report progress + * @see #getClasspathVariable + * @since 2.0 + */ +//public static void setClasspathVariables( +// String[] variableNames, +// IPath[] paths, +// IProgressMonitor monitor) +// throws JavaModelException { +// +// if (variableNames.length != paths.length) Assert.isTrue(false, "Variable names and paths collections should have the same size"); //$NON-NLS-1$ +// //TODO: should check that null cannot be used as variable paths +// updateVariableValues(variableNames, paths, monitor); +//} + +/* (non-Javadoc) + * Method declared on IExecutableExtension. + * Record any necessary initialization data from the plugin. + */ +public void setInitializationData( + IConfigurationElement cfig, + String propertyName, + Object data) + throws CoreException { +} + +/** + * Sets the current table of options. All and only the options explicitly included in the given table + * are remembered; all previous option settings are forgotten, including ones not explicitly + * mentioned. + *

        + * For a complete description of the configurable options, see getDefaultOptions. + *

        + * + * @param newOptions the new options (key type: String; value type: String), + * or null to reset all options to their default values + * @see JavaCore#getDefaultOptions + */ +public static void setOptions(Hashtable newOptions) { + + // see #initializeDefaultPluginPreferences() for changing default settings + Preferences preferences = getPlugin().getPluginPreferences(); + + if (newOptions == null){ + newOptions = PHPCore.getDefaultOptions(); + } + Enumeration keys = newOptions.keys(); + while (keys.hasMoreElements()){ + String key = (String)keys.nextElement(); + if (!JavaModelManager.OptionNames.contains(key)) continue; // unrecognized option + if (key.equals(CORE_ENCODING)) continue; // skipped, contributed by resource prefs + String value = (String)newOptions.get(key); + preferences.setValue(key, value); + } + + // persist options + getPlugin().savePluginPreferences(); +} + +/** + * Shutdown the JavaCore plug-in. + *

        + * De-registers the JavaModelManager as a resource changed listener and save participant. + *

        + * @see org.eclipse.core.runtime.Plugin#shutdown() + */ +public void shutdown() { + + //savePluginPreferences(); + getPlugin().savePluginPreferences(); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + workspace.removeResourceChangeListener(JavaModelManager.getJavaModelManager().deltaProcessor); + workspace.removeSaveParticipant(PHPeclipsePlugin.getDefault()); + + ((JavaModelManager) JavaModelManager.getJavaModelManager()).shutdown(); +} + +/** + * Initiate the background indexing process. + * This should be deferred after the plugin activation. + */ +//private void startIndexing() { +// +// JavaModelManager.getJavaModelManager().getIndexManager().reset(); +//} + +/** + * Startup of the JavaCore plug-in. + *

        + * Registers the JavaModelManager as a resource changed listener and save participant. + * Starts the background indexing, and restore saved classpath variable values. + *

        + * @see org.eclipse.core.runtime.Plugin#startup() + */ +public void startup() { + + JavaModelManager manager = JavaModelManager.getJavaModelManager(); + try { + manager.configurePluginDebugOptions(); + + // request state folder creation (workaround 19885) + PHPCore.getPlugin().getStateLocation(); + + // retrieve variable values + PHPCore.getPlugin().getPluginPreferences().addPropertyChangeListener(new JavaModelManager.PluginPreferencesListener()); +// TODO khartlage temp-del +// manager.loadVariablesAndContainers(); + + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + workspace.addResourceChangeListener( + manager.deltaProcessor, + IResourceChangeEvent.PRE_AUTO_BUILD + | IResourceChangeEvent.POST_AUTO_BUILD + | IResourceChangeEvent.POST_CHANGE + | IResourceChangeEvent.PRE_DELETE + | IResourceChangeEvent.PRE_CLOSE); + +// startIndexing(); + workspace.addSaveParticipant(PHPeclipsePlugin.getDefault(), manager); + + } catch (CoreException e) { + } catch (RuntimeException e) { + manager.shutdown(); + throw e; + } +} + + +/** + * Internal updating of a variable values (null path meaning removal), allowing to change multiple variable values at once. + */ +//private static void updateVariableValues( +// String[] variableNames, +// IPath[] variablePaths, +// IProgressMonitor monitor) throws JavaModelException { +// +// if (monitor != null && monitor.isCanceled()) return; +// +// if (JavaModelManager.CP_RESOLVE_VERBOSE){ +// System.out.println("CPVariable SET - setting variables: {" + Util.toString(variableNames) //$NON-NLS-1$ +// + "} with values: " + Util.toString(variablePaths)); //$NON-NLS-1$ +// } +// +// int varLength = variableNames.length; +// +// // gather classpath information for updating +// final HashMap affectedProjects = new HashMap(5); +// JavaModelManager manager = JavaModelManager.getJavaModelManager(); +// IJavaModel model = manager.getJavaModel(); +// +// // filter out unmodified variables +// int discardCount = 0; +// for (int i = 0; i < varLength; i++){ +// String variableName = variableNames[i]; +// IPath oldPath = (IPath)JavaModelManager.variableGet(variableName); // if reentering will provide previous session value +// if (oldPath == JavaModelManager.VariableInitializationInProgress){ +// IPath previousPath = (IPath)JavaModelManager.PreviousSessionVariables.get(variableName); +// if (previousPath != null){ +// if (JavaModelManager.CP_RESOLVE_VERBOSE){ +// System.out.println("CPVariable INIT - reentering access to variable: " + variableName+ " during its initialization, will see previous value: "+ previousPath); //$NON-NLS-1$ //$NON-NLS-2$ +// } +// JavaModelManager.variablePut(variableName, previousPath); // replace value so reentering calls are seeing old value +// } +// oldPath = null; //33695 - cannot filter out restored variable, must update affected project to reset cached CP +// } +// if (oldPath != null && oldPath.equals(variablePaths[i])){ +// variableNames[i] = null; +// discardCount++; +// } +// } +// if (discardCount > 0){ +// if (discardCount == varLength) return; +// int changedLength = varLength - discardCount; +// String[] changedVariableNames = new String[changedLength]; +// IPath[] changedVariablePaths = new IPath[changedLength]; +// for (int i = 0, index = 0; i < varLength; i++){ +// if (variableNames[i] != null){ +// changedVariableNames[index] = variableNames[i]; +// changedVariablePaths[index] = variablePaths[i]; +// index++; +// } +// } +// variableNames = changedVariableNames; +// variablePaths = changedVariablePaths; +// varLength = changedLength; +// } +// +// if (monitor != null && monitor.isCanceled()) return; +// +// if (model != null) { +// IJavaProject[] projects = model.getJavaProjects(); +// nextProject : for (int i = 0, projectLength = projects.length; i < projectLength; i++){ +// IJavaProject project = projects[i]; +// +// // check to see if any of the modified variables is present on the classpath +// IClasspathEntry[] classpath = project.getRawClasspath(); +// for (int j = 0, cpLength = classpath.length; j < cpLength; j++){ +// +// IClasspathEntry entry = classpath[j]; +// for (int k = 0; k < varLength; k++){ +// +// String variableName = variableNames[k]; +// if (entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE){ +// +// if (variableName.equals(entry.getPath().segment(0))){ +// affectedProjects.put(project, project.getResolvedClasspath(true)); +// continue nextProject; +// } +// IPath sourcePath, sourceRootPath; +// if (((sourcePath = entry.getSourceAttachmentPath()) != null && variableName.equals(sourcePath.segment(0))) +// || ((sourceRootPath = entry.getSourceAttachmentRootPath()) != null && variableName.equals(sourceRootPath.segment(0)))) { +// +// affectedProjects.put(project, project.getResolvedClasspath(true)); +// continue nextProject; +// } +// } +// } +// } +// } +// } +// // update variables +// for (int i = 0; i < varLength; i++){ +// JavaModelManager.variablePut(variableNames[i], variablePaths[i]); +// } +// final String[] dbgVariableNames = variableNames; +// +// // update affected project classpaths +// if (!affectedProjects.isEmpty()) { +// try { +// JavaCore_DeleteIt_DeleteIt_DeleteIt_DeleteIt_DeleteIt_DeleteIt_DeleteIt_DeleteIt_DeleteIt_DeleteIt_DeleteIt_DeleteIt_DeleteIt.run( +// new IWorkspaceRunnable() { +// public void run(IProgressMonitor monitor) throws CoreException { +// // propagate classpath change +// Iterator projectsToUpdate = affectedProjects.keySet().iterator(); +// while (projectsToUpdate.hasNext()) { +// +// if (monitor != null && monitor.isCanceled()) return; +// +// JavaProject project = (JavaProject) projectsToUpdate.next(); +// +// if (JavaModelManager.CP_RESOLVE_VERBOSE){ +// System.out.println("CPVariable SET - updating affected project: ["+project.getElementName()+"] due to setting variables: "+ Util.toString(dbgVariableNames)); //$NON-NLS-1$ //$NON-NLS-2$ +// } +// +// project +// .setRawClasspath( +// project.getRawClasspath(), +// SetClasspathOperation.ReuseOutputLocation, +// null, // don't call beginTask on the monitor (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=3717) +// !ResourcesPlugin.getWorkspace().isTreeLocked(), // can change resources +// (IClasspathEntry[]) affectedProjects.get(project), +// false, // updating - no validation +// false); // updating - no need to save +// } +// } +// }, +// monitor); +// } catch (CoreException e) { +// if (JavaModelManager.CP_RESOLVE_VERBOSE){ +// System.out.println("CPVariable SET - FAILED DUE TO EXCEPTION: "+Util.toString(dbgVariableNames)); //$NON-NLS-1$ +// e.printStackTrace(); +// } +// if (e instanceof JavaModelException) { +// throw (JavaModelException)e; +// } else { +// throw new JavaModelException(e); +// } +// } +// } +//} } \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPPerspectiveFactory.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPPerspectiveFactory.java index 2fe7605..8c9a4f0 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPPerspectiveFactory.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPPerspectiveFactory.java @@ -59,7 +59,7 @@ public class PHPPerspectiveFactory implements IPerspectiveFactory { layout.addShowViewShortcut(IPageLayout.ID_BOOKMARKS); // new actions - PHP project creation wizards - layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewInterfaceCreationWizard"); //$NON-NLS-1$ +// layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewInterfaceCreationWizard"); //$NON-NLS-1$ layout.addNewWizardShortcut("net.sourceforge.phpeclipse.wizards.PHPFileWizard"); //$NON-NLS-1$ layout.addNewWizardShortcut("org.eclipse.ui.wizards.new.folder");//$NON-NLS-1$ layout.addNewWizardShortcut("org.eclipse.ui.wizards.new.file");//$NON-NLS-1$ diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPSyntaxEditorPreferencePage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPSyntaxEditorPreferencePage.java new file mode 100644 index 0000000..7b9ba11 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPSyntaxEditorPreferencePage.java @@ -0,0 +1,560 @@ +package net.sourceforge.phpeclipse; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import net.sourceforge.phpeclipse.preferences.ColorEditor; +import net.sourceforge.phpeclipse.preferences.OverlayPreferenceStore; +import net.sourceforge.phpeclipse.preferences.PHPPreferencesMessages; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.preference.FileFieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.List; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +/* + * The preference page for setting the PHP Editor options. + */ +public class PHPSyntaxEditorPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + public final OverlayPreferenceStore.OverlayKey[] Keys = + new OverlayPreferenceStore.OverlayKey[] { + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_MULTILINE_COMMENT), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_MULTILINE_COMMENT_BOLD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_MULTILINE_COMMENT_ITALIC), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_MULTILINE_COMMENT_UNDERLINE), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_SINGLELINE_COMMENT), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_SINGLELINE_COMMENT_BOLD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_SINGLELINE_COMMENT_ITALIC), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_SINGLELINE_COMMENT_UNDERLINE), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_KEYWORD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_KEYWORD_BOLD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_KEYWORD_ITALIC), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_KEYWORD_UNDERLINE), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_VARIABLE), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_VARIABLE_BOLD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_VARIABLE_ITALIC), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_VARIABLE_UNDERLINE), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_TYPE), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_TYPE_BOLD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_TYPE_ITALIC), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_TYPE_UNDERLINE), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_CONSTANT), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_CONSTANT_BOLD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_CONSTANT_ITALIC), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_CONSTANT_UNDERLINE), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_FUNCTIONNAME), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_FUNCTIONNAME_BOLD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_FUNCTIONNAME_ITALIC), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_FUNCTIONNAME_UNDERLINE), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_STRING), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_STRING_BOLD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_STRING_ITALIC), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_STRING_UNDERLINE), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_DEFAULT), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_DEFAULT_BOLD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_DEFAULT_ITALIC), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_DEFAULT_UNDERLINE), + + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHPDOC_KEYWORD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_KEYWORD_BOLD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_KEYWORD_ITALIC), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_KEYWORD_UNDERLINE), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHPDOC_TAG), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_TAG_BOLD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_TAG_ITALIC), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_TAG_UNDERLINE), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHPDOC_LINK), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_LINK_BOLD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_LINK_ITALIC), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_LINK_UNDERLINE), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHPDOC_DEFAULT), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_DEFAULT_BOLD), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_DEFAULT_ITALIC), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_DEFAULT_UNDERLINE), + + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_USERDEF_XMLFILE), + // new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_EDITOR_BACKGROUND) + }; + + private final String[][] SyntaxColorListModel = + new String[][] { + { + PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.multiLineComment"), + IPreferenceConstants.PHP_MULTILINE_COMMENT }, + { + PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.singleLineComment"), + IPreferenceConstants.PHP_SINGLELINE_COMMENT }, + { + PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.keywords"), IPreferenceConstants.PHP_KEYWORD }, { + PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.variables"), IPreferenceConstants.PHP_VARIABLE }, { + PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.types"), IPreferenceConstants.PHP_TYPE }, { + PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.functions"), IPreferenceConstants.PHP_FUNCTIONNAME }, { + PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.constants"), IPreferenceConstants.PHP_CONSTANT }, { + PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.strings"), IPreferenceConstants.PHP_STRING }, { + PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.others"), IPreferenceConstants.PHP_DEFAULT }, { + PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.phpdoc_keywords"), IPreferenceConstants.PHPDOC_KEYWORD }, { + PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.phpdoc_tags"), IPreferenceConstants.PHPDOC_TAG }, { + PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.phpdoc_links"), IPreferenceConstants.PHPDOC_LINK }, { + PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.phpdoc_others"), IPreferenceConstants.PHPDOC_DEFAULT } + }; + + private OverlayPreferenceStore OverlayStore; + + private Map ColorButtons = new HashMap(); + private SelectionListener ColorButtonListener = new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + } + public void widgetSelected(SelectionEvent e) { + ColorEditor editor = (ColorEditor) e.widget.getData(); + PreferenceConverter.setValue(OverlayStore, (String) ColorButtons.get(editor), editor.getColorValue()); + } + }; + + private Map CheckBoxes = new HashMap(); + private SelectionListener CheckBoxListener = new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + } + public void widgetSelected(SelectionEvent e) { + Button button = (Button) e.widget; + OverlayStore.setValue((String) CheckBoxes.get(button), button.getSelection()); + } + }; + + private List SyntaxColorList; + /** The ColorEditor that choose the foreground color. */ + private ColorEditor SyntaxForegroundColorEditor; + private Button BoldCheckBox; + private Button ItalicCheckBox; + private Button UnderlineCheckBox; + private FileFieldEditor userdefPHPSyntaxFileFFE; + // private BooleanFieldEditor showLineNumber; + // private IntegerFieldEditor formatterTabSize; + // private BooleanFieldEditor spacesForTabs; + + public PHPSyntaxEditorPreferencePage() { + setDescription(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.description")); //$NON-NLS-1$ + setPreferenceStore(PHPeclipsePlugin.getDefault().getPreferenceStore()); + OverlayStore = new OverlayPreferenceStore(getPreferenceStore(), Keys); + } + + public void init(IWorkbench workbench) { + } + + public void createControl(Composite parent) { + super.createControl(parent); + } + + private void handleSyntaxColorListSelection() { + int i = SyntaxColorList.getSelectionIndex(); + String key = SyntaxColorListModel[i][1]; + RGB rgb = PreferenceConverter.getColor(OverlayStore, key); + SyntaxForegroundColorEditor.setColorValue(rgb); + BoldCheckBox.setSelection(OverlayStore.getBoolean(key + "_bold")); + ItalicCheckBox.setSelection(OverlayStore.getBoolean(key + "_italic")); + UnderlineCheckBox.setSelection(OverlayStore.getBoolean(key + "_underline")); + } + + /** + * Create the group of options for other parameters (background color for example). + * @param parent the parent component + */ + private void backgroundOptionPage(Composite parent) { + Label label = new Label(parent, SWT.LEFT); + label.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.color")); //$NON-NLS-1$ + GridData gd = new GridData(); + gd.horizontalAlignment = GridData.BEGINNING; + label.setLayoutData(gd); +// final ColorEditor syntaxBackgroundColorEditor = new ColorEditor(parent); +// RGB rgb = PreferenceConverter.getColor(OverlayStore, IPreferenceConstants.PHP_EDITOR_BACKGROUND); +// syntaxBackgroundColorEditor.setColorValue(rgb); +// Button backgroundColorButton = syntaxBackgroundColorEditor.getButton(); +// gd = new GridData(GridData.FILL_HORIZONTAL); +// gd.horizontalAlignment = GridData.BEGINNING; +// backgroundColorButton.setLayoutData(gd); +// backgroundColorButton.addSelectionListener(new SelectionListener() { +// public void widgetDefaultSelected(SelectionEvent e) { +// // do nothing +// } +// public void widgetSelected(SelectionEvent e) { +// PreferenceConverter.setValue(OverlayStore, IPreferenceConstants.PHP_EDITOR_BACKGROUND, syntaxBackgroundColorEditor.getColorValue()); +// } +// }); + } + + /** + * Create the group of options for the syntax parameters. + * @param parent the parent component + * @return + */ + private Control createSyntaxPage(Composite parent) { + + Composite colorComposite = new Composite(parent, SWT.NULL); + colorComposite.setLayout(new GridLayout()); + + Label label = new Label(colorComposite, SWT.LEFT); + label.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.syntax")); //$NON-NLS-1$ + label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Composite editorComposite = new Composite(colorComposite, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.marginHeight = 0; + layout.marginWidth = 0; + editorComposite.setLayout(layout); + GridData gd = new GridData(GridData.FILL_BOTH); + editorComposite.setLayoutData(gd); + + SyntaxColorList = new List(editorComposite, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER); + gd = new GridData(GridData.FILL_BOTH); + gd.heightHint = convertHeightInCharsToPixels(5); + SyntaxColorList.setLayoutData(gd); + + Composite stylesComposite = new Composite(editorComposite, SWT.NONE); + layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.numColumns = 2; + stylesComposite.setLayout(layout); + stylesComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + label = new Label(stylesComposite, SWT.LEFT); + label.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.color")); //$NON-NLS-1$ + gd = new GridData(); + gd.horizontalAlignment = GridData.BEGINNING; + label.setLayoutData(gd); + + SyntaxForegroundColorEditor = new ColorEditor(stylesComposite); + Button foregroundColorButton = SyntaxForegroundColorEditor.getButton(); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalAlignment = GridData.BEGINNING; + foregroundColorButton.setLayoutData(gd); + + BoldCheckBox = new Button(stylesComposite, SWT.CHECK); + BoldCheckBox.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.bold")); //$NON-NLS-1$ + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalAlignment = GridData.BEGINNING; + gd.horizontalSpan = 2; + BoldCheckBox.setLayoutData(gd); + + ItalicCheckBox = new Button(stylesComposite, SWT.CHECK); + ItalicCheckBox.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.italic")); //$NON-NLS-1$ + ItalicCheckBox.setEnabled(false); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalAlignment = GridData.BEGINNING; + gd.horizontalSpan = 2; + ItalicCheckBox.setLayoutData(gd); + + UnderlineCheckBox = new Button(stylesComposite, SWT.CHECK); + UnderlineCheckBox.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.underline")); //$NON-NLS-1$ + UnderlineCheckBox.setEnabled(false); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalAlignment = GridData.BEGINNING; + gd.horizontalSpan = 2; + UnderlineCheckBox.setLayoutData(gd); + + Composite customSyntaxComposite = new Composite(colorComposite, SWT.NONE); + layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.numColumns = 3; + stylesComposite.setLayout(layout); + stylesComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + userdefPHPSyntaxFileFFE = + new FileFieldEditor( + IPreferenceConstants.PHP_USERDEF_XMLFILE, + PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.syntaxdialog"), + colorComposite); + userdefPHPSyntaxFileFFE.setPreferencePage(this); + userdefPHPSyntaxFileFFE.setPreferenceStore(getPreferenceStore()); + userdefPHPSyntaxFileFFE.load(); + + SyntaxColorList.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // do nothing + } + public void widgetSelected(SelectionEvent e) { + handleSyntaxColorListSelection(); + } + }); + + foregroundColorButton.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // do nothing + } + public void widgetSelected(SelectionEvent e) { + int i = SyntaxColorList.getSelectionIndex(); + String key = SyntaxColorListModel[i][1]; + + PreferenceConverter.setValue(OverlayStore, key, SyntaxForegroundColorEditor.getColorValue()); + } + }); + BoldCheckBox.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // do nothing + } + public void widgetSelected(SelectionEvent e) { + int i = SyntaxColorList.getSelectionIndex(); + String key = SyntaxColorListModel[i][1]; + OverlayStore.setValue(key + "_bold", BoldCheckBox.getSelection()); + } + }); + + ItalicCheckBox.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // do nothing + } + public void widgetSelected(SelectionEvent e) { + int i = SyntaxColorList.getSelectionIndex(); + String key = SyntaxColorListModel[i][1]; + OverlayStore.setValue(key + "_italic", ItalicCheckBox.getSelection()); + } + }); + + UnderlineCheckBox.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // do nothing + } + public void widgetSelected(SelectionEvent e) { + int i = SyntaxColorList.getSelectionIndex(); + String key = SyntaxColorListModel[i][1]; + OverlayStore.setValue(key + "_underline", UnderlineCheckBox.getSelection()); + } + }); + return colorComposite; + } + + private void initializeViewerColors(ISourceViewer viewer) { + + IPreferenceStore store = OverlayStore; + if (store != null) { + + StyledText styledText = viewer.getTextWidget(); + } + } + + private Color createColor(IPreferenceStore store, String key, Display display) { + RGB rgb = null; + if (store.contains(key)) { + if (store.isDefault(key)) + rgb = PreferenceConverter.getDefaultColor(store, key); + else + rgb = PreferenceConverter.getColor(store, key); + if (rgb != null) + return new Color(display, rgb); + } + return null; + } + + private static void setEnabled(Control control, boolean enable) { + control.setEnabled(enable); + if (control instanceof Composite) { + Composite composite = (Composite) control; + Control[] children = composite.getChildren(); + for (int i = 0; i < children.length; i++) + setEnabled(children[i], enable); + } + } + + private static void indent(Control control) { + GridData gridData = new GridData(); + gridData.horizontalIndent = 20; + control.setLayoutData(gridData); + } + + private static void createDependency(final Button master, final Control slave) { + indent(slave); + master.addSelectionListener(new SelectionListener() { + public void widgetSelected(SelectionEvent e) { + slave.setEnabled(master.getSelection()); + } + + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + } + + protected Control createContents(Composite parent) { + OverlayStore.load(); + OverlayStore.start(); + //Create overall composite + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + composite.setLayout(layout); + Composite syntaxComposite = new Composite(composite, SWT.NULL); + syntaxComposite.setLayout(new GridLayout()); + layout = new GridLayout(); + layout.numColumns = 3; + Group syntaxGroup = new Group(syntaxComposite, SWT.NONE); + syntaxGroup.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.foreground")); + syntaxGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + syntaxGroup.setLayout(layout); + createSyntaxPage(syntaxGroup); + + Composite backgroundOptions = new Composite(composite,SWT.NULL); + backgroundOptions.setLayout(new GridLayout()); + layout = new GridLayout(); + layout.numColumns = 3; + Group backgroundOptionsGroup = new Group(backgroundOptions,SWT.NONE); + backgroundOptionsGroup.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.background")); + backgroundOptionsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + backgroundOptionsGroup.setLayout(layout); + backgroundOptionPage(backgroundOptionsGroup); + + initialize(); + + +// showLineNumber = new BooleanFieldEditor(PHPeclipsePlugin.LINE_NUMBER_RULER, +// "Show line numbers", composite); +// showLineNumber.setPreferencePage(this); +// showLineNumber.setPreferenceStore(getPreferenceStore()); +// showLineNumber.load(); + +// formatterTabSize = new IntegerFieldEditor(PHPeclipsePlugin.FORMATTER_TAB_SIZE, +// "Displayed tab width", composite, 3); +// formatterTabSize.setPreferencePage(this); +// formatterTabSize.setPreferenceStore(getPreferenceStore()); +// formatterTabSize.load(); +// +// spacesForTabs = new BooleanFieldEditor(PHPeclipsePlugin.SPACES_FOR_TABS, +// "Spaces for Tabs", composite); +// spacesForTabs.setPreferencePage(this); +// spacesForTabs.setPreferenceStore(getPreferenceStore()); +// spacesForTabs.load(); + return composite; + } + + private void initialize() { + initializeFields(); + for (int i = 0; i < SyntaxColorListModel.length; i++) + SyntaxColorList.add(SyntaxColorListModel[i][0]); + SyntaxColorList.getDisplay().asyncExec(new Runnable() { + public void run() { + if (SyntaxColorList != null && !SyntaxColorList.isDisposed()) { + SyntaxColorList.select(0); + handleSyntaxColorListSelection(); + } + } + }); + } + + private void initializeFields() { + + Iterator e = ColorButtons.keySet().iterator(); + while (e.hasNext()) { + ColorEditor c = (ColorEditor) e.next(); + String key = (String) ColorButtons.get(c); + RGB rgb = PreferenceConverter.getColor(OverlayStore, key); + c.setColorValue(rgb); + } + + e = CheckBoxes.keySet().iterator(); + while (e.hasNext()) { + Button b = (Button) e.next(); + String key = (String) CheckBoxes.get(b); + b.setSelection(OverlayStore.getBoolean(key)); + } + } + + public boolean performOk() { + OverlayStore.propagate(); + IPreferenceStore store = getPreferenceStore(); + PHPeclipsePlugin.getDefault().savePluginPreferences(); + userdefPHPSyntaxFileFFE.store(); + // showLineNumber.store(); + // spacesForTabs.store(); + // formatterTabSize.store(); + return true; + } + + protected void performDefaults() { + OverlayStore.loadDefaults(); + initializeFields(); + handleSyntaxColorListSelection(); + userdefPHPSyntaxFileFFE.loadDefault(); + // showLineNumber.loadDefault(); + // spacesForTabs.loadDefault(); + // showLineNumber.loadDefault(); + // formatterTabSize.loadDefault(); + super.performDefaults(); + } + + public void dispose() { + if (OverlayStore != null) { + OverlayStore.stop(); + OverlayStore = null; + } + super.dispose(); + } + + private Control addColorButton(Composite composite, String label, String key, int indentation) { + Label labelControl = new Label(composite, SWT.NONE); + labelControl.setText(label); + GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + gd.horizontalIndent = indentation; + labelControl.setLayoutData(gd); + ColorEditor editor = new ColorEditor(composite); + Button button = editor.getButton(); + button.setData(editor); + gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + button.setLayoutData(gd); + button.addSelectionListener(ColorButtonListener); + ColorButtons.put(editor, key); + return composite; + } + + private Button addCheckBox(Composite parent, String label, String key, int indentation) { + Button checkBox = new Button(parent, SWT.CHECK); + checkBox.setText(label); + GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + gd.horizontalIndent = indentation; + gd.horizontalSpan = 2; + checkBox.setLayoutData(gd); + checkBox.addSelectionListener(CheckBoxListener); + CheckBoxes.put(checkBox, key); + return checkBox; + } + + private void updateStatus(IStatus status) { + } + + /** + * @deprecated Inline to avoid reference to preference page + */ + public static boolean indicateQuixFixableProblems() { + // return PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_CORRECTION_INDICATION); + return false; + } + + /** + * @deprecated Inline to avoid reference to preference page + */ + static public boolean synchronizeOutlineOnCursorMove() { + // return PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE); + return false; + } + +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPeclipsePlugin.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPeclipsePlugin.java index 8cdd585..fe4136e 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPeclipsePlugin.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPeclipsePlugin.java @@ -23,8 +23,13 @@ import java.util.Set; import net.sourceforge.phpdt.externaltools.internal.model.ColorManager; import net.sourceforge.phpdt.externaltools.internal.model.ExternalToolsPlugin; import net.sourceforge.phpdt.externaltools.internal.model.VariableContextManager; +import net.sourceforge.phpdt.internal.ui.preferences.MembersOrderPreferenceCache; import net.sourceforge.phpdt.internal.ui.preferences.TemplatePreferencePage; +import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor; import net.sourceforge.phpdt.internal.ui.viewsupport.ImageDescriptorRegistry; +import net.sourceforge.phpdt.internal.ui.viewsupport.ProblemMarkerManager; +import net.sourceforge.phpdt.ui.IContextMenuConstants; +import net.sourceforge.phpdt.ui.IWorkingCopyManager; import net.sourceforge.phpdt.ui.PreferenceConstants; import net.sourceforge.phpdt.ui.text.JavaTextTools; import net.sourceforge.phpeclipse.builder.ExternalEditorInput; @@ -33,6 +38,7 @@ import net.sourceforge.phpeclipse.builder.FileStorage; import net.sourceforge.phpeclipse.builder.IdentifierIndexManager; import net.sourceforge.phpeclipse.phpeditor.PHPDocumentProvider; import net.sourceforge.phpeclipse.phpeditor.PHPSyntaxRdr; +import net.sourceforge.phpeclipse.phpeditor.WorkingCopyManager; import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider; import net.sourceforge.phpeclipse.resourcesview.PHPElement; import net.sourceforge.phpeclipse.resourcesview.PHPElementAdapterFactory; @@ -52,6 +58,9 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; +import org.eclipse.jface.action.GroupMarker; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.Separator; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; import org.eclipse.jface.text.BadLocationException; @@ -83,7 +92,7 @@ public class PHPeclipsePlugin extends AbstractUIPlugin implements IPreferenceCon * id of builder - matches plugin.xml (concatenate pluginid.builderid) */ public static final String BUILDER_PARSER_ID = PLUGIN_ID + ".parserbuilder"; -//public static final String BUILDER_INDEX_ID = PLUGIN_ID + ".indexbuilder"; + //public static final String BUILDER_INDEX_ID = PLUGIN_ID + ".indexbuilder"; /** General debug flag*/ public static final boolean DEBUG = false; @@ -134,14 +143,20 @@ public class PHPeclipsePlugin extends AbstractUIPlugin implements IPreferenceCon /** Windows NT */ private static final int WINDOWS_NT = 5; - private PHPDocumentProvider fCompilationUnitDocumentProvider; private ImageDescriptorRegistry fImageDescriptorRegistry; private HashMap fIndexManagerMap = new HashMap(); + private IWorkingCopyManager fWorkingCopyManager; + private PHPDocumentProvider fCompilationUnitDocumentProvider; private JavaTextTools fJavaTextTools; + private ProblemMarkerManager fProblemMarkerManager; + private MembersOrderPreferenceCache fMembersOrderPreferenceCache; + private IFile fLastEditorFile = null; + private JavaEditorTextHoverDescriptor[] fJavaEditorTextHoverDescriptors; + /** * The constructor. */ @@ -156,7 +171,50 @@ public class PHPeclipsePlugin extends AbstractUIPlugin implements IPreferenceCon // resourceBundle = null; // } } - + /** + * Returns all Java editor text hovers contributed to the workbench. + * + * @return an array of JavaEditorTextHoverDescriptor + * @since 2.1 + */ + public JavaEditorTextHoverDescriptor[] getJavaEditorTextHoverDescriptors() { + if (fJavaEditorTextHoverDescriptors == null) + fJavaEditorTextHoverDescriptors= JavaEditorTextHoverDescriptor.getContributedHovers(); + return fJavaEditorTextHoverDescriptors; + } + + /** + * Resets the Java editor text hovers contributed to the workbench. + *

        + * This will force a rebuild of the descriptors the next time + * a client asks for them. + *

        + * + * @return an array of JavaEditorTextHoverDescriptor + * @since 2.1 + */ + public void resetJavaEditorTextHoverDescriptors() { + fJavaEditorTextHoverDescriptors= null; + } + /** + * Creates the PHP plugin standard groups in a context menu. + */ + public static void createStandardGroups(IMenuManager menu) { + if (!menu.isEmpty()) + return; + + menu.add(new Separator(IContextMenuConstants.GROUP_NEW)); + menu.add(new GroupMarker(IContextMenuConstants.GROUP_GOTO)); + menu.add(new Separator(IContextMenuConstants.GROUP_OPEN)); + menu.add(new GroupMarker(IContextMenuConstants.GROUP_SHOW)); + menu.add(new Separator(IContextMenuConstants.GROUP_REORGANIZE)); + menu.add(new Separator(IContextMenuConstants.GROUP_GENERATE)); + menu.add(new Separator(IContextMenuConstants.GROUP_SEARCH)); + menu.add(new Separator(IContextMenuConstants.GROUP_BUILD)); + menu.add(new Separator(IContextMenuConstants.GROUP_ADDITIONS)); + menu.add(new Separator(IContextMenuConstants.GROUP_VIEWER_SETUP)); + menu.add(new Separator(IContextMenuConstants.GROUP_PROPERTIES)); + } public static IWorkbenchPage getActivePage() { return getDefault().internalGetActivePage(); } @@ -332,6 +390,26 @@ public class PHPeclipsePlugin extends AbstractUIPlugin implements IPreferenceCon return indexManager; } + public synchronized IWorkingCopyManager getWorkingCopyManager() { + if (fWorkingCopyManager == null) { + PHPDocumentProvider provider = getCompilationUnitDocumentProvider(); + fWorkingCopyManager = new WorkingCopyManager(provider); + } + return fWorkingCopyManager; + } + + public synchronized MembersOrderPreferenceCache getMemberOrderPreferenceCache() { + if (fMembersOrderPreferenceCache == null) + fMembersOrderPreferenceCache= new MembersOrderPreferenceCache(); + return fMembersOrderPreferenceCache; + } + + public synchronized ProblemMarkerManager getProblemMarkerManager() { + if (fProblemMarkerManager == null) + fProblemMarkerManager = new ProblemMarkerManager(); + return fProblemMarkerManager; + } + public synchronized JavaTextTools getJavaTextTools() { if (fJavaTextTools == null) fJavaTextTools = new JavaTextTools(getPreferenceStore()); @@ -425,7 +503,7 @@ public class PHPeclipsePlugin extends AbstractUIPlugin implements IPreferenceCon PreferenceConverter.setDefault(store, PHP_MULTILINE_COMMENT, PHPColorProvider.MULTI_LINE_COMMENT); PreferenceConverter.setDefault(store, PHP_SINGLELINE_COMMENT, PHPColorProvider.SINGLE_LINE_COMMENT); - PreferenceConverter.setDefault(store, PHP_TAG, PHPColorProvider.TAG); + PreferenceConverter.setDefault(store, PHP_TAG, PHPColorProvider.TAG); PreferenceConverter.setDefault(store, PHP_KEYWORD, PHPColorProvider.KEYWORD); PreferenceConverter.setDefault(store, PHP_VARIABLE, PHPColorProvider.VARIABLE); PreferenceConverter.setDefault(store, PHP_FUNCTIONNAME, PHPColorProvider.FUNCTION_NAME); @@ -477,11 +555,11 @@ public class PHPeclipsePlugin extends AbstractUIPlugin implements IPreferenceCon // PHPColorProvider.BACKGROUND_COLOR); //language stuff - store.setDefault(RESOURCE_BUNDLE, LANGUAGE_DEFAULT); - store.setDefault(RESOURCE_BUNDLE_EN_GB, "true"); - store.setDefault(RESOURCE_BUNDLE_DE, "false"); - store.setDefault(RESOURCE_BUNDLE_FR, "false"); - store.setDefault(RESOURCE_BUNDLE_ES, "false"); + // store.setDefault(RESOURCE_BUNDLE, LANGUAGE_DEFAULT); + // store.setDefault(RESOURCE_BUNDLE_EN_GB, "true"); + // store.setDefault(RESOURCE_BUNDLE_DE, "false"); + // store.setDefault(RESOURCE_BUNDLE_FR, "false"); + // store.setDefault(RESOURCE_BUNDLE_ES, "false"); store.setDefault(PHP_OUTLINE_CLASS, "true"); //$NON-NLS-1$ store.setDefault(PHP_OUTLINE_FUNC, "true"); //$NON-NLS-1$ @@ -627,7 +705,8 @@ public class PHPeclipsePlugin extends AbstractUIPlugin implements IPreferenceCon * @see org.eclipse.ui.plugin.AbstractUIPlugin#shutdown() */ public void shutdown() throws CoreException { - super.shutdown(); + // moved down: + // super.shutdown(); // externalTools.shutDown(); ColorManager.getDefault().dispose(); @@ -641,6 +720,32 @@ public class PHPeclipsePlugin extends AbstractUIPlugin implements IPreferenceCon indexManager.writeFile(); } + if (fImageDescriptorRegistry != null) + fImageDescriptorRegistry.dispose(); + + // unregisterAdapters(); + + super.shutdown(); + + if (fWorkingCopyManager != null) { + fWorkingCopyManager.shutdown(); + fWorkingCopyManager = null; + } + + if (fCompilationUnitDocumentProvider != null) { + fCompilationUnitDocumentProvider.shutdown(); + fCompilationUnitDocumentProvider = null; + } + + if (fJavaTextTools != null) { + fJavaTextTools.dispose(); + fJavaTextTools = null; + } + + // JavaDocLocations.shutdownJavadocLocations(); + // + // JFaceResources.getFontRegistry().removeListener(fFontPropertyChangeListener); + } public void startup() throws CoreException { diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPDocumentorAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPDocumentorAction.java new file mode 100644 index 0000000..592c5cd --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPDocumentorAction.java @@ -0,0 +1,103 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation + Klaus Hartlage - www.eclipseproject.de +**********************************************************************/ +package net.sourceforge.phpeclipse.actions; + +import java.util.Iterator; + +import net.sourceforge.phpdt.externaltools.launchConfigurations.ExternalToolsUtil; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.ui.IObjectActionDelegate; +import org.eclipse.ui.IWorkbenchPart; + +public class PHPDocumentorAction implements IObjectActionDelegate { + + private IWorkbenchPart workbenchPart; + /** + * Constructor for Action1. + */ + public PHPDocumentorAction() { + super(); + } + + /** + * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) + */ + public void setActivePart(IAction action, IWorkbenchPart targetPart) { + workbenchPart = targetPart; + } + + // public static void open(final URL url, final Shell shell, final String dialogTitle) { + // IHelp help= WorkbenchHelp.getHelpSupport(); + // if (help != null) { + // WorkbenchHelp.getHelpSupport().displayHelpResource(url.toExternalForm()); + // } else { + // showMessage(shell, dialogTitle, ActionMessages.getString("OpenBrowserUtil.help_not_available"), false); //$NON-NLS-1$ + // } + // } + + public void run(IAction action) { + ISelectionProvider selectionProvider = null; + selectionProvider = workbenchPart.getSite().getSelectionProvider(); + + StructuredSelection selection = null; + selection = (StructuredSelection) selectionProvider.getSelection(); + + final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore(); + final String phpExecutable = store.getString(PHPeclipsePlugin.PHP_RUN_PREF); + + //Shell shell = null; + Iterator iterator = null; + iterator = selection.iterator(); + while (iterator.hasNext()) { + // obj => selected object in the view + Object obj = iterator.next(); + + // is it a resource + if (obj instanceof IResource) { + IResource resource = (IResource) obj; + + // check the resource + switch (resource.getType()) { + case IResource.PROJECT : + IProject project = (IProject) resource; + String projectName = project.getLocation().toString(); + String targetDirectory = projectName + "/phpdoc"; + // example: + // C:\>php.exe "C:\Path\To\phpdoc" -t targetdir -o HTML:default:default -d parsedir + String argument = + "\"C:\\php\\phpDocumentor\\phpdoc\" -t " + targetDirectory + " -o HTML:default:default -d " + projectName; + ExternalToolsUtil.execute("phpdocumentor", phpExecutable, argument, true); + break; + // case IResource.FILE : + // // single file: + // IFile file = (IFile) resource; + // PHPParserSuperclass.phpExternalParse(file); + } + } + } + } + + /** + * @see IActionDelegate#selectionChanged(IAction, ISelection) + */ + public void selectionChanged(IAction action, ISelection selection) { + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPObfuscatorAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPObfuscatorAction.java new file mode 100644 index 0000000..1a24c29 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPObfuscatorAction.java @@ -0,0 +1,163 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + + Klaus Hartlage - www.eclipseproject.de +**********************************************************************/ +package net.sourceforge.phpeclipse.actions; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; + +import net.sourceforge.phpdt.internal.compiler.parser.Scanner; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.mover.DefaultFilter; +import net.sourceforge.phpeclipse.mover.DirectoryWalker; +import net.sourceforge.phpeclipse.mover.IFilter; +import net.sourceforge.phpeclipse.mover.IMover; +import net.sourceforge.phpeclipse.mover.obfuscator.ObfuscatorIgnores; +import net.sourceforge.phpeclipse.mover.obfuscator.PHPAnalyzer; +import net.sourceforge.phpeclipse.mover.obfuscator.PHPObfuscatorMover; +import net.sourceforge.phpeclipse.preferences.ProjectProperties; +import net.sourceforge.phpeclipse.views.PHPConsole; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IObjectActionDelegate; +import org.eclipse.ui.IWorkbenchPart; + +/** + * + * @author khartlage + * + * Run the PHP Obfuscator + */ +public class PHPObfuscatorAction implements IObjectActionDelegate { + + private IWorkbenchPart workbenchPart; + /** + * Constructor for PHPObfuscatorAction. + */ + public PHPObfuscatorAction() { + super(); + } + + public void run(IAction action) { + ISelectionProvider selectionProvider = null; + selectionProvider = workbenchPart.getSite().getSelectionProvider(); + + StructuredSelection selection = null; + selection = (StructuredSelection) selectionProvider.getSelection(); + PHPConsole console = PHPConsole.getInstance(); + + // HashMap identifierMap = new HashMap(8096); + // for (int i=0;i selected object in the view + Object obj = iterator.next(); + + // is it a resource + if (obj instanceof IResource) { + + IResource resource = (IResource) obj; + IProject proj = resource.getProject(); + String sourcePath; + + if (identifierMap == null) { + IPreferenceStore store = + PHPeclipsePlugin.getDefault().getPreferenceStore(); + ObfuscatorIgnores ignore = new ObfuscatorIgnores(proj); + identifierMap = ignore.getIdentifierMap(); + } + + String publishPath; + try { + ProjectProperties properties = new ProjectProperties(proj); + publishPath = properties.getPublish(); + } catch (CoreException e1) { + return; + // e1.printStackTrace(); + } + // try { + // publishPath = proj.getPersistentProperty(IObfuscatorPreferences.PUBLISH_PROPERTY_NAME); + // } catch (CoreException e) { + // return; + // } + + DefaultFilter[] filter = + { IFilter.PHP_FILTER, IFilter.DEFAULT_FILTER, }; + IMover[] mover = + { + new PHPAnalyzer( + PHPConsole.getInstance(), + new Scanner(false, false), + identifierMap), + new PHPObfuscatorMover( + PHPConsole.getInstance(), + new Scanner(true, true), + identifierMap)}; + DirectoryWalker walker = new DirectoryWalker(mover, filter); + switch (resource.getType()) { + case IResource.PROJECT : + IProject project = (IProject) resource; + sourcePath = project.getLocation().toOSString(); + try { + walker.walk(sourcePath, publishPath); + } catch (IOException e) { + } + break; + case IResource.FOLDER : + IFolder folder = (IFolder) resource; + sourcePath = folder.getLocation().toOSString(); + try { + walker.walk(sourcePath, publishPath); + } catch (IOException e) { + } + break; + case IResource.FILE : + // single file: + IFile file = (IFile) resource; + sourcePath = file.getLocation().toOSString(); + try { + walker.walk(sourcePath, publishPath); + } catch (IOException e) { + } + break; + } + } + } + } + /** + * @see IActionDelegate#selectionChanged(IAction, ISelection) + */ + public void selectionChanged(IAction action, ISelection selection) { + } + + /** + * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) + */ + public void setActivePart(IAction action, IWorkbenchPart targetPart) { + workbenchPart = targetPart; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/ClasspathDirectory.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/ClasspathDirectory.java new file mode 100644 index 0000000..8448fb7 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/ClasspathDirectory.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.builder; + +import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer; +import net.sourceforge.phpdt.internal.core.Util; +import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +class ClasspathDirectory extends ClasspathLocation { + +IContainer binaryFolder; // includes .class files for a single directory +boolean isOutputFolder; +String binaryLocation; +SimpleLookupTable directoryCache; +String[] missingPackageHolder = new String[1]; + +ClasspathDirectory(IContainer binaryFolder, boolean isOutputFolder) { + this.binaryFolder = binaryFolder; + this.isOutputFolder = isOutputFolder; + IPath location = binaryFolder.getLocation(); + this.binaryLocation = location != null ? location.addTrailingSeparator().toString() : ""; //$NON-NLS-1$ + + this.directoryCache = new SimpleLookupTable(5); +} + +public void cleanup() { + this.directoryCache = null; +} + +String[] directoryList(String qualifiedPackageName) { + String[] dirList = (String[]) directoryCache.get(qualifiedPackageName); + if (dirList == missingPackageHolder) return null; // package exists in another classpath directory or jar + if (dirList != null) return dirList; + + try { + IResource container = binaryFolder.findMember(qualifiedPackageName); // this is a case-sensitive check + if (container instanceof IContainer) { + IResource[] members = ((IContainer) container).members(); + dirList = new String[members.length]; + int index = 0; +// for (int i = 0, l = members.length; i < l; i++) { +// IResource m = members[i]; +// if (m.getType() == IResource.FILE && Util.isClassFileName(m.getName())) +// // add exclusion pattern check here if we want to hide .class files +// dirList[index++] = m.getName(); +// } + if (index < dirList.length) + System.arraycopy(dirList, 0, dirList = new String[index], 0, index); + directoryCache.put(qualifiedPackageName, dirList); + return dirList; + } + } catch(CoreException ignored) { + } + directoryCache.put(qualifiedPackageName, missingPackageHolder); + return null; +} + +boolean doesFileExist(String fileName, String qualifiedPackageName, String qualifiedFullName) { + 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 boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ClasspathDirectory)) return false; + + return binaryFolder.equals(((ClasspathDirectory) o).binaryFolder); +} + +//public NameEnvironmentAnswer findClass(String binaryFileName, String qualifiedPackageName, String qualifiedBinaryFileName) { +// if (!doesFileExist(binaryFileName, qualifiedPackageName, qualifiedBinaryFileName)) return null; // most common case + +// try { +// ClassFileReader reader = ClassFileReader.read(binaryLocation + qualifiedBinaryFileName); +// if (reader != null) return new NameEnvironmentAnswer(reader); +// } catch (Exception e) {} // treat as if class file is missing +// return null; +//} + +public IPath getProjectRelativePath() { + return binaryFolder.getProjectRelativePath(); +} + +public boolean isOutputFolder() { + return isOutputFolder; +} + +public boolean isPackage(String qualifiedPackageName) { + return directoryList(qualifiedPackageName) != null; +} + +public void reset() { + this.directoryCache = new SimpleLookupTable(5); +} + +public String toString() { + return "Binary classpath directory " + binaryFolder.getFullPath().toString(); //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/ClasspathLocation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/ClasspathLocation.java new file mode 100644 index 0000000..e96c467 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/ClasspathLocation.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.builder; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.runtime.IPath; + +public abstract class ClasspathLocation { + +static ClasspathLocation forSourceFolder(IContainer sourceFolder, IContainer outputFolder, char[][] exclusionPatterns) { + return new ClasspathMultiDirectory(sourceFolder, outputFolder, exclusionPatterns); +} + +public static ClasspathLocation forBinaryFolder(IContainer binaryFolder, boolean isOutputFolder) { + return new ClasspathDirectory(binaryFolder, isOutputFolder); +} + +//static ClasspathLocation forLibrary(String libraryPathname) { +// return new ClasspathJar(libraryPathname); +//} + +//static ClasspathLocation forLibrary(IFile library) { +// return new ClasspathJar(library); +//} + +//public abstract NameEnvironmentAnswer findClass(String binaryFileName, String qualifiedPackageName, String qualifiedBinaryFileName); + +public abstract IPath getProjectRelativePath(); + +public boolean isOutputFolder() { + return false; +} + +public abstract boolean isPackage(String qualifiedPackageName); + +// free anything which is not required when the state is saved +public void cleanup() { +} +// reset any internal caches before another compile loop starts +public void reset() { +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/ClasspathMultiDirectory.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/ClasspathMultiDirectory.java new file mode 100644 index 0000000..ad76fe2 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/ClasspathMultiDirectory.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.builder; + +import net.sourceforge.phpdt.core.compiler.CharOperation; + +import org.eclipse.core.resources.IContainer; + +class ClasspathMultiDirectory extends ClasspathDirectory { + +IContainer sourceFolder; +char[][] exclusionPatterns; // used by builders when walking source folders +boolean hasIndependentOutputFolder; // if output folder is not equal to any of the source folders + +ClasspathMultiDirectory(IContainer sourceFolder, IContainer binaryFolder, char[][] exclusionPatterns) { + super(binaryFolder, true); + + this.sourceFolder = sourceFolder; + this.exclusionPatterns = exclusionPatterns; + this.hasIndependentOutputFolder = false; + + // handle the case when a state rebuilds a source folder + if (this.exclusionPatterns != null && this.exclusionPatterns.length == 0) + this.exclusionPatterns = null; +} + +public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ClasspathMultiDirectory)) return false; + + ClasspathMultiDirectory md = (ClasspathMultiDirectory) o; + return sourceFolder.equals(md.sourceFolder) && binaryFolder.equals(md.binaryFolder) + && CharOperation.equals(exclusionPatterns, md.exclusionPatterns); +} + +public String toString() { + return "Source classpath directory " + sourceFolder.getFullPath().toString() + //$NON-NLS-1$ + " with binary directory " + binaryFolder.getFullPath().toString(); //$NON-NLS-1$ +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/PHPBuilder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/PHPBuilder.java new file mode 100644 index 0000000..a4a7be9 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/PHPBuilder.java @@ -0,0 +1,242 @@ +package net.sourceforge.phpeclipse.builder; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.Map; + +import net.sourceforge.phpdt.core.IJavaModelMarker; +import net.sourceforge.phpdt.internal.core.JavaProject; +import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable; +import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.phpeditor.PHPParserAction; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceVisitor; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; + +/** + * Builder for .php files. + * + * + * @see org.eclipse.core.resources.IncrementalProjectBuilder + * @see org.eclipse.core.resources.IResourceDelta + */ +public class PHPBuilder extends IncrementalProjectBuilder { + IProject currentProject; + JavaProject javaProject; + IWorkspaceRoot workspaceRoot; + // NameEnvironment nameEnvironment; + SimpleLookupTable binaryLocationsPerProject; + // maps a project to its binary resources (output folders, class folders, zip/jar files) + State lastState; + +// BuildNotifier notifier; + + private final static int TOTAL_WORK = 100; + + public static IMarker[] getProblemsFor(IResource resource) { + try { + if (resource != null && resource.exists()) + return resource.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); + } catch (CoreException e) { + } // assume there are no problems + return new IMarker[0]; + } + + public static IMarker[] getTasksFor(IResource resource) { + try { + if (resource != null && resource.exists()) + return resource.findMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE); + } catch (CoreException e) { + } // assume there are no tasks + return new IMarker[0]; + } + + // public static void finishedBuilding(IResourceChangeEvent event) { + // BuildNotifier.resetProblemCounters(); + // } + + public static void removeProblemsFor(IResource resource) { + try { + if (resource != null && resource.exists()) + resource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); + } catch (CoreException e) { + } // assume there were no problems + } + + public static void removeTasksFor(IResource resource) { + try { + if (resource != null && resource.exists()) + resource.deleteMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE); + } catch (CoreException e) { + } // assume there were no problems + } + + public static void removeProblemsAndTasksFor(IResource resource) { + try { + if (resource != null && resource.exists()) { + resource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); + resource.deleteMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE); + } + } catch (CoreException e) { + } // assume there were no problems + } + public static State readState(IProject project, DataInputStream in) throws IOException { + return State.read(project, in); + } + + public static void writeState(Object state, DataOutputStream out) throws IOException { + ((State) state).write(out); + } + + /** + * Constructor + */ + public PHPBuilder() { + } + + /** + * + */ + protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { + monitor.beginTask("Parsing files", TOTAL_WORK); + this.currentProject = getProject(); + if (currentProject == null || !currentProject.isAccessible()) + return new IProject[0]; + + if (kind == IncrementalProjectBuilder.FULL_BUILD) { + IResourceDelta delta = getDelta(getProject()); + + processFull(getProject(), monitor); + + } else { // INCREMENTAL_BUILD or AUTO_BUILD + + IResourceDelta delta = getDelta(getProject()); + if (delta != null) { + delta.accept(new ParserVisitor(getProject(), monitor)); + } + + } + monitor.done(); + return null; + } + + /** + * Performs a FULL_BUILD by visiting all nodes in the resource + * tree under the specified project. + * + * @param iProject + */ + public void processFull(final IProject iProject, final IProgressMonitor monitor) { + final IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault().getIndexManager(iProject); + // Create resource visitor logic + IResourceVisitor myVisitor = new IResourceVisitor() { + public boolean visit(IResource resource) throws CoreException { + if (resource.getType() == IResource.FILE) { + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + if ((resource.getFileExtension() != null) && PHPFileUtil.isPHPFile((IFile) resource)) { + monitor.worked(1); + monitor.subTask("Parsing: " + resource.getFullPath()); + // check for parsing errors + PHPParserAction.parseFile((IFile) resource); + // update indexfile for the project: + JavaProject nature = (JavaProject) iProject.getNature(PHPeclipsePlugin.PHP_NATURE_ID); + indexManager.addFile((IFile) resource); + } + } + + return true; + } + }; + + // Process the project using the visitor just created + try { + + // if (iProject.hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) { + // thePHPProject = new PHPProject(); + // thePHPProject.setProject(iProject); + // } + indexManager.initialize(); + iProject.accept(myVisitor); + indexManager.writeFile(); + } catch (CoreException e) { + e.printStackTrace(); + } + + } + + /** + * Sets initialization data for this builder. + *

        + * This method is part of the IExecutableExtension + * interface. + *

        + *

        + * Subclasses are free to extend this method to pick up + * initialization parameters from the plug-in plug-in manifest + * (plugin.xml) file, + * but should be sure to invoke this method on their superclass. + *

        + * For example, the following method looks for a boolean-valued + * parameter named "trace": + *

        +   *     public void setInitializationData(IConfigurationElement cfig, 
        +   *             String propertyName, Object data) 
        +   * 		        throws CoreException {
        +   *         super.setInitializationData(cfig, propertyName, data);
        +   *         if (data instanceof Hashtable) { 
        +   *             Hashtable args = (Hashtable) data; 
        +   *             String traceValue = (String) args.get("trace"); 
        +   *             TRACING = (traceValue!=null && traceValue.equals("true"));
        +   *         }
        +   *     }
        +   * 
        + *

        + */ + public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException { + super.setInitializationData(config, propertyName, data); + + } + + /** + * Informs this builder that it is being started by the build management + * infrastructure. By the time this method is run, the builder's project + * is available and setInitializationData has been called. + * The default implementation should be called by all overriding methods. + * + * @see #setInitializationData + */ + protected void startupOnInitialize() { + // traceMsg("Parse Builder Initialize - startupOnInitialize()"); + } + + /** + * Write trace statements. + * System.out.println with prefix tagging used for simplicity. + */ + // private void traceMsg(String msg) { + // if (PHPeclipsePlugin.DEBUG | traceEnabled) + // System.out.println( + // buildMode + // + "<" + // + getProject() + // + "> " + // + "\t\t\t" + // + buildMark + // + msg); + // } + +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/ParserBuilder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/ParserBuilder.java deleted file mode 100644 index d351132..0000000 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/ParserBuilder.java +++ /dev/null @@ -1,166 +0,0 @@ -package net.sourceforge.phpeclipse.builder; - -import java.util.Map; - -import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil; -import net.sourceforge.phpeclipse.PHPeclipsePlugin; -import net.sourceforge.phpeclipse.phpeditor.PHPParserAction; -import net.sourceforge.phpeclipse.resourcesview.PHPProject; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.resources.IResourceVisitor; -import org.eclipse.core.resources.IncrementalProjectBuilder; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; - -/** - * Builder for .php files. - * - * - * @see org.eclipse.core.resources.IncrementalProjectBuilder - * @see org.eclipse.core.resources.IResourceDelta - */ -public class ParserBuilder extends IncrementalProjectBuilder { - private final static int TOTAL_WORK = 100; - - /** - * Constructor - */ - public ParserBuilder() { - } - - /** - * - */ - protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { - monitor.beginTask("Parsing files", TOTAL_WORK); - - if (kind == IncrementalProjectBuilder.FULL_BUILD) { - IResourceDelta delta = getDelta(getProject()); - - processFull(getProject(), monitor); - - } else { // INCREMENTAL_BUILD or AUTO_BUILD - - IResourceDelta delta = getDelta(getProject()); - if (delta != null) { - delta.accept(new ParserVisitor(getProject(), monitor)); - } - - } - monitor.done(); - return null; - } - - /** - * Performs a FULL_BUILD by visiting all nodes in the resource - * tree under the specified project. - * - * @param iProject - */ - public void processFull(final IProject iProject, final IProgressMonitor monitor) { - final IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault().getIndexManager(iProject); - // Create resource visitor logic - IResourceVisitor myVisitor = new IResourceVisitor() { - public boolean visit(IResource resource) throws CoreException { - if (resource.getType() == IResource.FILE) { - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - if ((resource.getFileExtension() != null) && PHPFileUtil.isPHPFile((IFile) resource)) { - monitor.worked(1); - monitor.subTask("Parsing: " + resource.getFullPath()); - // check for parsing errors - PHPParserAction.parseFile((IFile) resource); - // update indexfile for the project: - PHPProject nature = (PHPProject) iProject.getNature(PHPeclipsePlugin.PHP_NATURE_ID); - indexManager.addFile((IFile) resource); - } - } - - return true; - } - }; - - // Process the project using the visitor just created - try { - -// if (iProject.hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) { -// thePHPProject = new PHPProject(); -// thePHPProject.setProject(iProject); -// } - indexManager.initialize(); - iProject.accept(myVisitor); - indexManager.writeFile(); - } catch (CoreException e) { - e.printStackTrace(); - } - - } - - /** - * Sets initialization data for this builder. - *

        - * This method is part of the IExecutableExtension - * interface. - *

        - *

        - * Subclasses are free to extend this method to pick up - * initialization parameters from the plug-in plug-in manifest - * (plugin.xml) file, - * but should be sure to invoke this method on their superclass. - *

        - * For example, the following method looks for a boolean-valued - * parameter named "trace": - *

        -   *     public void setInitializationData(IConfigurationElement cfig, 
        -   *             String propertyName, Object data) 
        -   * 		        throws CoreException {
        -   *         super.setInitializationData(cfig, propertyName, data);
        -   *         if (data instanceof Hashtable) { 
        -   *             Hashtable args = (Hashtable) data; 
        -   *             String traceValue = (String) args.get("trace"); 
        -   *             TRACING = (traceValue!=null && traceValue.equals("true"));
        -   *         }
        -   *     }
        -   * 
        - *

        - */ - public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException { - super.setInitializationData(config, propertyName, data); - - } - - /** - * Informs this builder that it is being started by the build management - * infrastructure. By the time this method is run, the builder's project - * is available and setInitializationData has been called. - * The default implementation should be called by all overriding methods. - * - * @see #setInitializationData - */ - protected void startupOnInitialize() { - // traceMsg("Parse Builder Initialize - startupOnInitialize()"); - } - - /** - * Write trace statements. - * System.out.println with prefix tagging used for simplicity. - */ - // private void traceMsg(String msg) { - // if (PHPeclipsePlugin.DEBUG | traceEnabled) - // System.out.println( - // buildMode - // + "<" - // + getProject() - // + "> " - // + "\t\t\t" - // + buildMark - // + msg); - // } -} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/State.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/State.java new file mode 100644 index 0000000..754ecbe --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/State.java @@ -0,0 +1,612 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.builder; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; + +import net.sourceforge.phpdt.internal.core.Util; +import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +public class State { +// NOTE: this state cannot contain types that are not defined in this project + +String javaProjectName; +ClasspathMultiDirectory[] sourceLocations; +ClasspathLocation[] binaryLocations; +// keyed by the project relative path of the type (ie. "src1/p1/p2/A.java"), value is a ReferenceCollection or an AdditionalTypeCollection +SimpleLookupTable references; +// keyed by qualified type name "p1/p2/A", value is the project relative path which defines this type "src1/p1/p2/A.java" +SimpleLookupTable typeLocators; + +int buildNumber; +long lastStructuralBuildTime; +SimpleLookupTable structuralBuildTimes; + +private String[] knownPackageNames; // of the form "p1/p2" + +static final byte VERSION = 0x0007; + +static final byte SOURCE_FOLDER = 1; +static final byte BINARY_FOLDER = 2; +static final byte EXTERNAL_JAR = 3; +static final byte INTERNAL_JAR = 4; + +State() { +} + +protected State(PHPBuilder javaBuilder) { + this.knownPackageNames = null; + this.javaProjectName = javaBuilder.currentProject.getName(); + +// this.sourceLocations = javaBuilder.nameEnvironment.sourceLocations; +// this.binaryLocations = javaBuilder.nameEnvironment.binaryLocations; + this.references = new SimpleLookupTable(7); + this.typeLocators = new SimpleLookupTable(7); + + this.buildNumber = 0; // indicates a full build + this.lastStructuralBuildTime = System.currentTimeMillis(); + this.structuralBuildTimes = new SimpleLookupTable(3); +} + +void copyFrom(State lastState) { + try { + this.knownPackageNames = null; + this.buildNumber = lastState.buildNumber + 1; + this.lastStructuralBuildTime = lastState.lastStructuralBuildTime; + this.references = (SimpleLookupTable) lastState.references.clone(); + this.typeLocators = (SimpleLookupTable) lastState.typeLocators.clone(); + } catch (CloneNotSupportedException e) { + this.references = new SimpleLookupTable(lastState.references.elementSize); + Object[] keyTable = lastState.references.keyTable; + Object[] valueTable = lastState.references.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) + if (keyTable[i] != null) + this.references.put(keyTable[i], valueTable[i]); + + this.typeLocators = new SimpleLookupTable(lastState.typeLocators.elementSize); + keyTable = lastState.typeLocators.keyTable; + valueTable = lastState.typeLocators.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) + if (keyTable[i] != null) + this.typeLocators.put(keyTable[i], valueTable[i]); + } +} + +char[][] getDefinedTypeNamesFor(String typeLocator) { + Object c = references.get(typeLocator); +// if (c instanceof AdditionalTypeCollection) +// return ((AdditionalTypeCollection) c).definedTypeNames; + return null; // means only one type is defined with the same name as the file... saves space +} + +boolean isDuplicateLocator(String qualifiedTypeName, String typeLocator) { + String existing = (String) typeLocators.get(qualifiedTypeName); + return existing != null && !existing.equals(typeLocator); +} + +boolean isKnownPackage(String qualifiedPackageName) { + if (knownPackageNames == null) { + ArrayList names = new ArrayList(typeLocators.elementSize); + Object[] keyTable = typeLocators.keyTable; + for (int i = 0, l = keyTable.length; i < l; i++) { + if (keyTable[i] != null) { + String packageName = (String) keyTable[i]; // is a type name of the form p1/p2/A + int last = packageName.lastIndexOf('/'); + packageName = last == -1 ? null : packageName.substring(0, last); + while (packageName != null && !names.contains(packageName)) { + names.add(packageName); + last = packageName.lastIndexOf('/'); + packageName = last == -1 ? null : packageName.substring(0, last); + } + } + } + knownPackageNames = new String[names.size()]; + names.toArray(knownPackageNames); + } + for (int i = 0, l = knownPackageNames.length; i < l; i++) + if (knownPackageNames[i].equals(qualifiedPackageName)) + return true; + return false; +} + +void record(String typeLocator, char[][][] qualifiedRefs, char[][] simpleRefs, char[] mainTypeName, ArrayList typeNames) { +// if (typeNames.size() == 1 && CharOperation.equals(mainTypeName, (char[]) typeNames.get(0))) { +// references.put(typeLocator, new ReferenceCollection(qualifiedRefs, simpleRefs)); +// } else { +// char[][] definedTypeNames = new char[typeNames.size()][]; // can be empty when no types are defined +// typeNames.toArray(definedTypeNames); +// references.put(typeLocator, new AdditionalTypeCollection(definedTypeNames, qualifiedRefs, simpleRefs)); +// } +} + +void recordLocatorForType(String qualifiedTypeName, String typeLocator) { + this.knownPackageNames = null; + typeLocators.put(qualifiedTypeName, typeLocator); +} + +void recordStructuralDependency(IProject prereqProject, State prereqState) { + if (prereqState != null) + structuralBuildTimes.put(prereqProject.getName(), new Long(prereqState.lastStructuralBuildTime)); +} + +void removeLocator(String typeLocatorToRemove) { + this.knownPackageNames = null; + references.removeKey(typeLocatorToRemove); + typeLocators.removeValue(typeLocatorToRemove); +} + +void removePackage(IResourceDelta sourceDelta) { + IResource resource = sourceDelta.getResource(); + switch(resource.getType()) { + case IResource.FOLDER : + IResourceDelta[] children = sourceDelta.getAffectedChildren(); + for (int i = 0, l = children.length; i < l; i++) + removePackage(children[i]); + return; + case IResource.FILE : + IPath typeLocatorPath = resource.getProjectRelativePath(); + if (Util.isJavaFileName(typeLocatorPath.lastSegment())) + removeLocator(typeLocatorPath.toString()); + } +} + +void removeQualifiedTypeName(String qualifiedTypeNameToRemove) { + this.knownPackageNames = null; + typeLocators.removeKey(qualifiedTypeNameToRemove); +} + +static State read(IProject project, DataInputStream in) throws IOException { +// if (JavaBuilder.DEBUG) +// System.out.println("About to read state..."); //$NON-NLS-1$ + if (VERSION != in.readByte()) { +// if (JavaBuilder.DEBUG) +// System.out.println("Found non-compatible state version... answered null"); //$NON-NLS-1$ + return null; + } + + State newState = new State(); + newState.javaProjectName = in.readUTF(); + if (!project.getName().equals(newState.javaProjectName)) { +// if (JavaBuilder.DEBUG) +// System.out.println("Project's name does not match... answered null"); //$NON-NLS-1$ + return null; + } + newState.buildNumber = in.readInt(); + newState.lastStructuralBuildTime = in.readLong(); + + int length = in.readInt(); + newState.sourceLocations = new ClasspathMultiDirectory[length]; + for (int i = 0; i < length; i++) { + IContainer sourceFolder = project, outputFolder = project; + String folderName; + if ((folderName = in.readUTF()).length() > 0) sourceFolder = project.getFolder(folderName); + if ((folderName = in.readUTF()).length() > 0) outputFolder = project.getFolder(folderName); + ClasspathMultiDirectory md = + (ClasspathMultiDirectory) ClasspathLocation.forSourceFolder(sourceFolder, outputFolder, readNames(in)); + if (in.readBoolean()) + md.hasIndependentOutputFolder = true; + newState.sourceLocations[i] = md; + } + + length = in.readInt(); + newState.binaryLocations = new ClasspathLocation[length]; + IWorkspaceRoot root = project.getWorkspace().getRoot(); + for (int i = 0; i < length; i++) { + switch (in.readByte()) { + case SOURCE_FOLDER : + newState.binaryLocations[i] = newState.sourceLocations[in.readInt()]; + break; + case BINARY_FOLDER : + IPath path = new Path(in.readUTF()); + IContainer outputFolder = path.segmentCount() == 1 + ? (IContainer) root.getProject(path.toString()) + : (IContainer) root.getFolder(path); + newState.binaryLocations[i] = ClasspathLocation.forBinaryFolder(outputFolder, in.readBoolean()); + break; +// case EXTERNAL_JAR : +// newState.binaryLocations[i] = ClasspathLocation.forLibrary(in.readUTF()); +// break; +// case INTERNAL_JAR : +// newState.binaryLocations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF()))); + } + } + + newState.structuralBuildTimes = new SimpleLookupTable(length = in.readInt()); + for (int i = 0; i < length; i++) + newState.structuralBuildTimes.put(in.readUTF(), new Long(in.readLong())); + + String[] internedTypeLocators = new String[length = in.readInt()]; + for (int i = 0; i < length; i++) + internedTypeLocators[i] = in.readUTF(); + + newState.typeLocators = new SimpleLookupTable(length = in.readInt()); + for (int i = 0; i < length; i++) + newState.typeLocators.put(in.readUTF(), internedTypeLocators[in.readInt()]); + +// char[][] internedSimpleNames = ReferenceCollection.internSimpleNames(readNames(in), false); +// char[][][] internedQualifiedNames = new char[length = in.readInt()][][]; +// for (int i = 0; i < length; i++) { +// int qLength = in.readInt(); +// char[][] qName = new char[qLength][]; +// for (int j = 0; j < qLength; j++) +// qName[j] = internedSimpleNames[in.readInt()]; +// internedQualifiedNames[i] = qName; +// } +// internedQualifiedNames = ReferenceCollection.internQualifiedNames(internedQualifiedNames); + +// newState.references = new SimpleLookupTable(length = in.readInt()); +// for (int i = 0; i < length; i++) { +// String typeLocator = internedTypeLocators[in.readInt()]; +// ReferenceCollection collection = null; +// switch (in.readByte()) { +// case 1 : +// char[][] additionalTypeNames = readNames(in); +// char[][][] qualifiedNames = new char[in.readInt()][][]; +// for (int j = 0, m = qualifiedNames.length; j < m; j++) +// qualifiedNames[j] = internedQualifiedNames[in.readInt()]; +// char[][] simpleNames = new char[in.readInt()][]; +// for (int j = 0, m = simpleNames.length; j < m; j++) +// simpleNames[j] = internedSimpleNames[in.readInt()]; +// collection = new AdditionalTypeCollection(additionalTypeNames, qualifiedNames, simpleNames); +// break; +// case 2 : +// char[][][] qNames = new char[in.readInt()][][]; +// for (int j = 0, m = qNames.length; j < m; j++) +// qNames[j] = internedQualifiedNames[in.readInt()]; +// char[][] sNames = new char[in.readInt()][]; +// for (int j = 0, m = sNames.length; j < m; j++) +// sNames[j] = internedSimpleNames[in.readInt()]; +// collection = new ReferenceCollection(qNames, sNames); +// } +// newState.references.put(typeLocator, collection); +// } +// if (JavaBuilder.DEBUG) +// System.out.println("Successfully read state for " + newState.javaProjectName); //$NON-NLS-1$ + return newState; +} + +private static char[][] readNames(DataInputStream in) throws IOException { + int length = in.readInt(); + char[][] names = new char[length][]; + for (int i = 0; i < length; i++) { + int nLength = in.readInt(); + char[] name = new char[nLength]; + for (int j = 0; j < nLength; j++) + name[j] = in.readChar(); + names[i] = name; + } + return names; +} + +void tagAsNoopBuild() { + this.buildNumber = -1; // tag the project since it has no source folders and can be skipped +} + +boolean wasNoopBuild() { + return buildNumber == -1; +} + +void tagAsStructurallyChanged() { + this.lastStructuralBuildTime = System.currentTimeMillis(); +} + +boolean wasStructurallyChanged(IProject prereqProject, State prereqState) { + if (prereqState != null) { + Object o = structuralBuildTimes.get(prereqProject.getName()); + long previous = o == null ? 0 : ((Long) o).longValue(); + if (previous == prereqState.lastStructuralBuildTime) return false; + } + return true; +} + +void write(DataOutputStream out) throws IOException { + int length; + Object[] keyTable; + Object[] valueTable; + +/* + * byte VERSION + * String project name + * int build number + * int last structural build number +*/ + out.writeByte(VERSION); + out.writeUTF(javaProjectName); + out.writeInt(buildNumber); + out.writeLong(lastStructuralBuildTime); + +/* + * ClasspathMultiDirectory[] + * int id + * String path(s) +*/ + out.writeInt(length = sourceLocations.length); + for (int i = 0; i < length; i++) { + ClasspathMultiDirectory md = sourceLocations[i]; + out.writeUTF(md.sourceFolder.getProjectRelativePath().toString()); + out.writeUTF(md.binaryFolder.getProjectRelativePath().toString()); + writeNames(md.exclusionPatterns, out); + out.writeBoolean(md.hasIndependentOutputFolder); + } + +/* + * ClasspathLocation[] + * int id + * String path(s) +*/ + out.writeInt(length = binaryLocations.length); + next : for (int i = 0; i < length; i++) { + ClasspathLocation c = binaryLocations[i]; + if (c instanceof ClasspathMultiDirectory) { + out.writeByte(SOURCE_FOLDER); + for (int j = 0, m = sourceLocations.length; j < m; j++) { + if (sourceLocations[j] == c) { + out.writeInt(j); + continue next; + } + } + } else if (c instanceof ClasspathDirectory) { + out.writeByte(BINARY_FOLDER); + ClasspathDirectory cd = (ClasspathDirectory) c; + out.writeUTF(cd.binaryFolder.getFullPath().toString()); + out.writeBoolean(cd.isOutputFolder); + } else { +// ClasspathJar jar = (ClasspathJar) c; +// if (jar.resource == null) { +// out.writeByte(EXTERNAL_JAR); +// out.writeUTF(jar.zipFilename); +// } else { +// out.writeByte(INTERNAL_JAR); +// out.writeUTF(jar.resource.getFullPath().toString()); +// } + } + } + +/* + * Structural build numbers table + * String prereq project name + * int last structural build number +*/ + out.writeInt(length = structuralBuildTimes.elementSize); + if (length > 0) { + keyTable = structuralBuildTimes.keyTable; + valueTable = structuralBuildTimes.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) { + if (keyTable[i] != null) { + length--; + out.writeUTF((String) keyTable[i]); + out.writeLong(((Long) valueTable[i]).longValue()); + } + } +// if (JavaBuilder.DEBUG && length != 0) +// System.out.println("structuralBuildNumbers table is inconsistent"); //$NON-NLS-1$ + } + +/* + * String[] Interned type locators + */ + out.writeInt(length = references.elementSize); + ArrayList internedTypeLocators = new ArrayList(length); + if (length > 0) { + keyTable = references.keyTable; + for (int i = 0, l = keyTable.length; i < l; i++) { + if (keyTable[i] != null) { + length--; + String key = (String) keyTable[i]; + out.writeUTF(key); + internedTypeLocators.add(key); + } + } +// if (JavaBuilder.DEBUG && length != 0) +// System.out.println("references table is inconsistent"); //$NON-NLS-1$ + } + +/* + * Type locators table + * String type name + * int interned locator id + */ + out.writeInt(length = typeLocators.elementSize); + if (length > 0) { + keyTable = typeLocators.keyTable; + valueTable = typeLocators.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) { + if (keyTable[i] != null) { + length--; + out.writeUTF((String) keyTable[i]); + out.writeInt(internedTypeLocators.indexOf((String) valueTable[i])); + } + } +// if (JavaBuilder.DEBUG && length != 0) +// System.out.println("typeLocators table is inconsistent"); //$NON-NLS-1$ + } + +/* + * char[][][] Interned qualified names + * char[][] Interned simple names + */ + ArrayList internedQualifiedNames = new ArrayList(31); + ArrayList internedSimpleNames = new ArrayList(31); + valueTable = references.valueTable; + for (int i = 0, l = valueTable.length; i < l; i++) { +// if (valueTable[i] != null) { +// ReferenceCollection collection = (ReferenceCollection) valueTable[i]; +// char[][][] qNames = collection.qualifiedNameReferences; +// for (int j = 0, m = qNames.length; j < m; j++) { +// char[][] qName = qNames[j]; +// if (!internedQualifiedNames.contains(qName)) { // remember the names have been interned +// internedQualifiedNames.add(qName); +// for (int k = 0, n = qName.length; k < n; k++) { +// char[] sName = qName[k]; +// if (!internedSimpleNames.contains(sName)) // remember the names have been interned +// internedSimpleNames.add(sName); +// } +// } +// } +// char[][] sNames = collection.simpleNameReferences; +// for (int j = 0, m = sNames.length; j < m; j++) { +// char[] sName = sNames[j]; +// if (!internedSimpleNames.contains(sName)) // remember the names have been interned +// internedSimpleNames.add(sName); +// } +// } + } + char[][] internedArray = new char[internedSimpleNames.size()][]; + internedSimpleNames.toArray(internedArray); + writeNames(internedArray, out); + // now write the interned qualified names as arrays of interned simple names + out.writeInt(length = internedQualifiedNames.size()); + for (int i = 0; i < length; i++) { + char[][] qName = (char[][]) internedQualifiedNames.get(i); + int qLength = qName.length; + out.writeInt(qLength); + for (int j = 0; j < qLength; j++) + out.writeInt(internedSimpleNames.indexOf(qName[j])); + } + +/* + * References table + * int interned locator id + * ReferenceCollection +*/ + out.writeInt(length = references.elementSize); + if (length > 0) { + keyTable = references.keyTable; + for (int i = 0, l = keyTable.length; i < l; i++) { +// if (keyTable[i] != null) { +// length--; +// out.writeInt(internedTypeLocators.indexOf((String) keyTable[i])); +// ReferenceCollection collection = (ReferenceCollection) valueTable[i]; +// if (collection instanceof AdditionalTypeCollection) { +// out.writeByte(1); +// AdditionalTypeCollection atc = (AdditionalTypeCollection) collection; +// writeNames(atc.definedTypeNames, out); +// } else { +// out.writeByte(2); +// } +// char[][][] qNames = collection.qualifiedNameReferences; +// int qLength = qNames.length; +// out.writeInt(qLength); +// for (int j = 0; j < qLength; j++) +// out.writeInt(internedQualifiedNames.indexOf(qNames[j])); +// char[][] sNames = collection.simpleNameReferences; +// int sLength = sNames.length; +// out.writeInt(sLength); +// for (int j = 0; j < sLength; j++) +// out.writeInt(internedSimpleNames.indexOf(sNames[j])); +// } + } +// if (JavaBuilder.DEBUG && length != 0) +// System.out.println("references table is inconsistent"); //$NON-NLS-1$ + } +} + +private void writeNames(char[][] names, DataOutputStream out) throws IOException { + int length = names == null ? 0 : names.length; + out.writeInt(length); + for (int i = 0; i < length; i++) { + char[] name = names[i]; + int nLength = name.length; + out.writeInt(nLength); + for (int j = 0; j < nLength; j++) + out.writeChar(name[j]); + } +} + +/** + * Returns a string representation of the receiver. + */ +public String toString() { + return "State for " + javaProjectName //$NON-NLS-1$ + + " (#" + buildNumber //$NON-NLS-1$ + + " @ " + new Date(lastStructuralBuildTime) //$NON-NLS-1$ + + ")"; //$NON-NLS-1$ +} + +/* Debug helper +void dump() { + System.out.println("State for " + javaProjectName + " (" + buildNumber + " @ " + new Date(lastStructuralBuildTime) + ")"); + System.out.println("\tClass path source locations:"); + for (int i = 0, l = sourceLocations.length; i < l; i++) + System.out.println("\t\t" + sourceLocations[i]); + System.out.println("\tClass path binary locations:"); + for (int i = 0, l = binaryLocations.length; i < l; i++) + System.out.println("\t\t" + binaryLocations[i]); + + System.out.print("\tStructural build numbers table:"); + if (structuralBuildTimes.elementSize == 0) { + System.out.print(" "); + } else { + Object[] keyTable = structuralBuildTimes.keyTable; + Object[] valueTable = structuralBuildTimes.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) + if (keyTable[i] != null) + System.out.print("\n\t\t" + keyTable[i].toString() + " -> " + valueTable[i].toString()); + } + + System.out.print("\tType locators table:"); + if (typeLocators.elementSize == 0) { + System.out.print(" "); + } else { + Object[] keyTable = typeLocators.keyTable; + Object[] valueTable = typeLocators.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) + if (keyTable[i] != null) + System.out.print("\n\t\t" + keyTable[i].toString() + " -> " + valueTable[i].toString()); + } + + System.out.print("\n\tReferences table:"); + if (references.elementSize == 0) { + System.out.print(" "); + } else { + Object[] keyTable = references.keyTable; + Object[] valueTable = references.valueTable; + for (int i = 0, l = keyTable.length; i < l; i++) { + if (keyTable[i] != null) { + System.out.print("\n\t\t" + keyTable[i].toString()); + ReferenceCollection c = (ReferenceCollection) valueTable[i]; + char[][][] qRefs = c.qualifiedNameReferences; + System.out.print("\n\t\t\tqualified:"); + if (qRefs.length == 0) + System.out.print(" "); + else for (int j = 0, m = qRefs.length; j < m; j++) + System.out.print(" '" + CharOperation.toString(qRefs[j]) + "'"); + char[][] sRefs = c.simpleNameReferences; + System.out.print("\n\t\t\tsimple:"); + if (sRefs.length == 0) + System.out.print(" "); + else for (int j = 0, m = sRefs.length; j < m; j++) + System.out.print(" " + new String(sRefs[j])); + if (c instanceof AdditionalTypeCollection) { + char[][] names = ((AdditionalTypeCollection) c).definedTypeNames; + System.out.print("\n\t\t\tadditional type names:"); + for (int j = 0, m = names.length; j < m; j++) + System.out.print(" " + new String(names[j])); + } + } + } + } + System.out.print("\n\n"); +} +*/ +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AND_AND_Expression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AND_AND_Expression.java new file mode 100644 index 0000000..be9ecd9 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AND_AND_Expression.java @@ -0,0 +1,310 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; + +//dedicated treatment for the && +public class AND_AND_Expression extends BinaryExpression { + + int rightInitStateIndex = -1; + int mergedInitStateIndex = -1; + + public AND_AND_Expression(Expression left, Expression right, int operator) { + super(left, right, operator); + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + Constant cst = this.left.optimizedBooleanConstant(); + boolean isLeftOptimizedTrue = cst != NotAConstant && cst.booleanValue() == true; + boolean isLeftOptimizedFalse = cst != NotAConstant && cst.booleanValue() == false; + + if (isLeftOptimizedTrue) { + // TRUE && anything + // need to be careful of scenario: + // (x && y) && !z, if passing the left info to the right, it would be swapped by the ! + FlowInfo mergedInfo = left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits(); + mergedInfo = right.analyseCode(currentScope, flowContext, mergedInfo); + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(mergedInfo); + return mergedInfo; + } + + FlowInfo leftInfo = left.analyseCode(currentScope, flowContext, flowInfo); + // need to be careful of scenario: + // (x && y) && !z, if passing the left info to the right, it would be swapped by the ! + FlowInfo rightInfo = leftInfo.initsWhenTrue().unconditionalInits().copy(); + rightInitStateIndex = + currentScope.methodScope().recordInitializationStates(rightInfo); + + int previousMode = rightInfo.reachMode(); + if (isLeftOptimizedFalse){ + rightInfo.setReachMode(FlowInfo.UNREACHABLE); + } + rightInfo = right.analyseCode(currentScope, flowContext, rightInfo); + FlowInfo trueMergedInfo = rightInfo.initsWhenTrue().copy(); + rightInfo.setReachMode(previousMode); // reset after trueMergedInfo got extracted + + FlowInfo mergedInfo = + FlowInfo.conditional( + trueMergedInfo, + leftInfo.initsWhenFalse().copy().unconditionalInits().mergedWith( + rightInfo.initsWhenFalse().copy().unconditionalInits())); + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(mergedInfo); + return mergedInfo; + } + + /** + * Code generation for a binary operation + */ +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// int pc = codeStream.position; +// Label falseLabel, endLabel; +// if (constant != Constant.NotAConstant) { +// // inlined value +// if (valueRequired) +// codeStream.generateConstant(constant, implicitConversion); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// return; +// } +// bits |= OnlyValueRequiredMASK; +// generateOptimizedBoolean( +// currentScope, +// codeStream, +// null, +// (falseLabel = new Label(codeStream)), +// valueRequired); +// /* improving code gen for such a case: boolean b = i < 0 && false +// * since the label has never been used, we have the inlined value on the stack. */ +// if (falseLabel.hasForwardReferences()) { +// if (valueRequired) { +// codeStream.iconst_1(); +// if ((bits & ValueForReturnMASK) != 0) { +// codeStream.ireturn(); +// falseLabel.place(); +// codeStream.iconst_0(); +// } else { +// codeStream.goto_(endLabel = new Label(codeStream)); +// codeStream.decrStackSize(1); +// falseLabel.place(); +// codeStream.iconst_0(); +// endLabel.place(); +// } +// } else { +// falseLabel.place(); +// } +// } +// if (valueRequired) { +// codeStream.generateImplicitConversion(implicitConversion); +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// } + + /** + * Boolean operator code generation + * Optimized operations are: && + */ +// public void generateOptimizedBoolean( +// BlockScope currentScope, +// CodeStream codeStream, +// Label trueLabel, +// Label falseLabel, +// boolean valueRequired) { +// +// if (constant != Constant.NotAConstant) { +// super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired); +// return; +// } +// Constant condConst; +// if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) { +// if (condConst.booleanValue() == true) { +// // && x +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// if (rightInitStateIndex != -1) { +// codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex); +// } +// if ((bits & OnlyValueRequiredMASK) != 0) { +// right.generateCode(currentScope, codeStream, valueRequired); +// } else { +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// } +// } else { +// // && x +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// if (valueRequired) { +// if ((bits & OnlyValueRequiredMASK) != 0) { +// codeStream.iconst_0(); +// } else { +// if (falseLabel != null) { +// // implicit falling through the TRUE case +// codeStream.goto_(falseLabel); +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// } +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// return; +// } +// if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) { +// if (condConst.booleanValue() == true) { +// // x && +// if ((bits & OnlyValueRequiredMASK) != 0) { +// left.generateCode(currentScope, codeStream, valueRequired); +// } else { +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// } +// if (rightInitStateIndex != -1) { +// codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex); +// } +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// } else { +// // x && +// Label internalTrueLabel = new Label(codeStream); +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// internalTrueLabel, // will be false in the end +// null, +// false); +// if (rightInitStateIndex != -1) { +// codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex); +// } +// internalTrueLabel.place(); +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// if (valueRequired) { +// if ((bits & OnlyValueRequiredMASK) != 0) { +// codeStream.iconst_0(); +// } else { +// if (falseLabel != null) { +// // implicit falling through the TRUE case +// codeStream.goto_(falseLabel); +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// } +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// return; +// } +// // default case +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// Label internalFalseLabel = new Label(codeStream); +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// null, +// internalFalseLabel, +// true); +// if (rightInitStateIndex != -1) { +// codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex); +// } +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// null, +// valueRequired); +// internalFalseLabel.place(); +// } +// } else { +// // implicit falling through the TRUE case +// if (trueLabel == null) { +// left.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, true); +// if (rightInitStateIndex != -1) { +// codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex); +// } +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// null, +// falseLabel, +// valueRequired); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// } + + public boolean isCompactableOperation() { + return false; + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + if (visitor.visit(this, scope)) { + left.traverse(visitor, scope); + right.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AbstractMethodDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AbstractMethodDeclaration.java new file mode 100644 index 0000000..15b28ed --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AbstractMethodDeclaration.java @@ -0,0 +1,399 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.InitializationFlowContext; +import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; +import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; +import net.sourceforge.phpdt.internal.compiler.parser.UnitParser; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilationUnit; +import net.sourceforge.phpdt.internal.compiler.problem.AbortMethod; +import net.sourceforge.phpdt.internal.compiler.problem.AbortType; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities; + + +public abstract class AbstractMethodDeclaration + extends AstNode + implements ProblemSeverities, ReferenceContext { + + public MethodScope scope; + //it is not relevent for constructor but it helps to have the name of the constructor here + //which is always the name of the class.....parsing do extra work to fill it up while it do not have to.... + public char[] selector; + public int declarationSourceStart; + public int declarationSourceEnd; + public int modifiers; + public int modifiersSourceStart; + public Argument[] arguments; + public TypeReference[] thrownExceptions; + public Statement[] statements; + public int explicitDeclarations; + public MethodBinding binding; + public boolean ignoreFurtherInvestigation = false; + public boolean needFreeReturn = false; + + public int bodyStart; + public int bodyEnd = -1; + public CompilationResult compilationResult; + + AbstractMethodDeclaration(CompilationResult compilationResult){ + this.compilationResult = compilationResult; + } + + /* + * We cause the compilation task to abort to a given extent. + */ + public void abort(int abortLevel) { + + if (scope == null) { + throw new AbortCompilation(); // cannot do better + } + + CompilationResult compilationResult = + scope.referenceCompilationUnit().compilationResult; + + switch (abortLevel) { + case AbortCompilation : + throw new AbortCompilation(compilationResult); + case AbortCompilationUnit : + throw new AbortCompilationUnit(compilationResult); + case AbortType : + throw new AbortType(compilationResult); + default : + throw new AbortMethod(compilationResult); + } + } + + public abstract void analyseCode(ClassScope scope, InitializationFlowContext initializationContext, FlowInfo info); + + /** + * Bind and add argument's binding into the scope of the method + */ + public void bindArguments() { + + if (arguments != null) { + // by default arguments in abstract/native methods are considered to be used (no complaint is expected) + boolean used = binding == null || binding.isAbstract();// || binding.isNative(); + + int length = arguments.length; + for (int i = 0; i < length; i++) { + TypeBinding argType = binding == null ? null : binding.parameters[i]; + arguments[i].bind(scope, argType, used); + } + } + } + + /** + * Record the thrown exception type bindings in the corresponding type references. + */ + public void bindThrownExceptions() { + + if (this.thrownExceptions != null + && this.binding != null + && this.binding.thrownExceptions != null) { + int thrownExceptionLength = this.thrownExceptions.length; + int length = this.binding.thrownExceptions.length; + if (length == thrownExceptionLength) { + for (int i = 0; i < length; i++) { + this.thrownExceptions[i].resolvedType = this.binding.thrownExceptions[i]; + } + } else { + int bindingIndex = 0; + for (int i = 0; i < thrownExceptionLength && bindingIndex < length; i++) { + TypeReference thrownException = this.thrownExceptions[i]; + ReferenceBinding thrownExceptionBinding = this.binding.thrownExceptions[bindingIndex]; + char[][] bindingCompoundName = thrownExceptionBinding.compoundName; + if (thrownException instanceof SingleTypeReference) { + // single type reference + int lengthName = bindingCompoundName.length; + char[] thrownExceptionTypeName = thrownException.getTypeName()[0]; + if (CharOperation.equals(thrownExceptionTypeName, bindingCompoundName[lengthName - 1])) { + thrownException.resolvedType = thrownExceptionBinding; + bindingIndex++; + } + } else { + // qualified type reference + if (CharOperation.equals(thrownException.getTypeName(), bindingCompoundName)) { + thrownException.resolvedType = thrownExceptionBinding; + bindingIndex++; + } + } + } + } + } + } + + public CompilationResult compilationResult() { + + return this.compilationResult; + } + + /** + * Bytecode generation for a method + */ +// public void generateCode(ClassScope classScope, ClassFile classFile) { +// +// int problemResetPC = 0; +// classFile.codeStream.wideMode = false; // reset wideMode to false +// if (ignoreFurtherInvestigation) { +// // method is known to have errors, dump a problem method +// if (this.binding == null) +// return; // handle methods with invalid signature or duplicates +// int problemsLength; +// IProblem[] problems = +// scope.referenceCompilationUnit().compilationResult.getProblems(); +// IProblem[] problemsCopy = new IProblem[problemsLength = problems.length]; +// System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); +// classFile.addProblemMethod(this, binding, problemsCopy); +// return; +// } +// // regular code generation +// try { +// problemResetPC = classFile.contentsOffset; +// this.generateCode(classFile); +// } catch (AbortMethod e) { +// // a fatal error was detected during code generation, need to restart code gen if possible +// if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) { +// // a branch target required a goto_w, restart code gen in wide mode. +// try { +// this.traverse(new ResetStateForCodeGenerationVisitor(), classScope); +// classFile.contentsOffset = problemResetPC; +// classFile.methodCount--; +// classFile.codeStream.wideMode = true; // request wide mode +// this.generateCode(classFile); // restart method generation +// } catch (AbortMethod e2) { +// int problemsLength; +// IProblem[] problems = +// scope.referenceCompilationUnit().compilationResult.getAllProblems(); +// IProblem[] problemsCopy = new IProblem[problemsLength = problems.length]; +// System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); +// classFile.addProblemMethod(this, binding, problemsCopy, problemResetPC); +// } +// } else { +// // produce a problem method accounting for this fatal error +// int problemsLength; +// IProblem[] problems = +// scope.referenceCompilationUnit().compilationResult.getAllProblems(); +// IProblem[] problemsCopy = new IProblem[problemsLength = problems.length]; +// System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); +// classFile.addProblemMethod(this, binding, problemsCopy, problemResetPC); +// } +// } +// } +// +// private void generateCode(ClassFile classFile) { +// +// classFile.generateMethodInfoHeader(binding); +// int methodAttributeOffset = classFile.contentsOffset; +// int attributeNumber = classFile.generateMethodInfoAttribute(binding); +// if ((!binding.isNative()) && (!binding.isAbstract())) { +// int codeAttributeOffset = classFile.contentsOffset; +// classFile.generateCodeAttributeHeader(); +// CodeStream codeStream = classFile.codeStream; +// codeStream.reset(this, classFile); +// // initialize local positions +// this.scope.computeLocalVariablePositions(binding.isStatic() ? 0 : 1, codeStream); +// +// // arguments initialization for local variable debug attributes +// if (arguments != null) { +// for (int i = 0, max = arguments.length; i < max; i++) { +// LocalVariableBinding argBinding; +// codeStream.addVisibleLocalVariable(argBinding = arguments[i].binding); +// argBinding.recordInitializationStartPC(0); +// } +// } +// if (statements != null) { +// for (int i = 0, max = statements.length; i < max; i++) +// statements[i].generateCode(scope, codeStream); +// } +// if (this.needFreeReturn) { +// codeStream.return_(); +// } +// // local variable attributes +// codeStream.exitUserScope(scope); +// codeStream.recordPositionsFrom(0, this.declarationSourceEnd); +// classFile.completeCodeAttribute(codeAttributeOffset); +// attributeNumber++; +// } else { +// checkArgumentsSize(); +// } +// classFile.completeMethodInfo(methodAttributeOffset, attributeNumber); +// +// // if a problem got reported during code gen, then trigger problem method creation +// if (ignoreFurtherInvestigation) { +// throw new AbortMethod(scope.referenceCompilationUnit().compilationResult); +// } +// } + +// private void checkArgumentsSize() { +// TypeBinding[] parameters = binding.parameters; +// int size = 1; // an abstact method or a native method cannot be static +// for (int i = 0, max = parameters.length; i < max; i++) { +// TypeBinding parameter = parameters[i]; +// if (parameter == LongBinding || parameter == DoubleBinding) { +// size += 2; +// } else { +// size++; +// } +// if (size > 0xFF) { +// scope.problemReporter().noMoreAvailableSpaceForArgument(scope.locals[i], scope.locals[i].declaration); +// } +// } +// } + + public boolean hasErrors() { + return this.ignoreFurtherInvestigation; + } + + public boolean isAbstract() { + + if (binding != null) + return binding.isAbstract(); + return (modifiers & AccAbstract) != 0; + } + + public boolean isClinit() { + + return false; + } + + public boolean isConstructor() { + + return false; + } + + public boolean isDefaultConstructor() { + + return false; + } + + public boolean isInitializationMethod() { + + return false; + } + +// public boolean isNative() { +// +// if (binding != null) +// return binding.isNative(); +// return (modifiers & AccNative) != 0; +// } + + public boolean isStatic() { + + if (binding != null) + return binding.isStatic(); + return (modifiers & AccStatic) != 0; + } + + /** + * Fill up the method body with statement + */ + public abstract void parseStatements( + UnitParser parser, + CompilationUnitDeclaration unit); + + public void resolve(ClassScope upperScope) { + + if (binding == null) { + ignoreFurtherInvestigation = true; + } + + try { + bindArguments(); + bindThrownExceptions(); + resolveStatements(); + } catch (AbortMethod e) { // ========= abort on fatal error ============= + this.ignoreFurtherInvestigation = true; + } + } + + public void resolveStatements() { + + if (statements != null) { + int i = 0, length = statements.length; + while (i < length) + statements[i++].resolve(scope); + } + } + + public String returnTypeToString(int tab) { + + return ""; //$NON-NLS-1$ + } + + public void tagAsHavingErrors() { + + ignoreFurtherInvestigation = true; + } + + public String toString(int tab) { + + String s = tabString(tab); + if (modifiers != AccDefault) { + s += modifiersString(modifiers); + } + + s += returnTypeToString(0); + s += new String(selector) + "("; //$NON-NLS-1$ + if (arguments != null) { + for (int i = 0; i < arguments.length; i++) { + s += arguments[i].toString(0); + if (i != (arguments.length - 1)) + s = s + ", "; //$NON-NLS-1$ + }; + }; + s += ")"; //$NON-NLS-1$ + if (thrownExceptions != null) { + s += " throws "; //$NON-NLS-1$ + for (int i = 0; i < thrownExceptions.length; i++) { + s += thrownExceptions[i].toString(0); + if (i != (thrownExceptions.length - 1)) + s = s + ", "; //$NON-NLS-1$ + }; + }; + + s += toStringStatements(tab + 1); + return s; + } + + public String toStringStatements(int tab) { + + if (isAbstract() || (this.modifiers & AccSemicolonBody) != 0) + return ";"; //$NON-NLS-1$ + + String s = " {"; //$NON-NLS-1$ + if (statements != null) { + for (int i = 0; i < statements.length; i++) { + s = s + "\n" + statements[i].toString(tab); //$NON-NLS-1$ + if (!(statements[i] instanceof Block)) { + s += ";"; //$NON-NLS-1$ + } + } + } + s += "\n" + tabString(tab == 0 ? 0 : tab - 1) + "}"; //$NON-NLS-2$ //$NON-NLS-1$ + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + ClassScope classScope) { + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AbstractVariableDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AbstractVariableDeclaration.java new file mode 100644 index 0000000..3f7803b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AbstractVariableDeclaration.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; + +public abstract class AbstractVariableDeclaration extends Statement { + public int modifiers; + + public TypeReference type; + public Expression initialization; + + public char[] name; + public int declarationEnd; + public int declarationSourceStart; + public int declarationSourceEnd; + public int modifiersSourceStart; + + public AbstractVariableDeclaration() {} + + public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { + return flowInfo; + } + + public abstract String name(); + + public void resolve(BlockScope scope) {} + + public String toString(int tab) { + + String s = tabString(tab); + if (modifiers != AccDefault) { + s += modifiersString(modifiers); + } + s += type.toString(0) + " " + new String(name()); //$NON-NLS-1$ + if (initialization != null) + s += " = " + initialization.toStringExpression(tab); //$NON-NLS-1$ + return s; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AllocationExpression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AllocationExpression.java new file mode 100644 index 0000000..9e898ac --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AllocationExpression.java @@ -0,0 +1,290 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.InvocationSite; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.NestedTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SyntheticArgumentBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class AllocationExpression + extends Expression + implements InvocationSite { + + public TypeReference type; + public Expression[] arguments; + public MethodBinding binding; + + MethodBinding syntheticAccessor; + + public AllocationExpression() { + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + // check captured variables are initialized in current context (26134) + checkCapturedLocalInitializationIfNecessary(this.binding.declaringClass, currentScope, flowInfo); + + // process arguments + if (arguments != null) { + for (int i = 0, count = arguments.length; i < count; i++) { + flowInfo = + arguments[i] + .analyseCode(currentScope, flowContext, flowInfo) + .unconditionalInits(); + } + } + // record some dependency information for exception types + ReferenceBinding[] thrownExceptions; + if (((thrownExceptions = this.binding.thrownExceptions).length) != 0) { + // check exception handling + flowContext.checkExceptionHandlers( + thrownExceptions, + this, + flowInfo, + currentScope); + } + manageEnclosingInstanceAccessIfNecessary(currentScope); + manageSyntheticAccessIfNecessary(currentScope); + + return flowInfo; + } + + public void checkCapturedLocalInitializationIfNecessary(ReferenceBinding checkedType, BlockScope currentScope, FlowInfo flowInfo) { + + if (checkedType.isLocalType() + && !checkedType.isAnonymousType() + && !currentScope.isDefinedInType(checkedType)) { // only check external allocations + NestedTypeBinding nestedType = (NestedTypeBinding) checkedType; + SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables(); + if (syntheticArguments != null) + for (int i = 0, count = syntheticArguments.length; i < count; i++){ + SyntheticArgumentBinding syntheticArgument = syntheticArguments[i]; + LocalVariableBinding targetLocal; + if ((targetLocal = syntheticArgument.actualOuterLocalVariable) == null) continue; + if (targetLocal.declaration != null && !flowInfo.isDefinitelyAssigned(targetLocal)){ + currentScope.problemReporter().uninitializedLocalVariable(targetLocal, this); + } + } + + } + } + + public Expression enclosingInstance() { + return null; + } + +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// int pc = codeStream.position; +// ReferenceBinding allocatedType = binding.declaringClass; +// +// codeStream.new_(allocatedType); +// if (valueRequired) { +// codeStream.dup(); +// } +// // better highlight for allocation: display the type individually +// codeStream.recordPositionsFrom(pc, type.sourceStart); +// +// // handling innerclass instance allocation - enclosing instance arguments +// if (allocatedType.isNestedType()) { +// codeStream.generateSyntheticEnclosingInstanceValues( +// currentScope, +// allocatedType, +// enclosingInstance(), +// this); +// } +// // generate the arguments for constructor +// if (arguments != null) { +// for (int i = 0, count = arguments.length; i < count; i++) { +// arguments[i].generateCode(currentScope, codeStream, true); +// } +// } +// // handling innerclass instance allocation - outer local arguments +// if (allocatedType.isNestedType()) { +// codeStream.generateSyntheticOuterArgumentValues( +// currentScope, +// allocatedType, +// this); +// } +// // invoke constructor +// if (syntheticAccessor == null) { +// codeStream.invokespecial(binding); +// } else { +// // synthetic accessor got some extra arguments appended to its signature, which need values +// for (int i = 0, +// max = syntheticAccessor.parameters.length - binding.parameters.length; +// i < max; +// i++) { +// codeStream.aconst_null(); +// } +// codeStream.invokespecial(syntheticAccessor); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public boolean isSuperAccess() { + + return false; + } + + public boolean isTypeAccess() { + + return true; + } + + /* Inner emulation consists in either recording a dependency + * link only, or performing one level of propagation. + * + * Dependency mechanism is used whenever dealing with source target + * types, since by the time we reach them, we might not yet know their + * exact need. + */ + public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) { + + ReferenceBinding allocatedType; + + // perform some emulation work in case there is some and we are inside a local type only + if ((allocatedType = binding.declaringClass).isNestedType() + && currentScope.enclosingSourceType().isLocalType()) { + + if (allocatedType.isLocalType()) { + ((LocalTypeBinding) allocatedType).addInnerEmulationDependent(currentScope, false); + // request cascade of accesses + } else { + // locally propagate, since we already now the desired shape for sure + currentScope.propagateInnerEmulation(allocatedType, false); + // request cascade of accesses + } + } + } + + public void manageSyntheticAccessIfNecessary(BlockScope currentScope) { + + if (binding.isPrivate() + && (currentScope.enclosingSourceType() != binding.declaringClass)) { + +// if (currentScope +// .environment() +// .options +// .isPrivateConstructorAccessChangingVisibility) { +// binding.tagForClearingPrivateModifier(); +// // constructor will not be dumped as private, no emulation required thus +// } else { + syntheticAccessor = + ((SourceTypeBinding) binding.declaringClass).addSyntheticMethod(binding, isSuperAccess()); + currentScope.problemReporter().needToEmulateMethodAccess(binding, this); +// } + } + } + + public TypeBinding resolveType(BlockScope scope) { + + // Propagate the type checking to the arguments, and check if the constructor is defined. + constant = NotAConstant; + this.resolvedType = type.resolveType(scope); + // will check for null after args are resolved + + // buffering the arguments' types + TypeBinding[] argumentTypes = NoParameters; + if (arguments != null) { + boolean argHasError = false; + int length = arguments.length; + argumentTypes = new TypeBinding[length]; + for (int i = 0; i < length; i++) + if ((argumentTypes[i] = arguments[i].resolveType(scope)) == null) + argHasError = true; + if (argHasError) + return this.resolvedType; + } + if (this.resolvedType == null) + return null; + + if (!this.resolvedType.canBeInstantiated()) { + scope.problemReporter().cannotInstantiate(type, this.resolvedType); + return this.resolvedType; + } + ReferenceBinding allocatedType = (ReferenceBinding) this.resolvedType; + if (!(binding = scope.getConstructor(allocatedType, argumentTypes, this)) + .isValidBinding()) { + if (binding.declaringClass == null) + binding.declaringClass = allocatedType; + scope.problemReporter().invalidConstructor(this, binding); + return this.resolvedType; + } + if (isMethodUseDeprecated(binding, scope)) + scope.problemReporter().deprecatedMethod(binding, this); + + if (arguments != null) + for (int i = 0; i < arguments.length; i++) + arguments[i].implicitWidening(binding.parameters[i], argumentTypes[i]); + return allocatedType; + } + + public void setActualReceiverType(ReferenceBinding receiverType) { + // ignored + } + + public void setDepth(int i) { + // ignored + } + + public void setFieldIndex(int i) { + // ignored + } + + public String toStringExpression() { + + String s = "new " + type.toString(0); //$NON-NLS-1$ + if (arguments == null) + s = s + "()"; //$NON-NLS-1$ + else { + s = s + "("; //$NON-NLS-1$ + for (int i = 0; i < arguments.length; i++) { + s = s + arguments[i].toStringExpression(); + if (i == (arguments.length - 1)) + s = s + ")"; //$NON-NLS-1$ + else + s = s + ", "; //$NON-NLS-1$ + } + } + return s; + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + int argumentsLength; + type.traverse(visitor, scope); + if (arguments != null) { + argumentsLength = arguments.length; + for (int i = 0; i < argumentsLength; i++) + arguments[i].traverse(visitor, scope); + } + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AnonymousLocalTypeDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AnonymousLocalTypeDeclaration.java new file mode 100644 index 0000000..21793c9 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AnonymousLocalTypeDeclaration.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; +import net.sourceforge.phpdt.internal.compiler.problem.AbortType; + +public class AnonymousLocalTypeDeclaration extends LocalTypeDeclaration { + + public static final char[] ANONYMOUS_EMPTY_NAME = new char[] {}; + public QualifiedAllocationExpression allocation; + + public AnonymousLocalTypeDeclaration(CompilationResult compilationResult) { + super(compilationResult); + modifiers = AccDefault; + name = ANONYMOUS_EMPTY_NAME; + } + + // use a default name in order to th name lookup + // to operate just like a regular type (which has a name) + //without checking systematically if the naem is null .... + public MethodBinding createsInternalConstructorWithBinding(MethodBinding inheritedConstructorBinding) { + + //Add to method'set, the default constuctor that just recall the + //super constructor with the same arguments + String baseName = "$anonymous"; //$NON-NLS-1$ + TypeBinding[] argumentTypes = inheritedConstructorBinding.parameters; + int argumentsLength = argumentTypes.length; + //the constructor + ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationResult); + cd.selector = new char[] { 'x' }; //no maining + cd.sourceStart = sourceStart; + cd.sourceEnd = sourceEnd; + cd.modifiers = modifiers & AccVisibilityMASK; + cd.isDefaultConstructor = true; + + if (argumentsLength > 0) { + Argument[] arguments = (cd.arguments = new Argument[argumentsLength]); + for (int i = argumentsLength; --i >= 0;) { + arguments[i] = new Argument((baseName + i).toCharArray(), 0L, null /*type ref*/, AccDefault); + } + } + + //the super call inside the constructor + cd.constructorCall = SuperReference.implicitSuperConstructorCall(); + cd.constructorCall.sourceStart = sourceStart; + cd.constructorCall.sourceEnd = sourceEnd; + + if (argumentsLength > 0) { + Expression[] args; + args = cd.constructorCall.arguments = new Expression[argumentsLength]; + for (int i = argumentsLength; --i >= 0;) { + args[i] = new SingleNameReference((baseName + i).toCharArray(), 0L); + } + } + + //adding the constructor in the methods list + if (methods == null) { + methods = new AbstractMethodDeclaration[] { cd }; + } else { + AbstractMethodDeclaration[] newMethods; + System.arraycopy( + methods, + 0, + newMethods = new AbstractMethodDeclaration[methods.length + 1], + 1, + methods.length); + newMethods[0] = cd; + methods = newMethods; + } + + //============BINDING UPDATE========================== + cd.binding = new MethodBinding( + cd.modifiers, //methodDeclaration + argumentsLength == 0 ? NoParameters : argumentTypes, //arguments bindings + inheritedConstructorBinding.thrownExceptions, //exceptions + binding); //declaringClass + + cd.scope = new MethodScope(scope, cd, true); + cd.bindArguments(); + cd.constructorCall.resolve(cd.scope); + + if (binding.methods == null) { + binding.methods = new MethodBinding[] { cd.binding }; + } else { + MethodBinding[] newMethods; + System.arraycopy( + binding.methods, + 0, + newMethods = new MethodBinding[binding.methods.length + 1], + 1, + binding.methods.length); + newMethods[0] = cd.binding; + binding.methods = newMethods; + } + //=================================================== + + return cd.binding; + + } + public void resolve(BlockScope scope) { + + if (binding != null) { + // remember local types binding for innerclass emulation propagation + scope.referenceCompilationUnit().record((LocalTypeBinding)binding); + } + // scope and binding are provided in updateBindingSuperclass + resolve(); + updateMaxFieldCount(); + } + + public String toString(int tab) { + + return toStringBody(tab); + } + + /** + * Iteration for a local anonymous innertype + * + */ + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (ignoreFurtherInvestigation) + return; + try { + if (visitor.visit(this, blockScope)) { + + int fieldsLength; + int methodsLength; + int memberTypesLength; + + // is bound to the actual type from the allocation expression + // therefore it has already been iterated at this point. + + if (memberTypes != null) { + memberTypesLength = memberTypes.length; + for (int i = 0; i < memberTypesLength; i++) + memberTypes[i].traverse(visitor, scope); + } + if (fields != null) { + fieldsLength = fields.length; + for (int i = 0; i < fieldsLength; i++) { + FieldDeclaration field; + if ((field = fields[i]).isStatic()) { + // local type cannot have static fields + } else { + field.traverse(visitor, initializerScope); + } + } + } + if (methods != null) { + methodsLength = methods.length; + for (int i = 0; i < methodsLength; i++) + methods[i].traverse(visitor, scope); + } + } + visitor.endVisit(this, blockScope); + } catch (AbortType e) { + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Argument.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Argument.java new file mode 100644 index 0000000..f803c13 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Argument.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class Argument extends LocalDeclaration { + + public Argument(char[] name, long posNom, TypeReference tr, int modifiers) { + + super(null, name, (int) (posNom >>> 32), (int) posNom); + this.declarationSourceEnd = (int) posNom; + this.modifiers = modifiers; + type = tr; + this.bits |= IsLocalDeclarationReachableMASK; + } + + public void bind(MethodScope scope, TypeBinding typeBinding, boolean used) { + + if (this.type != null) + this.type.resolvedType = typeBinding; + // record the resolved type into the type reference + int modifierFlag = this.modifiers; + if ((this.binding = scope.duplicateName(this.name)) != null) { + //the name already exist....may carry on with the first binding .... + scope.problemReporter().redefineArgument(this); + } else { + scope.addLocalVariable( + this.binding = + new LocalVariableBinding(this, typeBinding, modifierFlag, true)); + //true stand for argument instead of just local + if (typeBinding != null && isTypeUseDeprecated(typeBinding, scope)) + scope.problemReporter().deprecatedType(typeBinding, this.type); + this.binding.declaration = this; + this.binding.useFlag = used ? LocalVariableBinding.USED : LocalVariableBinding.UNUSED; + } + } + + public TypeBinding resolveForCatch(BlockScope scope) { + + // resolution on an argument of a catch clause + // provide the scope with a side effect : insertion of a LOCAL + // that represents the argument. The type must be from JavaThrowable + + TypeBinding tb = type.resolveTypeExpecting(scope, scope.getJavaLangThrowable()); + if (tb == null) + return null; + if ((binding = scope.duplicateName(name)) != null) { + // the name already exists....may carry on with the first binding .... + scope.problemReporter().redefineArgument(this); + return null; + } + binding = new LocalVariableBinding(this, tb, modifiers, false); // argument decl, but local var (where isArgument = false) + scope.addLocalVariable(binding); + binding.constant = NotAConstant; + return tb; + } + + public String toString(int tab) { + + String s = ""; //$NON-NLS-1$ + if (modifiers != AccDefault) { + s += modifiersString(modifiers); + } + if (type == null) { + s += " "; //$NON-NLS-1$ + } else { + s += type.toString(tab) + " "; //$NON-NLS-1$ + } + s += new String(name); + return s; + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + if (type != null) + type.traverse(visitor, scope); + if (initialization != null) + initialization.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayAllocationExpression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayAllocationExpression.java new file mode 100644 index 0000000..93a145a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayAllocationExpression.java @@ -0,0 +1,186 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public class ArrayAllocationExpression extends Expression { + + public TypeReference type; + + //dimensions.length gives the number of dimensions, but the + // last ones may be nulled as in new int[4][5][][] + public Expression[] dimensions; + public ArrayInitializer initializer; + + /** + * ArrayAllocationExpression constructor comment. + */ + public ArrayAllocationExpression() { + super(); + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + for (int i = 0, max = dimensions.length; i < max; i++) { + Expression dim; + if ((dim = dimensions[i]) != null) { + flowInfo = dim.analyseCode(currentScope, flowContext, flowInfo); + } + } + if (initializer != null) { + return initializer.analyseCode(currentScope, flowContext, flowInfo); + } else { + return flowInfo; + } + } + + /** + * Code generation for a array allocation expression + */ +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// int pc = codeStream.position; +// +// if (initializer != null) { +// initializer.generateCode(currentScope, codeStream, valueRequired); +// return; +// } +// +// int nonNullDimensionsLength = 0; +// for (int i = 0, max = dimensions.length; i < max; i++) +// if (dimensions[i] != null) { +// dimensions[i].generateCode(currentScope, codeStream, true); +// nonNullDimensionsLength++; +// } +// +// // Generate a sequence of bytecodes corresponding to an array allocation +// if (this.resolvedType.dimensions() == 1) { +// // Mono-dimensional array +// codeStream.newArray(currentScope, (ArrayBinding)this.resolvedType); +// } else { +// // Multi-dimensional array +// codeStream.multianewarray(this.resolvedType, nonNullDimensionsLength); +// } +// +// if (valueRequired) { +// codeStream.generateImplicitConversion(implicitConversion); +// } else { +// codeStream.pop(); +// } +// +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public TypeBinding resolveType(BlockScope scope) { + + // Build an array type reference using the current dimensions + // The parser does not check for the fact that dimension may be null + // only at the -end- like new int [4][][]. The parser allows new int[][4][] + // so this must be checked here......(this comes from a reduction to LL1 grammar) + + TypeBinding referenceType = type.resolveType(scope); + + // will check for null after dimensions are checked + constant = Constant.NotAConstant; + if (referenceType == VoidBinding) { + scope.problemReporter().cannotAllocateVoidArray(this); + referenceType = null; + } + + // check the validity of the dimension syntax (and test for all null dimensions) + int explicitDimIndex = -1; + for (int i = dimensions.length; --i >= 0;) { + if (dimensions[i] != null) { + if (explicitDimIndex < 0) explicitDimIndex = i; + } else if (explicitDimIndex> 0) { + // should not have an empty dimension before an non-empty one + scope.problemReporter().incorrectLocationForEmptyDimension(this, i); + } + } + + // explicitDimIndex < 0 says if all dimensions are nulled + // when an initializer is given, no dimension must be specified + if (initializer == null) { + if (explicitDimIndex < 0) { + scope.problemReporter().mustDefineDimensionsOrInitializer(this); + } + } else if (explicitDimIndex >= 0) { + scope.problemReporter().cannotDefineDimensionsAndInitializer(this); + } + + // dimensions resolution + for (int i = 0; i <= explicitDimIndex; i++) { + if (dimensions[i] != null) { + TypeBinding dimensionType = dimensions[i].resolveTypeExpecting(scope, IntBinding); + if (dimensionType != null) { + dimensions[i].implicitWidening(IntBinding, dimensionType); + } + } + } + + // building the array binding + if (referenceType != null) { + if (dimensions.length > 255) { + scope.problemReporter().tooManyDimensions(this); + } + this.resolvedType = scope.createArray(referenceType, dimensions.length); + + // check the initializer + if (initializer != null) { + if ((initializer.resolveTypeExpecting(scope, this.resolvedType)) != null) + initializer.binding = (ArrayBinding)this.resolvedType; + } + } + return this.resolvedType; + } + + public String toStringExpression() { + + String s = "new " + type.toString(0); //$NON-NLS-1$ + for (int i = 0; i < dimensions.length; i++) { + if (dimensions[i] == null) + s = s + "[]"; //$NON-NLS-1$ + else + s = s + "[" + dimensions[i].toStringExpression() + "]"; //$NON-NLS-2$ //$NON-NLS-1$ + } + if (initializer != null) + s = s + initializer.toStringExpression(); + return s; + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + int dimensionsLength = dimensions.length; + type.traverse(visitor, scope); + for (int i = 0; i < dimensionsLength; i++) { + if (dimensions[i] != null) + dimensions[i].traverse(visitor, scope); + } + if (initializer != null) + initializer.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayInitializer.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayInitializer.java new file mode 100644 index 0000000..9fe1e25 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayInitializer.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BaseTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class ArrayInitializer extends Expression { + public Expression[] expressions; + public ArrayBinding binding; //the type of the { , , , } + +/** + * ArrayInitializer constructor comment. + */ +public ArrayInitializer() { + super(); +} +public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { + if (expressions != null) { + for (int i = 0, max = expressions.length; i < max; i++) { + flowInfo = expressions[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits(); + } + } + return flowInfo; +} +/** + * Code generation for a array initializer + */ +//public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { +// // Flatten the values and compute the dimensions, by iterating in depth into nested array initializers +// +// int pc = codeStream.position; +// int expressionLength = (expressions == null) ? 0: expressions.length; +// codeStream.generateInlinedValue(expressionLength); +// codeStream.newArray(currentScope, binding); +// if (expressions != null) { +// // binding is an ArrayType, so I can just deal with the dimension +// int elementsTypeID = binding.dimensions > 1 ? -1 : binding.leafComponentType.id; +// for (int i = 0; i < expressionLength; i++) { +// Expression expr; +// if ((expr = expressions[i]).constant != NotAConstant) { +// switch (elementsTypeID) { // filter out initializations to default values +// case T_int : +// case T_short : +// case T_byte : +// case T_char : +// case T_long : +// if (expr.constant.longValue() != 0) { +// codeStream.dup(); +// codeStream.generateInlinedValue(i); +// expr.generateCode(currentScope, codeStream, true); +// codeStream.arrayAtPut(elementsTypeID, false); +// } +// break; +// case T_float : +// case T_double : +// double constantValue = expr.constant.doubleValue(); +// if (constantValue == -0.0 || constantValue != 0) { +// codeStream.dup(); +// codeStream.generateInlinedValue(i); +// expr.generateCode(currentScope, codeStream, true); +// codeStream.arrayAtPut(elementsTypeID, false); +// } +// break; +// case T_boolean : +// if (expr.constant.booleanValue() != false) { +// codeStream.dup(); +// codeStream.generateInlinedValue(i); +// expr.generateCode(currentScope, codeStream, true); +// codeStream.arrayAtPut(elementsTypeID, false); +// } +// break; +// default : +// if (!(expr instanceof NullLiteral)) { +// codeStream.dup(); +// codeStream.generateInlinedValue(i); +// expr.generateCode(currentScope, codeStream, true); +// codeStream.arrayAtPut(elementsTypeID, false); +// } +// } +// } else if (!(expr instanceof NullLiteral)) { +// codeStream.dup(); +// codeStream.generateInlinedValue(i); +// expr.generateCode(currentScope, codeStream, true); +// codeStream.arrayAtPut(elementsTypeID, false); +// } +// } +// } +// if (!valueRequired) { +// codeStream.pop(); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +public TypeBinding resolveTypeExpecting(BlockScope scope, TypeBinding expectedTb) { + // Array initializers can only occur on the right hand side of an assignment + // expression, therefore the expected type contains the valid information + // concerning the type that must be enforced by the elements of the array initializer. + + // this method is recursive... (the test on isArrayType is the stop case) + + constant = NotAConstant; + if (expectedTb.isArrayType()) { + binding = (ArrayBinding) expectedTb; + if (expressions == null) + return binding; + TypeBinding expectedElementsTb = binding.elementsType(scope); + if (expectedElementsTb.isBaseType()) { + for (int i = 0, length = expressions.length; i < length; i++) { + Expression expression = expressions[i]; + TypeBinding expressionTb = + (expression instanceof ArrayInitializer) + ? expression.resolveTypeExpecting(scope, expectedElementsTb) + : expression.resolveType(scope); + if (expressionTb == null) + return null; + + // Compile-time conversion required? + if (expression.isConstantValueOfTypeAssignableToType(expressionTb, expectedElementsTb)) { + expression.implicitWidening(expectedElementsTb, expressionTb); + } else if (BaseTypeBinding.isWidening(expectedElementsTb.id, expressionTb.id)) { + expression.implicitWidening(expectedElementsTb, expressionTb); + } else { + scope.problemReporter().typeMismatchErrorActualTypeExpectedType(expression, expressionTb, expectedElementsTb); + return null; + } + } + } else { + for (int i = 0, length = expressions.length; i < length; i++) + if (expressions[i].resolveTypeExpecting(scope, expectedElementsTb) == null) + return null; + } + return binding; + } + + // infer initializer type for error reporting based on first element + TypeBinding leafElementType = null; + int dim = 1; + if (expressions == null) { + leafElementType = scope.getJavaLangObject(); + } else { + Expression currentExpression = expressions[0]; + while(currentExpression != null && currentExpression instanceof ArrayInitializer) { + dim++; + Expression[] subExprs = ((ArrayInitializer) currentExpression).expressions; + if (subExprs == null){ + leafElementType = scope.getJavaLangObject(); + currentExpression = null; + break; + } + currentExpression = ((ArrayInitializer) currentExpression).expressions[0]; + } + if (currentExpression != null) { + leafElementType = currentExpression.resolveType(scope); + } + } + if (leafElementType != null) { + TypeBinding probableTb = scope.createArray(leafElementType, dim); + scope.problemReporter().typeMismatchErrorActualTypeExpectedType(this, probableTb, expectedTb); + } + return null; +} +public String toStringExpression() { + + String s = "{" ; //$NON-NLS-1$ + if (expressions != null) + { int j = 20 ; + for (int i = 0 ; i < expressions.length ; i++) + { s = s + expressions[i].toStringExpression() + "," ; //$NON-NLS-1$ + j -- ; + if (j == 0) + { s = s + "\n "; j = 20;}}}; //$NON-NLS-1$ + s = s + "}"; //$NON-NLS-1$ + return s;} + +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + if (visitor.visit(this, scope)) { + if (expressions != null) { + int expressionsLength = expressions.length; + for (int i = 0; i < expressionsLength; i++) + expressions[i].traverse(visitor, scope); + } + } + visitor.endVisit(this, scope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayQualifiedTypeReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayQualifiedTypeReference.java new file mode 100644 index 0000000..da3ade9 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayQualifiedTypeReference.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope; +import net.sourceforge.phpdt.internal.compiler.lookup.Scope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class ArrayQualifiedTypeReference extends QualifiedTypeReference { + int dimensions; +public ArrayQualifiedTypeReference(char[][] sources , int dim, long[] poss) { + super( sources , poss); + dimensions = dim ; +} +public ArrayQualifiedTypeReference(char[][] sources , TypeBinding tb, int dim, long[] poss) { + super( sources , tb, poss); + dimensions = dim ; +} +public int dimensions() { + return dimensions; +} +public TypeBinding getTypeBinding(Scope scope) { + if (this.resolvedType != null) + return this.resolvedType; + if (dimensions > 255) { + scope.problemReporter().tooManyDimensions(this); + } + return scope.createArray(scope.getType(tokens), dimensions); +} +public String toStringExpression(int tab){ + /* slow speed */ + + String s = super.toStringExpression(tab) ; + if (dimensions == 1 ) return s + "[]" ; //$NON-NLS-1$ + for (int i=1 ; i <= dimensions ; i++) + s = s + "[]" ; //$NON-NLS-1$ + return s ; +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayReference.java new file mode 100644 index 0000000..ee45ff3 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayReference.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class ArrayReference extends Reference { + + public Expression receiver; + public Expression position; + + public ArrayReference(Expression rec, Expression pos) { + this.receiver = rec; + this.position = pos; + sourceStart = rec.sourceStart; + } + + public FlowInfo analyseAssignment( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo, + Assignment assignment, + boolean compoundAssignment) { + + if (assignment.expression == null) { + return analyseCode(currentScope, flowContext, flowInfo).unconditionalInits(); + } else { + return assignment + .expression + .analyseCode( + currentScope, + flowContext, + analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()) + .unconditionalInits(); + } + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + return position.analyseCode( + currentScope, + flowContext, + receiver.analyseCode(currentScope, flowContext, flowInfo)); + } + +// public void generateAssignment( +// BlockScope currentScope, +// CodeStream codeStream, +// Assignment assignment, +// boolean valueRequired) { +// +// receiver.generateCode(currentScope, codeStream, true); +// position.generateCode(currentScope, codeStream, true); +// assignment.expression.generateCode(currentScope, codeStream, true); +// codeStream.arrayAtPut(this.resolvedType.id, valueRequired); +// if (valueRequired) { +// codeStream.generateImplicitConversion(assignment.implicitConversion); +// } +// } + + /** + * Code generation for a array reference + */ +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// int pc = codeStream.position; +// receiver.generateCode(currentScope, codeStream, true); +// position.generateCode(currentScope, codeStream, true); +// codeStream.arrayAt(this.resolvedType.id); +// // Generating code for the potential runtime type checking +// if (valueRequired) { +// codeStream.generateImplicitConversion(implicitConversion); +// } else { +// if (this.resolvedType == LongBinding +// || this.resolvedType == DoubleBinding) { +// codeStream.pop2(); +// } else { +// codeStream.pop(); +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } +// +// public void generateCompoundAssignment( +// BlockScope currentScope, +// CodeStream codeStream, +// Expression expression, +// int operator, +// int assignmentImplicitConversion, +// boolean valueRequired) { +// +// receiver.generateCode(currentScope, codeStream, true); +// position.generateCode(currentScope, codeStream, true); +// codeStream.dup2(); +// codeStream.arrayAt(this.resolvedType.id); +// int operationTypeID; +// if ((operationTypeID = implicitConversion >> 4) == T_String) { +// codeStream.generateStringAppend(currentScope, null, expression); +// } else { +// // promote the array reference to the suitable operation type +// codeStream.generateImplicitConversion(implicitConversion); +// // generate the increment value (will by itself be promoted to the operation value) +// if (expression == IntLiteral.One) { // prefix operation +// codeStream.generateConstant(expression.constant, implicitConversion); +// } else { +// expression.generateCode(currentScope, codeStream, true); +// } +// // perform the operation +// codeStream.sendOperator(operator, operationTypeID); +// // cast the value back to the array reference type +// codeStream.generateImplicitConversion(assignmentImplicitConversion); +// } +// codeStream.arrayAtPut(this.resolvedType.id, valueRequired); +// } +// +// public void generatePostIncrement( +// BlockScope currentScope, +// CodeStream codeStream, +// CompoundAssignment postIncrement, +// boolean valueRequired) { +// +// receiver.generateCode(currentScope, codeStream, true); +// position.generateCode(currentScope, codeStream, true); +// codeStream.dup2(); +// codeStream.arrayAt(this.resolvedType.id); +// if (valueRequired) { +// if ((this.resolvedType == LongBinding) +// || (this.resolvedType == DoubleBinding)) { +// codeStream.dup2_x2(); +// } else { +// codeStream.dup_x2(); +// } +// } +// codeStream.generateConstant( +// postIncrement.expression.constant, +// implicitConversion); +// codeStream.sendOperator(postIncrement.operator, this.resolvedType.id); +// codeStream.generateImplicitConversion( +// postIncrement.assignmentImplicitConversion); +// codeStream.arrayAtPut(this.resolvedType.id, false); +// } + + public TypeBinding resolveType(BlockScope scope) { + + constant = Constant.NotAConstant; + TypeBinding arrayType = receiver.resolveType(scope); + if (arrayType != null) { + if (arrayType.isArrayType()) { + this.resolvedType = ((ArrayBinding) arrayType).elementsType(scope); + } else { + scope.problemReporter().referenceMustBeArrayTypeAt(arrayType, this); + } + } + TypeBinding positionType = position.resolveTypeExpecting(scope, IntBinding); + if (positionType != null) { + position.implicitWidening(IntBinding, positionType); + } + return this.resolvedType; + } + + public String toStringExpression() { + + return receiver.toStringExpression() + "[" //$NON-NLS-1$ + +position.toStringExpression() + "]"; //$NON-NLS-1$ + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + receiver.traverse(visitor, scope); + position.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayTypeReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayTypeReference.java new file mode 100644 index 0000000..15930a5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ArrayTypeReference.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.Scope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class ArrayTypeReference extends SingleTypeReference { + public int dimensions; +/** + * ArrayTypeReference constructor comment. + * @param source char[] + * @param dim int + * @param pos int + */ +public ArrayTypeReference(char[] source, int dim, long pos) { + super(source, pos); + dimensions = dim ; +} +public ArrayTypeReference(char[] source, TypeBinding tb, int dim, long pos) { + super(source, tb, pos); + dimensions = dim ;} +public int dimensions() { + return dimensions; +} +public TypeBinding getTypeBinding(Scope scope) { + if (this.resolvedType != null) + return this.resolvedType; + if (dimensions > 255) { + scope.problemReporter().tooManyDimensions(this); + } + return scope.createArray(scope.getType(token), dimensions); + +} +public String toStringExpression(int tab){ + + String s = super.toStringExpression(tab) ; + if (dimensions == 1 ) return s + "[]" ; //$NON-NLS-1$ + for (int i=1 ; i <= dimensions ; i++) + s = s + "[]" ; //$NON-NLS-1$ + return s ; +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AssertStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AssertStatement.java new file mode 100644 index 0000000..1d42371 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AssertStatement.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class AssertStatement extends Statement { + + public Expression assertExpression, exceptionArgument; + + // for local variable attribute + int preAssertInitStateIndex = -1; + private FieldBinding assertionSyntheticFieldBinding; + + public AssertStatement( + Expression exceptionArgument, + Expression assertExpression, + int startPosition) { + + this.assertExpression = assertExpression; + this.exceptionArgument = exceptionArgument; + sourceStart = startPosition; + sourceEnd = exceptionArgument.sourceEnd; + } + + public AssertStatement(Expression assertExpression, int startPosition) { + + this.assertExpression = assertExpression; + sourceStart = startPosition; + sourceEnd = assertExpression.sourceEnd; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + preAssertInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo); + + Constant cst = this.assertExpression.optimizedBooleanConstant(); + boolean isOptimizedTrueAssertion = cst != NotAConstant && cst.booleanValue() == true; + boolean isOptimizedFalseAssertion = cst != NotAConstant && cst.booleanValue() == false; + + FlowInfo assertInfo = flowInfo.copy(); + if (isOptimizedTrueAssertion) { + assertInfo.setReachMode(FlowInfo.UNREACHABLE); + } + assertInfo = assertExpression.analyseCode(currentScope, flowContext, assertInfo).unconditionalInits(); + + if (exceptionArgument != null) { + // only gets evaluated when escaping - results are not taken into account + FlowInfo exceptionInfo = exceptionArgument.analyseCode(currentScope, flowContext, assertInfo.copy()); + + if (!isOptimizedTrueAssertion){ + flowContext.checkExceptionHandlers( + currentScope.getJavaLangAssertionError(), + this, + exceptionInfo, + currentScope); + } + } + + // add the assert support in the clinit + manageSyntheticAccessIfNecessary(currentScope); + if (isOptimizedFalseAssertion) { + return flowInfo; // if assertions are enabled, the following code will be unreachable + } else { + return flowInfo.mergedWith(assertInfo.unconditionalInits()); + } + } + +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// +// if (this.assertionSyntheticFieldBinding != null) { +// Label assertionActivationLabel = new Label(codeStream); +// codeStream.getstatic(this.assertionSyntheticFieldBinding); +// codeStream.ifne(assertionActivationLabel); +// Label falseLabel = new Label(codeStream); +// assertExpression.generateOptimizedBoolean(currentScope, codeStream, (falseLabel = new Label(codeStream)), null , true); +// codeStream.newJavaLangAssertionError(); +// codeStream.dup(); +// if (exceptionArgument != null) { +// exceptionArgument.generateCode(currentScope, codeStream, true); +// codeStream.invokeJavaLangAssertionErrorConstructor(exceptionArgument.implicitConversion & 0xF); +// } else { +// codeStream.invokeJavaLangAssertionErrorDefaultConstructor(); +// } +// codeStream.athrow(); +// falseLabel.place(); +// assertionActivationLabel.place(); +// } +// +// // May loose some local variable initializations : affecting the local variable attributes +// if (preAssertInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables(currentScope, preAssertInitStateIndex); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public void resolve(BlockScope scope) { + + assertExpression.resolveTypeExpecting(scope, BooleanBinding); + if (exceptionArgument != null) { + TypeBinding exceptionArgumentType = exceptionArgument.resolveType(scope); + if (exceptionArgumentType != null){ + if (exceptionArgumentType.id == T_void){ + scope.problemReporter().illegalVoidExpression(exceptionArgument); + } + exceptionArgument.implicitConversion = (exceptionArgumentType.id << 4) + exceptionArgumentType.id; + } + } + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + assertExpression.traverse(visitor, scope); + if (exceptionArgument != null) { + exceptionArgument.traverse(visitor, scope); + } + } + visitor.endVisit(this, scope); + } + + public void manageSyntheticAccessIfNecessary(BlockScope currentScope) { + + // need assertion flag: $assertionsDisabled on outer most source clas + // (in case of static member of interface, will use the outermost static member - bug 22334) + SourceTypeBinding outerMostClass = currentScope.enclosingSourceType(); + while (outerMostClass.isLocalType()){ + ReferenceBinding enclosing = outerMostClass.enclosingType(); + if (enclosing == null || enclosing.isInterface()) break; + outerMostClass = (SourceTypeBinding) enclosing; + } + + this.assertionSyntheticFieldBinding = outerMostClass.addSyntheticField(this, currentScope); + + // find and enable assertion support + TypeDeclaration typeDeclaration = outerMostClass.scope.referenceType(); + AbstractMethodDeclaration[] methods = typeDeclaration.methods; + for (int i = 0, max = methods.length; i < max; i++) { + AbstractMethodDeclaration method = methods[i]; + if (method.isClinit()) { + ((Clinit) method).addSupportForAssertion(assertionSyntheticFieldBinding); + break; + } + } + } + + public String toString(int tab) { + + StringBuffer buffer = new StringBuffer(tabString(tab)); + buffer.append("assert "); //$NON-NLS-1$ + buffer.append(this.assertExpression); + if (this.exceptionArgument != null) { + buffer.append(":"); //$NON-NLS-1$ + buffer.append(this.exceptionArgument); + buffer.append(";"); //$NON-NLS-1$ + } + return buffer.toString(); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Assignment.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Assignment.java new file mode 100644 index 0000000..4950b2b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Assignment.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Genady Beriozkin - added support for reporting assignment with no effect + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BaseTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.Binding; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class Assignment extends Expression { + + public Expression lhs; + public Expression expression; + + public Assignment(Expression lhs, Expression expression, int sourceEnd) { + //lhs is always a reference by construction , + //but is build as an expression ==> the checkcast cannot fail + + this.lhs = lhs; + lhs.bits |= IsStrictlyAssignedMASK; // tag lhs as assigned + + this.expression = expression; + + this.sourceStart = lhs.sourceStart; + this.sourceEnd = sourceEnd; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + // record setting a variable: various scenarii are possible, setting an array reference, + // a field reference, a blank final field reference, a field of an enclosing instance or + // just a local variable. + + return ((Reference) lhs) + .analyseAssignment(currentScope, flowContext, flowInfo, this, false) + .unconditionalInits(); + } + + void checkAssignmentEffect(BlockScope scope) { + + Binding left = getDirectBinding(this.lhs); + if (left != null && left == getDirectBinding(this.expression)) { + scope.problemReporter().assignmentHasNoEffect(this, left.shortReadableName()); + this.bits |= IsAssignmentWithNoEffectMASK; // record assignment has no effect + } + } + +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// // various scenarii are possible, setting an array reference, +// // a field reference, a blank final field reference, a field of an enclosing instance or +// // just a local variable. +// +// int pc = codeStream.position; +// if ((this.bits & IsAssignmentWithNoEffectMASK) != 0) { +// if (valueRequired) { +// this.expression.generateCode(currentScope, codeStream, true); +// } +// } else { +// ((Reference) lhs).generateAssignment(currentScope, codeStream, this, valueRequired); +// // variable may have been optimized out +// // the lhs is responsible to perform the implicitConversion generation for the assignment since optimized for unused local assignment. +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + Binding getDirectBinding(Expression someExpression) { + if (someExpression instanceof SingleNameReference) { + return ((SingleNameReference)someExpression).binding; + } else if (someExpression instanceof FieldReference) { + FieldReference fieldRef = (FieldReference)someExpression; + if (fieldRef.receiver.isThis() && !(fieldRef.receiver instanceof QualifiedThisReference)) { + return fieldRef.binding; + } + } + return null; + } + + public TypeBinding resolveType(BlockScope scope) { + + // due to syntax lhs may be only a NameReference, a FieldReference or an ArrayReference + constant = NotAConstant; + if (!(this.lhs instanceof Reference)) { + scope.problemReporter().expressionShouldBeAVariable(this.lhs); + } + this.resolvedType = lhs.resolveType(scope); // expressionType contains the assignment type (lhs Type) + TypeBinding rhsType = expression.resolveType(scope); + if (this.resolvedType == null || rhsType == null) { + return null; + } + checkAssignmentEffect(scope); + + // Compile-time conversion of base-types : implicit narrowing integer into byte/short/character + // may require to widen the rhs expression at runtime + if ((expression.isConstantValueOfTypeAssignableToType(rhsType, this.resolvedType) + || (this.resolvedType.isBaseType() && BaseTypeBinding.isWidening(this.resolvedType.id, rhsType.id))) + || rhsType.isCompatibleWith(this.resolvedType)) { + expression.implicitWidening(this.resolvedType, rhsType); + return this.resolvedType; + } + scope.problemReporter().typeMismatchErrorActualTypeExpectedType( + expression, + rhsType, + this.resolvedType); + return this.resolvedType; + } + + public String toString(int tab) { + + //no () when used as a statement + return tabString(tab) + toStringExpressionNoParenthesis(); + } + + public String toStringExpression() { + + //subclass redefine toStringExpressionNoParenthesis() + return "(" + toStringExpressionNoParenthesis() + ")"; //$NON-NLS-2$ //$NON-NLS-1$ + } + + public String toStringExpressionNoParenthesis() { + + return lhs.toStringExpression() + " " //$NON-NLS-1$ + + "=" //$NON-NLS-1$ + + ((expression.constant != null) && (expression.constant != NotAConstant) + ? " /*cst:" + expression.constant.toString() + "*/ " //$NON-NLS-1$ //$NON-NLS-2$ + : " ") //$NON-NLS-1$ + + expression.toStringExpression(); + } + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + lhs.traverse(visitor, scope); + expression.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AstNode.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AstNode.java new file mode 100644 index 0000000..1d4b920 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/AstNode.java @@ -0,0 +1,266 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BaseTypes; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.Scope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeIds; + + +public abstract class AstNode implements BaseTypes, CompilerModifiers, TypeConstants, TypeIds { + + public int sourceStart, sourceEnd; + + //some global provision for the hierarchy + public final static Constant NotAConstant = Constant.NotAConstant; + + // storage for internal flags (32 bits) BIT USAGE + public final static int Bit1 = 0x1; // return type (operators) | name reference kind (name ref) | add assertion (type decl) + public final static int Bit2 = 0x2; // return type (operators) | name reference kind (name ref) | has local type (type, method, field decl) + public final static int Bit3 = 0x4; // return type (operators) | name reference kind (name ref) | implicit this (this ref) + public final static int Bit4 = 0x8; // return type (operators) | first assignment to local (local decl) + public final static int Bit5 = 0x10; // value for return (binary expression) | + public final static int Bit6 = 0x20; // depth (name ref, msg) | only value required (binary expression) + public final static int Bit7 = 0x40; // depth (name ref, msg) | operator (operators) + public final static int Bit8 = 0x80; // depth (name ref, msg) | operator (operators) + public final static int Bit9 = 0x100; // depth (name ref, msg) | operator (operators) + public final static int Bit10= 0x200; // depth (name ref, msg) | operator (operators) + public final static int Bit11 = 0x400; // depth (name ref, msg) | operator (operators) + public final static int Bit12 = 0x800; // depth (name ref, msg) | operator (operators) + public final static int Bit13 = 0x1000; // depth (name ref, msg) + public final static int Bit14 = 0x2000; // assigned (reference lhs) + public final static int Bit15 = 0x4000; + public final static int Bit16 = 0x8000; + public final static int Bit17 = 0x10000; + public final static int Bit18 = 0x20000; + public final static int Bit19 = 0x40000; + public final static int Bit20 = 0x80000; + public final static int Bit21 = 0x100000; + public final static int Bit22 = 0x200000; // parenthesis count (expression) + public final static int Bit23 = 0x400000; // parenthesis count (expression) + public final static int Bit24 = 0x800000; // parenthesis count (expression) + public final static int Bit25 = 0x1000000; // parenthesis count (expression) + public final static int Bit26 = 0x2000000; // parenthesis count (expression) + public final static int Bit27 = 0x4000000; // parenthesis count (expression) + public final static int Bit28 = 0x8000000; // parenthesis count (expression) + public final static int Bit29 = 0x10000000; // parenthesis count (expression) + public final static int Bit30 = 0x20000000; // assignment with no effect (assignment) + public final static int Bit31 = 0x40000000; // local declaration reachable (local decl) + public final static int Bit32 = 0x80000000; // reachable (statement) + + public int bits = IsReachableMASK; // reachable by default + + // for operators + public static final int ReturnTypeIDMASK = Bit1|Bit2|Bit3|Bit4; + public static final int OperatorSHIFT = 6; // Bit7 -> Bit12 + public static final int OperatorMASK = Bit7|Bit8|Bit9|Bit10|Bit11|Bit12; // 6 bits for operator ID + + // for binary expressions + public static final int ValueForReturnMASK = Bit5; + public static final int OnlyValueRequiredMASK = Bit6; + + // for name references + public static final int RestrictiveFlagMASK = Bit1|Bit2|Bit3; + public static final int FirstAssignmentToLocalMASK = Bit4; + + // for this reference + public static final int IsImplicitThisMask = Bit3; + + // for single name references + public static final int DepthSHIFT = 5; // Bit6 -> Bit13 + public static final int DepthMASK = Bit6|Bit7|Bit8|Bit9|Bit10|Bit11|Bit12|Bit13; // 8 bits for actual depth value (max. 255) + + // for statements + public static final int IsReachableMASK = Bit32; + public static final int IsLocalDeclarationReachableMASK = Bit31; + + // for type declaration + public static final int AddAssertionMASK = Bit1; + + // for type, method and field declarations + public static final int HasLocalTypeMASK = Bit2; // cannot conflict with AddAssertionMASK + + // for expression + public static final int ParenthesizedSHIFT = 21; // Bit22 -> Bit29 + public static final int ParenthesizedMASK = Bit22|Bit23|Bit24|Bit25|Bit26|Bit27|Bit28|Bit29; // 8 bits for parenthesis count value (max. 255) + + // for assignment + public static final int IsAssignmentWithNoEffectMASK = Bit30; + + // for references on lhs of assignment (set only for true assignments, as opposed to compound ones) + public static final int IsStrictlyAssignedMASK = Bit14; + + public AstNode() { + + super(); + } + + public boolean cannotReturn() { + return false; + } + + public AstNode concreteStatement() { + return this; + } + + /* Answer true if the field use is considered deprecated. + * An access in the same compilation unit is allowed. + */ + public final boolean isFieldUseDeprecated(FieldBinding field, Scope scope) { + + if (field.isPrivate() && !scope.isDefinedInField(field)) { + // ignore cases where field is used from within inside itself + field.modifiers |= AccPrivateUsed; + } + + if (!field.isViewedAsDeprecated()) return false; + + // inside same unit - no report + if (scope.isDefinedInSameUnit(field.declaringClass)) return false; + + // if context is deprecated, may avoid reporting +// if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false; + return true; + } + + public boolean isImplicitThis() { + + return false; + } + + /* Answer true if the method use is considered deprecated. + * An access in the same compilation unit is allowed. + */ + public final boolean isMethodUseDeprecated(MethodBinding method, Scope scope) { + + if (method.isPrivate() && !scope.isDefinedInMethod(method)) { + // ignore cases where method is used from within inside itself (e.g. direct recursions) + method.modifiers |= AccPrivateUsed; + } + + if (!method.isViewedAsDeprecated()) return false; + + // inside same unit - no report + if (scope.isDefinedInSameUnit(method.declaringClass)) return false; + + // if context is deprecated, may avoid reporting +// if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false; + return true; + } + + public boolean isSuper() { + + return false; + } + + public boolean isThis() { + + return false; + } + + /* Answer true if the type use is considered deprecated. + * An access in the same compilation unit is allowed. + */ + public final boolean isTypeUseDeprecated(TypeBinding type, Scope scope) { + + if (type.isArrayType()) + type = ((ArrayBinding) type).leafComponentType; + if (type.isBaseType()) + return false; + + ReferenceBinding refType = (ReferenceBinding) type; + + if (refType.isPrivate() && !scope.isDefinedInType(refType)) { + // ignore cases where type is used from within inside itself + refType.modifiers |= AccPrivateUsed; + } + + if (!refType.isViewedAsDeprecated()) return false; + + // inside same unit - no report + if (scope.isDefinedInSameUnit(refType)) return false; + + // if context is deprecated, may avoid reporting +// if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false; + return true; + } + + public static String modifiersString(int modifiers) { + + String s = ""; //$NON-NLS-1$ + if ((modifiers & AccPublic) != 0) + s = s + "public "; //$NON-NLS-1$ + if ((modifiers & AccPrivate) != 0) + s = s + "private "; //$NON-NLS-1$ + if ((modifiers & AccProtected) != 0) + s = s + "protected "; //$NON-NLS-1$ + if ((modifiers & AccStatic) != 0) + s = s + "static "; //$NON-NLS-1$ + if ((modifiers & AccFinal) != 0) + s = s + "final "; //$NON-NLS-1$ +// if ((modifiers & AccSynchronized) != 0) +// s = s + "synchronized "; //$NON-NLS-1$ +// if ((modifiers & AccVolatile) != 0) +// s = s + "volatile "; //$NON-NLS-1$ +// if ((modifiers & AccTransient) != 0) +// s = s + "transient "; //$NON-NLS-1$ +// if ((modifiers & AccNative) != 0) +// s = s + "native "; //$NON-NLS-1$ + if ((modifiers & AccAbstract) != 0) + s = s + "abstract "; //$NON-NLS-1$ + return s; + } + + /** + * @deprecated - use field instead + */ + public int sourceEnd() { + return sourceEnd; + } + + /** + * @deprecated - use field instead + */ + public int sourceStart() { + return sourceStart; + } + + public static String tabString(int tab) { + + String s = ""; //$NON-NLS-1$ + for (int i = tab; i > 0; i--) + s = s + " "; //$NON-NLS-1$ + return s; + } + + public String toString() { + + return toString(0); + } + + public String toString(int tab) { + + return "****" + super.toString() + "****"; //$NON-NLS-2$ //$NON-NLS-1$ + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/BinaryExpression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/BinaryExpression.java new file mode 100644 index 0000000..ea6c70d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/BinaryExpression.java @@ -0,0 +1,1751 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class BinaryExpression extends OperatorExpression { + + public Expression left, right; + public Constant optimizedBooleanConstant; + + public BinaryExpression(Expression left, Expression right, int operator) { + + this.left = left; + this.right = right; + this.bits |= operator << OperatorSHIFT; // encode operator + this.sourceStart = left.sourceStart; + this.sourceEnd = right.sourceEnd; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + return right + .analyseCode( + currentScope, + flowContext, + left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()) + .unconditionalInits(); + } + + public void computeConstant(BlockScope scope, int leftId, int rightId) { + + //compute the constant when valid + if ((this.left.constant != Constant.NotAConstant) + && (this.right.constant != Constant.NotAConstant)) { + try { + this.constant = + Constant.computeConstantOperation( + this.left.constant, + leftId, + (this.bits & OperatorMASK) >> OperatorSHIFT, + this.right.constant, + rightId); + } catch (ArithmeticException e) { + this.constant = Constant.NotAConstant; + // 1.2 no longer throws an exception at compile-time + //scope.problemReporter().compileTimeConstantThrowsArithmeticException(this); + } + } else { + this.constant = Constant.NotAConstant; + //add some work for the boolean operators & | +// this.optimizedBooleanConstant( +// leftId, +// (this.bits & OperatorMASK) >> OperatorSHIFT, +// rightId); + } + } + + public Constant optimizedBooleanConstant() { + + return this.optimizedBooleanConstant == null ? this.constant : this.optimizedBooleanConstant; + } + + /** + * Code generation for a binary operation + */ +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// int pc = codeStream.position; +// Label falseLabel, endLabel; +// if (constant != Constant.NotAConstant) { +// if (valueRequired) +// codeStream.generateConstant(constant, implicitConversion); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// return; +// } +// bits |= OnlyValueRequiredMASK; +// switch ((bits & OperatorMASK) >> OperatorSHIFT) { +// case PLUS : +// switch (bits & ReturnTypeIDMASK) { +// case T_String : +// codeStream.generateStringAppend(currentScope, left, right); +// if (!valueRequired) +// codeStream.pop(); +// break; +// case T_int : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.iadd(); +// break; +// case T_long : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.ladd(); +// break; +// case T_double : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.dadd(); +// break; +// case T_float : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.fadd(); +// break; +// } +// break; +// case MINUS : +// switch (bits & ReturnTypeIDMASK) { +// case T_int : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.isub(); +// break; +// case T_long : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.lsub(); +// break; +// case T_double : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.dsub(); +// break; +// case T_float : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.fsub(); +// break; +// } +// break; +// case MULTIPLY : +// switch (bits & ReturnTypeIDMASK) { +// case T_int : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.imul(); +// break; +// case T_long : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.lmul(); +// break; +// case T_double : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.dmul(); +// break; +// case T_float : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.fmul(); +// break; +// } +// break; +// case DIVIDE : +// switch (bits & ReturnTypeIDMASK) { +// case T_int : +// left.generateCode(currentScope, codeStream, true); +// right.generateCode(currentScope, codeStream, true); +// codeStream.idiv(); +// if (!valueRequired) +// codeStream.pop(); +// break; +// case T_long : +// left.generateCode(currentScope, codeStream, true); +// right.generateCode(currentScope, codeStream, true); +// codeStream.ldiv(); +// if (!valueRequired) +// codeStream.pop2(); +// break; +// case T_double : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.ddiv(); +// break; +// case T_float : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.fdiv(); +// break; +// } +// break; +// case REMAINDER : +// switch (bits & ReturnTypeIDMASK) { +// case T_int : +// left.generateCode(currentScope, codeStream, true); +// right.generateCode(currentScope, codeStream, true); +// codeStream.irem(); +// if (!valueRequired) +// codeStream.pop(); +// break; +// case T_long : +// left.generateCode(currentScope, codeStream, true); +// right.generateCode(currentScope, codeStream, true); +// codeStream.lrem(); +// if (!valueRequired) +// codeStream.pop2(); +// break; +// case T_double : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.drem(); +// break; +// case T_float : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.frem(); +// break; +// } +// break; +// case AND : +// switch (bits & ReturnTypeIDMASK) { +// case T_int : +// // 0 & x +// if ((left.constant != Constant.NotAConstant) +// && (left.constant.typeID() == T_int) +// && (left.constant.intValue() == 0)) { +// right.generateCode(currentScope, codeStream, false); +// if (valueRequired) +// codeStream.iconst_0(); +// } else { +// // x & 0 +// if ((right.constant != Constant.NotAConstant) +// && (right.constant.typeID() == T_int) +// && (right.constant.intValue() == 0)) { +// left.generateCode(currentScope, codeStream, false); +// if (valueRequired) +// codeStream.iconst_0(); +// } else { +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.iand(); +// } +// } +// break; +// case T_long : +// // 0 & x +// if ((left.constant != Constant.NotAConstant) +// && (left.constant.typeID() == T_long) +// && (left.constant.longValue() == 0L)) { +// right.generateCode(currentScope, codeStream, false); +// if (valueRequired) +// codeStream.lconst_0(); +// } else { +// // x & 0 +// if ((right.constant != Constant.NotAConstant) +// && (right.constant.typeID() == T_long) +// && (right.constant.longValue() == 0L)) { +// left.generateCode(currentScope, codeStream, false); +// if (valueRequired) +// codeStream.lconst_0(); +// } else { +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.land(); +// } +// } +// break; +// case T_boolean : // logical and +// generateOptimizedLogicalAnd( +// currentScope, +// codeStream, +// null, +// (falseLabel = new Label(codeStream)), +// valueRequired); +// /* improving code gen for such a case: boolean b = i < 0 && false; +// * since the label has never been used, we have the inlined value on the stack. */ +// if (falseLabel.hasForwardReferences()) { +// if (valueRequired) { +// codeStream.iconst_1(); +// if ((bits & ValueForReturnMASK) != 0) { +// codeStream.ireturn(); +// falseLabel.place(); +// codeStream.iconst_0(); +// } else { +// codeStream.goto_(endLabel = new Label(codeStream)); +// codeStream.decrStackSize(1); +// falseLabel.place(); +// codeStream.iconst_0(); +// endLabel.place(); +// } +// } else { +// falseLabel.place(); +// } +// } +// } +// break; +// case OR : +// switch (bits & ReturnTypeIDMASK) { +// case T_int : +// // 0 | x +// if ((left.constant != Constant.NotAConstant) +// && (left.constant.typeID() == T_int) +// && (left.constant.intValue() == 0)) { +// right.generateCode(currentScope, codeStream, valueRequired); +// } else { +// // x | 0 +// if ((right.constant != Constant.NotAConstant) +// && (right.constant.typeID() == T_int) +// && (right.constant.intValue() == 0)) { +// left.generateCode(currentScope, codeStream, valueRequired); +// } else { +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.ior(); +// } +// } +// break; +// case T_long : +// // 0 | x +// if ((left.constant != Constant.NotAConstant) +// && (left.constant.typeID() == T_long) +// && (left.constant.longValue() == 0L)) { +// right.generateCode(currentScope, codeStream, valueRequired); +// } else { +// // x | 0 +// if ((right.constant != Constant.NotAConstant) +// && (right.constant.typeID() == T_long) +// && (right.constant.longValue() == 0L)) { +// left.generateCode(currentScope, codeStream, valueRequired); +// } else { +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.lor(); +// } +// } +// break; +// case T_boolean : // logical or +// generateOptimizedLogicalOr( +// currentScope, +// codeStream, +// null, +// (falseLabel = new Label(codeStream)), +// valueRequired); +// /* improving code gen for such a case: boolean b = i < 0 || true; +// * since the label has never been used, we have the inlined value on the stack. */ +// if (falseLabel.hasForwardReferences()) { +// if (valueRequired) { +// codeStream.iconst_1(); +// if ((bits & ValueForReturnMASK) != 0) { +// codeStream.ireturn(); +// falseLabel.place(); +// codeStream.iconst_0(); +// } else { +// codeStream.goto_(endLabel = new Label(codeStream)); +// codeStream.decrStackSize(1); +// falseLabel.place(); +// codeStream.iconst_0(); +// endLabel.place(); +// } +// } else { +// falseLabel.place(); +// } +// } +// } +// break; +// case XOR : +// switch (bits & ReturnTypeIDMASK) { +// case T_int : +// // 0 ^ x +// if ((left.constant != Constant.NotAConstant) +// && (left.constant.typeID() == T_int) +// && (left.constant.intValue() == 0)) { +// right.generateCode(currentScope, codeStream, valueRequired); +// } else { +// // x ^ 0 +// if ((right.constant != Constant.NotAConstant) +// && (right.constant.typeID() == T_int) +// && (right.constant.intValue() == 0)) { +// left.generateCode(currentScope, codeStream, valueRequired); +// } else { +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.ixor(); +// } +// } +// break; +// case T_long : +// // 0 ^ x +// if ((left.constant != Constant.NotAConstant) +// && (left.constant.typeID() == T_long) +// && (left.constant.longValue() == 0L)) { +// right.generateCode(currentScope, codeStream, valueRequired); +// } else { +// // x ^ 0 +// if ((right.constant != Constant.NotAConstant) +// && (right.constant.typeID() == T_long) +// && (right.constant.longValue() == 0L)) { +// left.generateCode(currentScope, codeStream, valueRequired); +// } else { +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.lxor(); +// } +// } +// break; +// case T_boolean : +// generateOptimizedLogicalXor( +// currentScope, +// codeStream, +// null, +// (falseLabel = new Label(codeStream)), +// valueRequired); +// /* improving code gen for such a case: boolean b = i < 0 ^ bool; +// * since the label has never been used, we have the inlined value on the stack. */ +// if (falseLabel.hasForwardReferences()) { +// if (valueRequired) { +// codeStream.iconst_1(); +// if ((bits & ValueForReturnMASK) != 0) { +// codeStream.ireturn(); +// falseLabel.place(); +// codeStream.iconst_0(); +// } else { +// codeStream.goto_(endLabel = new Label(codeStream)); +// codeStream.decrStackSize(1); +// falseLabel.place(); +// codeStream.iconst_0(); +// endLabel.place(); +// } +// } else { +// falseLabel.place(); +// } +// } +// } +// break; +// case LEFT_SHIFT : +// switch (bits & ReturnTypeIDMASK) { +// case T_int : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.ishl(); +// break; +// case T_long : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.lshl(); +// } +// break; +// case RIGHT_SHIFT : +// switch (bits & ReturnTypeIDMASK) { +// case T_int : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.ishr(); +// break; +// case T_long : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.lshr(); +// } +// break; +// case UNSIGNED_RIGHT_SHIFT : +// switch (bits & ReturnTypeIDMASK) { +// case T_int : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.iushr(); +// break; +// case T_long : +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) +// codeStream.lushr(); +// } +// break; +// case GREATER : +// generateOptimizedGreaterThan( +// currentScope, +// codeStream, +// null, +// (falseLabel = new Label(codeStream)), +// valueRequired); +// if (valueRequired) { +// codeStream.iconst_1(); +// if ((bits & ValueForReturnMASK) != 0) { +// codeStream.ireturn(); +// falseLabel.place(); +// codeStream.iconst_0(); +// } else { +// codeStream.goto_(endLabel = new Label(codeStream)); +// codeStream.decrStackSize(1); +// falseLabel.place(); +// codeStream.iconst_0(); +// endLabel.place(); +// } +// } +// break; +// case GREATER_EQUAL : +// generateOptimizedGreaterThanOrEqual( +// currentScope, +// codeStream, +// null, +// (falseLabel = new Label(codeStream)), +// valueRequired); +// if (valueRequired) { +// codeStream.iconst_1(); +// if ((bits & ValueForReturnMASK) != 0) { +// codeStream.ireturn(); +// falseLabel.place(); +// codeStream.iconst_0(); +// } else { +// codeStream.goto_(endLabel = new Label(codeStream)); +// codeStream.decrStackSize(1); +// falseLabel.place(); +// codeStream.iconst_0(); +// endLabel.place(); +// } +// } +// break; +// case LESS : +// generateOptimizedLessThan( +// currentScope, +// codeStream, +// null, +// (falseLabel = new Label(codeStream)), +// valueRequired); +// if (valueRequired) { +// codeStream.iconst_1(); +// if ((bits & ValueForReturnMASK) != 0) { +// codeStream.ireturn(); +// falseLabel.place(); +// codeStream.iconst_0(); +// } else { +// codeStream.goto_(endLabel = new Label(codeStream)); +// codeStream.decrStackSize(1); +// falseLabel.place(); +// codeStream.iconst_0(); +// endLabel.place(); +// } +// } +// break; +// case LESS_EQUAL : +// generateOptimizedLessThanOrEqual( +// currentScope, +// codeStream, +// null, +// (falseLabel = new Label(codeStream)), +// valueRequired); +// if (valueRequired) { +// codeStream.iconst_1(); +// if ((bits & ValueForReturnMASK) != 0) { +// codeStream.ireturn(); +// falseLabel.place(); +// codeStream.iconst_0(); +// } else { +// codeStream.goto_(endLabel = new Label(codeStream)); +// codeStream.decrStackSize(1); +// falseLabel.place(); +// codeStream.iconst_0(); +// endLabel.place(); +// } +// } +// } +// if (valueRequired) { +// codeStream.generateImplicitConversion(implicitConversion); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + /** + * Boolean operator code generation + * Optimized operations are: <, <=, >, >=, &, |, ^ + */ +// public void generateOptimizedBoolean( +// BlockScope currentScope, +// CodeStream codeStream, +// Label trueLabel, +// Label falseLabel, +// boolean valueRequired) { +// +// if ((constant != Constant.NotAConstant) && (constant.typeID() == T_boolean)) { +// super.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// return; +// } +// switch ((bits & OperatorMASK) >> OperatorSHIFT) { +// case LESS : +// generateOptimizedLessThan( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// return; +// case LESS_EQUAL : +// generateOptimizedLessThanOrEqual( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// return; +// case GREATER : +// generateOptimizedGreaterThan( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// return; +// case GREATER_EQUAL : +// generateOptimizedGreaterThanOrEqual( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// return; +// case AND : +// generateOptimizedLogicalAnd( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// return; +// case OR : +// generateOptimizedLogicalOr( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// return; +// case XOR : +// generateOptimizedLogicalXor( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// return; +// } +// super.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// } +// +// /** +// * Boolean generation for > +// */ +// public void generateOptimizedGreaterThan( +// BlockScope currentScope, +// CodeStream codeStream, +// Label trueLabel, +// Label falseLabel, +// boolean valueRequired) { +// +// int promotedTypeID = left.implicitConversion >> 4; +// // both sides got promoted in the same way +// if (promotedTypeID == T_int) { +// // 0 > x +// if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) { +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicitly falling through the FALSE case +// codeStream.iflt(trueLabel); +// } +// } else { +// if (trueLabel == null) { +// // implicitly falling through the TRUE case +// codeStream.ifge(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } +// // x > 0 +// if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) { +// left.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicitly falling through the FALSE case +// codeStream.ifgt(trueLabel); +// } +// } else { +// if (trueLabel == null) { +// // implicitly falling through the TRUE case +// codeStream.ifle(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } +// } +// // default comparison +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// switch (promotedTypeID) { +// case T_int : +// codeStream.if_icmpgt(trueLabel); +// break; +// case T_float : +// codeStream.fcmpl(); +// codeStream.ifgt(trueLabel); +// break; +// case T_long : +// codeStream.lcmp(); +// codeStream.ifgt(trueLabel); +// break; +// case T_double : +// codeStream.dcmpl(); +// codeStream.ifgt(trueLabel); +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } +// } else { +// if (trueLabel == null) { +// // implicit falling through the TRUE case +// switch (promotedTypeID) { +// case T_int : +// codeStream.if_icmple(falseLabel); +// break; +// case T_float : +// codeStream.fcmpl(); +// codeStream.ifle(falseLabel); +// break; +// case T_long : +// codeStream.lcmp(); +// codeStream.ifle(falseLabel); +// break; +// case T_double : +// codeStream.dcmpl(); +// codeStream.ifle(falseLabel); +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// } + + /** + * Boolean generation for >= + */ +// public void generateOptimizedGreaterThanOrEqual( +// BlockScope currentScope, +// CodeStream codeStream, +// Label trueLabel, +// Label falseLabel, +// boolean valueRequired) { +// +// int promotedTypeID = left.implicitConversion >> 4; +// // both sides got promoted in the same way +// if (promotedTypeID == T_int) { +// // 0 >= x +// if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) { +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicitly falling through the FALSE case +// codeStream.ifle(trueLabel); +// } +// } else { +// if (trueLabel == null) { +// // implicitly falling through the TRUE case +// codeStream.ifgt(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } +// // x >= 0 +// if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) { +// left.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicitly falling through the FALSE case +// codeStream.ifge(trueLabel); +// } +// } else { +// if (trueLabel == null) { +// // implicitly falling through the TRUE case +// codeStream.iflt(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } +// } +// // default comparison +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// switch (promotedTypeID) { +// case T_int : +// codeStream.if_icmpge(trueLabel); +// break; +// case T_float : +// codeStream.fcmpl(); +// codeStream.ifge(trueLabel); +// break; +// case T_long : +// codeStream.lcmp(); +// codeStream.ifge(trueLabel); +// break; +// case T_double : +// codeStream.dcmpl(); +// codeStream.ifge(trueLabel); +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } +// } else { +// if (trueLabel == null) { +// // implicit falling through the TRUE case +// switch (promotedTypeID) { +// case T_int : +// codeStream.if_icmplt(falseLabel); +// break; +// case T_float : +// codeStream.fcmpl(); +// codeStream.iflt(falseLabel); +// break; +// case T_long : +// codeStream.lcmp(); +// codeStream.iflt(falseLabel); +// break; +// case T_double : +// codeStream.dcmpl(); +// codeStream.iflt(falseLabel); +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// } +// +// /** +// * Boolean generation for < +// */ +// public void generateOptimizedLessThan( +// BlockScope currentScope, +// CodeStream codeStream, +// Label trueLabel, +// Label falseLabel, +// boolean valueRequired) { +// +// int promotedTypeID = left.implicitConversion >> 4; +// // both sides got promoted in the same way +// if (promotedTypeID == T_int) { +// // 0 < x +// if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) { +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicitly falling through the FALSE case +// codeStream.ifgt(trueLabel); +// } +// } else { +// if (trueLabel == null) { +// // implicitly falling through the TRUE case +// codeStream.ifle(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } +// // x < 0 +// if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) { +// left.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicitly falling through the FALSE case +// codeStream.iflt(trueLabel); +// } +// } else { +// if (trueLabel == null) { +// // implicitly falling through the TRUE case +// codeStream.ifge(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } +// } +// // default comparison +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// switch (promotedTypeID) { +// case T_int : +// codeStream.if_icmplt(trueLabel); +// break; +// case T_float : +// codeStream.fcmpg(); +// codeStream.iflt(trueLabel); +// break; +// case T_long : +// codeStream.lcmp(); +// codeStream.iflt(trueLabel); +// break; +// case T_double : +// codeStream.dcmpg(); +// codeStream.iflt(trueLabel); +// } +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } +// } else { +// if (trueLabel == null) { +// // implicit falling through the TRUE case +// switch (promotedTypeID) { +// case T_int : +// codeStream.if_icmpge(falseLabel); +// break; +// case T_float : +// codeStream.fcmpg(); +// codeStream.ifge(falseLabel); +// break; +// case T_long : +// codeStream.lcmp(); +// codeStream.ifge(falseLabel); +// break; +// case T_double : +// codeStream.dcmpg(); +// codeStream.ifge(falseLabel); +// } +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// } +// +// /** +// * Boolean generation for <= +// */ +// public void generateOptimizedLessThanOrEqual( +// BlockScope currentScope, +// CodeStream codeStream, +// Label trueLabel, +// Label falseLabel, +// boolean valueRequired) { +// +// int promotedTypeID = left.implicitConversion >> 4; +// // both sides got promoted in the same way +// if (promotedTypeID == T_int) { +// // 0 <= x +// if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) { +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicitly falling through the FALSE case +// codeStream.ifge(trueLabel); +// } +// } else { +// if (trueLabel == null) { +// // implicitly falling through the TRUE case +// codeStream.iflt(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } +// // x <= 0 +// if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) { +// left.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicitly falling through the FALSE case +// codeStream.ifle(trueLabel); +// } +// } else { +// if (trueLabel == null) { +// // implicitly falling through the TRUE case +// codeStream.ifgt(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } +// } +// // default comparison +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// switch (promotedTypeID) { +// case T_int : +// codeStream.if_icmple(trueLabel); +// break; +// case T_float : +// codeStream.fcmpg(); +// codeStream.ifle(trueLabel); +// break; +// case T_long : +// codeStream.lcmp(); +// codeStream.ifle(trueLabel); +// break; +// case T_double : +// codeStream.dcmpg(); +// codeStream.ifle(trueLabel); +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } +// } else { +// if (trueLabel == null) { +// // implicit falling through the TRUE case +// switch (promotedTypeID) { +// case T_int : +// codeStream.if_icmpgt(falseLabel); +// break; +// case T_float : +// codeStream.fcmpg(); +// codeStream.ifgt(falseLabel); +// break; +// case T_long : +// codeStream.lcmp(); +// codeStream.ifgt(falseLabel); +// break; +// case T_double : +// codeStream.dcmpg(); +// codeStream.ifgt(falseLabel); +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// return; +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// } +// +// /** +// * Boolean generation for & +// */ +// public void generateOptimizedLogicalAnd( +// BlockScope currentScope, +// CodeStream codeStream, +// Label trueLabel, +// Label falseLabel, +// boolean valueRequired) { +// +// Constant condConst; +// if ((left.implicitConversion & 0xF) == T_boolean) { +// if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) { +// if (condConst.booleanValue() == true) { +// // & x +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// if ((bits & OnlyValueRequiredMASK) != 0) { +// right.generateCode(currentScope, codeStream, valueRequired); +// } else { +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// } +// } else { +// // & x +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// if (valueRequired) { +// if ((bits & OnlyValueRequiredMASK) != 0) { +// codeStream.iconst_0(); +// } else { +// if (falseLabel != null) { +// // implicit falling through the TRUE case +// codeStream.goto_(falseLabel); +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// } +// return; +// } +// if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) { +// if (condConst.booleanValue() == true) { +// // x & +// if ((bits & OnlyValueRequiredMASK) != 0) { +// left.generateCode(currentScope, codeStream, valueRequired); +// } else { +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// } +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// } else { +// // x & +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// if (valueRequired) { +// if ((bits & OnlyValueRequiredMASK) != 0) { +// codeStream.iconst_0(); +// } else { +// if (falseLabel != null) { +// // implicit falling through the TRUE case +// codeStream.goto_(falseLabel); +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// } +// return; +// } +// } +// // default case +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// codeStream.iand(); +// if ((bits & OnlyValueRequiredMASK) == 0) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// codeStream.ifne(trueLabel); +// } +// } else { +// // implicit falling through the TRUE case +// if (trueLabel == null) { +// codeStream.ifeq(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// } +// +// /** +// * Boolean generation for | +// */ +// public void generateOptimizedLogicalOr( +// BlockScope currentScope, +// CodeStream codeStream, +// Label trueLabel, +// Label falseLabel, +// boolean valueRequired) { +// +// Constant condConst; +// if ((left.implicitConversion & 0xF) == T_boolean) { +// if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) { +// if (condConst.booleanValue() == true) { +// // | x +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// if (valueRequired) { +// if ((bits & OnlyValueRequiredMASK) != 0) { +// codeStream.iconst_1(); +// } else { +// if (trueLabel != null) { +// codeStream.goto_(trueLabel); +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// } else { +// // | x +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// if ((bits & OnlyValueRequiredMASK) != 0) { +// right.generateCode(currentScope, codeStream, valueRequired); +// } else { +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// } +// } +// return; +// } +// if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) { +// if (condConst.booleanValue() == true) { +// // x | +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// if (valueRequired) { +// if ((bits & OnlyValueRequiredMASK) != 0) { +// codeStream.iconst_1(); +// } else { +// if (trueLabel != null) { +// codeStream.goto_(trueLabel); +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// } else { +// // x | +// if ((bits & OnlyValueRequiredMASK) != 0) { +// left.generateCode(currentScope, codeStream, valueRequired); +// } else { +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// } +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// } +// return; +// } +// } +// // default case +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// codeStream.ior(); +// if ((bits & OnlyValueRequiredMASK) == 0) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// codeStream.ifne(trueLabel); +// } +// } else { +// // implicit falling through the TRUE case +// if (trueLabel == null) { +// codeStream.ifeq(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// } +// +// /** +// * Boolean generation for ^ +// */ +// public void generateOptimizedLogicalXor( +// BlockScope currentScope, +// CodeStream codeStream, +// Label trueLabel, +// Label falseLabel, +// boolean valueRequired) { +// +// Constant condConst; +// if ((left.implicitConversion & 0xF) == T_boolean) { +// if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) { +// if (condConst.booleanValue() == true) { +// // ^ x +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// falseLabel, +// trueLabel, +// valueRequired); +// } else { +// // ^ x +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// if ((bits & OnlyValueRequiredMASK) != 0) { +// right.generateCode(currentScope, codeStream, valueRequired); +// } else { +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// } +// } +// return; +// } +// if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) { +// if (condConst.booleanValue() == true) { +// // x ^ +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// falseLabel, +// trueLabel, +// valueRequired); +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// } else { +// // x ^ +// if ((bits & OnlyValueRequiredMASK) != 0) { +// left.generateCode(currentScope, codeStream, valueRequired); +// } else { +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// } +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// } +// return; +// } +// } +// // default case +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// codeStream.ixor(); +// if ((bits & OnlyValueRequiredMASK) == 0) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// codeStream.ifne(trueLabel); +// } +// } else { +// // implicit falling through the TRUE case +// if (trueLabel == null) { +// codeStream.ifeq(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// } +// +// public void generateOptimizedStringBuffer( +// BlockScope blockScope, +// CodeStream codeStream, +// int typeID) { +// +// /* In the case trying to make a string concatenation, there is no need to create a new +// * string buffer, thus use a lower-level API for code generation involving only the +// * appending of arguments to the existing StringBuffer +// */ +// +// if ((((bits & OperatorMASK) >> OperatorSHIFT) == PLUS) +// && ((bits & ReturnTypeIDMASK) == T_String)) { +// if (constant != NotAConstant) { +// codeStream.generateConstant(constant, implicitConversion); +// codeStream.invokeStringBufferAppendForType(implicitConversion & 0xF); +// } else { +// int pc = codeStream.position; +// left.generateOptimizedStringBuffer( +// blockScope, +// codeStream, +// left.implicitConversion & 0xF); +// codeStream.recordPositionsFrom(pc, left.sourceStart); +// pc = codeStream.position; +// right.generateOptimizedStringBuffer( +// blockScope, +// codeStream, +// right.implicitConversion & 0xF); +// codeStream.recordPositionsFrom(pc, right.sourceStart); +// } +// } else { +// super.generateOptimizedStringBuffer(blockScope, codeStream, typeID); +// } +// } +// +// public void generateOptimizedStringBufferCreation( +// BlockScope blockScope, +// CodeStream codeStream, +// int typeID) { +// +// /* In the case trying to make a string concatenation, there is no need to create a new +// * string buffer, thus use a lower-level API for code generation involving only the +// * appending of arguments to the existing StringBuffer +// */ +// +// if ((((bits & OperatorMASK) >> OperatorSHIFT) == PLUS) +// && ((bits & ReturnTypeIDMASK) == T_String)) { +// if (constant != NotAConstant) { +// codeStream.newStringBuffer(); // new: java.lang.StringBuffer +// codeStream.dup(); +// codeStream.ldc(constant.stringValue()); +// codeStream.invokeStringBufferStringConstructor(); +// // invokespecial: java.lang.StringBuffer.(Ljava.lang.String;)V +// } else { +// int pc = codeStream.position; +// left.generateOptimizedStringBufferCreation( +// blockScope, +// codeStream, +// left.implicitConversion & 0xF); +// codeStream.recordPositionsFrom(pc, left.sourceStart); +// pc = codeStream.position; +// right.generateOptimizedStringBuffer( +// blockScope, +// codeStream, +// right.implicitConversion & 0xF); +// codeStream.recordPositionsFrom(pc, right.sourceStart); +// } +// } else { +// super.generateOptimizedStringBufferCreation(blockScope, codeStream, typeID); +// } +// } +// +// public boolean isCompactableOperation() { +// +// return true; +// } +// +// public void optimizedBooleanConstant(int leftId, int operator, int rightId) { +// +// switch (operator) { +// case AND : +// if ((leftId != T_boolean) || (rightId != T_boolean)) +// return; +// case AND_AND : +// Constant cst; +// if ((cst = left.optimizedBooleanConstant()) != NotAConstant) { +// if (cst.booleanValue() == false) { // left is equivalent to false +// optimizedBooleanConstant = cst; // constant(false) +// return; +// } else { //left is equivalent to true +// if ((cst = right.optimizedBooleanConstant()) != NotAConstant) { +// optimizedBooleanConstant = cst; +// // the conditional result is equivalent to the right conditional value +// } +// return; +// } +// } +// if ((cst = right.optimizedBooleanConstant()) != NotAConstant) { +// if (cst.booleanValue() == false) { // right is equivalent to false +// optimizedBooleanConstant = cst; // constant(false) +// } +// } +// return; +// case OR : +// if ((leftId != T_boolean) || (rightId != T_boolean)) +// return; +// case OR_OR : +// if ((cst = left.optimizedBooleanConstant()) != NotAConstant) { +// if (cst.booleanValue() == true) { // left is equivalent to true +// optimizedBooleanConstant = cst; // constant(true) +// return; +// } else { //left is equivalent to false +// if ((cst = right.optimizedBooleanConstant()) != NotAConstant) { +// optimizedBooleanConstant = cst; +// } +// return; +// } +// } +// if ((cst = right.optimizedBooleanConstant()) != NotAConstant) { +// if (cst.booleanValue() == true) { // right is equivalent to true +// optimizedBooleanConstant = cst; // constant(true) +// } +// } +// } +// } + + public TypeBinding resolveType(BlockScope scope) { + + // use the id of the type to navigate into the table + TypeBinding leftTb = left.resolveType(scope); + TypeBinding rightTb = right.resolveType(scope); + if (leftTb == null || rightTb == null) { + constant = Constant.NotAConstant; + return null; + } + int leftId = leftTb.id; + int rightId = rightTb.id; + if (leftId > 15 + || rightId > 15) { // must convert String + Object || Object + String + if (leftId == T_String) { + rightId = T_Object; + } else if (rightId == T_String) { + leftId = T_Object; + } else { + constant = Constant.NotAConstant; + scope.problemReporter().invalidOperator(this, leftTb, rightTb); + return null; + } + } + if (((bits & OperatorMASK) >> OperatorSHIFT) == PLUS) { + if (leftId == T_String + && rightTb.isArrayType() + && ((ArrayBinding) rightTb).elementsType(scope) == CharBinding) + scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression( + right); + else if ( + rightId == T_String + && leftTb.isArrayType() + && ((ArrayBinding) leftTb).elementsType(scope) == CharBinding) + scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression( + left); + } + + // the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 <<0 + + // Don't test for result = 0. If it is zero, some more work is done. + // On the one hand when it is not zero (correct code) we avoid doing the test + int result = + ResolveTypeTables[(bits & OperatorMASK) >> OperatorSHIFT][(leftId << 4) + + rightId]; + left.implicitConversion = result >>> 12; + right.implicitConversion = (result >>> 4) & 0x000FF; + + bits |= result & 0xF; + switch (result & 0xF) { // record the current ReturnTypeID + // only switch on possible result type..... + case T_boolean : + this.resolvedType = BooleanBinding; + break; + case T_byte : + this.resolvedType = ByteBinding; + break; + case T_char : + this.resolvedType = CharBinding; + break; + case T_double : + this.resolvedType = DoubleBinding; + break; + case T_float : + this.resolvedType = FloatBinding; + break; + case T_int : + this.resolvedType = IntBinding; + break; + case T_long : + this.resolvedType = LongBinding; + break; + case T_String : + this.resolvedType = scope.getJavaLangString(); + break; + default : //error........ + constant = Constant.NotAConstant; + scope.problemReporter().invalidOperator(this, leftTb, rightTb); + return null; + } + + // compute the constant when valid + computeConstant(scope, leftId, rightId); + return this.resolvedType; + } + + public String toStringExpressionNoParenthesis() { + + return left.toStringExpression() + " " + //$NON-NLS-1$ + operatorToString() + " " + //$NON-NLS-1$ + right.toStringExpression(); + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + left.traverse(visitor, scope); + right.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Block.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Block.java new file mode 100644 index 0000000..d2fe75f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Block.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; + +public class Block extends Statement { + + public Statement[] statements; + public int explicitDeclarations; + // the number of explicit declaration , used to create scope + public BlockScope scope; + public static final Block None = new Block(0); + + public Block(int explicitDeclarations) { + this.explicitDeclarations = explicitDeclarations; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + // empty block + if (statements == null) return flowInfo; + boolean didAlreadyComplain = false; + for (int i = 0, max = statements.length; i < max; i++) { + Statement stat; + if (!flowInfo.complainIfUnreachable(stat = statements[i], scope, didAlreadyComplain)) { + flowInfo = stat.analyseCode(scope, flowContext, flowInfo); + } else { + didAlreadyComplain = true; + } + } + return flowInfo; + } + + public static final Block EmptyWith(int sourceStart, int sourceEnd) { + + //return an empty block which position is s and e + Block bk = new Block(0); + bk.sourceStart = sourceStart; + bk.sourceEnd = sourceEnd; + return bk; + } + + /** + * Code generation for a block + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// if (statements != null) { +// for (int i = 0, max = statements.length; i < max; i++) { +// statements[i].generateCode(scope, codeStream); +// } +// } // for local variable debug attributes +// if (scope != currentScope) { // was really associated with its own scope +// codeStream.exitUserScope(scope); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public boolean isEmptyBlock() { + + return statements == null; + } + + public void resolve(BlockScope upperScope) { + + if (statements != null) { + scope = + explicitDeclarations == 0 + ? upperScope + : new BlockScope(upperScope, explicitDeclarations); + int i = 0, length = statements.length; + while (i < length) + statements[i++].resolve(scope); + } + } + + public void resolveUsing(BlockScope givenScope) { + + // this optimized resolve(...) is sent only on none empty blocks + scope = givenScope; + if (statements != null) { + int i = 0, length = statements.length; + while (i < length) + statements[i++].resolve(scope); + } + } + + public String toString(int tab) { + + String s = tabString(tab); + if (this.statements == null) { + s += "{\n"; //$NON-NLS-1$ + s += tabString(tab); + s += "}"; //$NON-NLS-1$ + return s; + } + s += "{\n"; //$NON-NLS-1$ + s += this.toStringStatements(tab); + s += tabString(tab); + s += "}"; //$NON-NLS-1$ + return s; + } + + public String toStringStatements(int tab) { + + if (this.statements == null) + return ""; //$NON-NLS-1$ + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < statements.length; i++) { + buffer.append(statements[i].toString(tab + 1)); + if (statements[i] instanceof Block) { + buffer.append("\n"); //$NON-NLS-1$ + } else { + buffer.append(";\n"); //$NON-NLS-1$ + } + }; + return buffer.toString(); + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + if (statements != null) { + int statementLength = statements.length; + for (int i = 0; i < statementLength; i++) + statements[i].traverse(visitor, scope); + } + } + visitor.endVisit(this, blockScope); + } + + /** + * Dispatch the call on its last statement. + */ + public void branchChainTo(Label label) { + if (this.statements != null) { + this.statements[statements.length - 1].branchChainTo(label); + } + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/BranchStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/BranchStatement.java new file mode 100644 index 0000000..be0bdb0 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/BranchStatement.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; + +public abstract class BranchStatement extends Statement { + public char[] label; + public Label targetLabel; + public AstNode[] subroutines; +/** + * BranchStatement constructor comment. + */ +public BranchStatement(char[] l, int s,int e) { + label = l ; + sourceStart = s; + sourceEnd = e; +} +/** + * Branch code generation + * + * generate the finallyInvocationSequence. + */ +//public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// +// // generation of code responsible for invoking the finally +// // blocks in sequence +// if (subroutines != null){ +// for (int i = 0, max = subroutines.length; i < max; i++){ +// AstNode sub; +// if ((sub = subroutines[i]) instanceof SynchronizedStatement){ +// codeStream.load(((SynchronizedStatement)sub).synchroVariable); +// codeStream.monitorexit(); +// } else { +// TryStatement trySub = (TryStatement) sub; +// if (trySub.subRoutineCannotReturn) { +// codeStream.goto_(trySub.subRoutineStartLabel); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// return; +// } else { +// codeStream.jsr(trySub.subRoutineStartLabel); +// } +// } +// } +// } +// codeStream.goto_(targetLabel); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +public void resetStateForCodeGeneration() { + if (this.targetLabel != null) { + this.targetLabel.resetStateForCodeGeneration(); + } +} + +public void resolve(BlockScope scope) { +} + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Break.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Break.java new file mode 100644 index 0000000..d01e783 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Break.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; + +public class Break extends BranchStatement { + + public Break(char[] label, int sourceStart, int e) { + super(label, sourceStart, e); + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + // here requires to generate a sequence of finally blocks invocations depending corresponding + // to each of the traversed try statements, so that execution will terminate properly. + + // lookup the label, this should answer the returnContext + FlowContext targetContext = (label == null) + ? flowContext.getTargetContextForDefaultBreak() + : flowContext.getTargetContextForBreakLabel(label); + + if (targetContext == null) { + if (label == null) { + currentScope.problemReporter().invalidBreak(this); + } else { + currentScope.problemReporter().undefinedLabel(this); + } + return flowInfo; // pretend it did not break since no actual target + } + + targetLabel = targetContext.breakLabel(); + FlowContext traversedContext = flowContext; + int subIndex = 0, maxSub = 5; + subroutines = new AstNode[maxSub]; + + do { + AstNode sub; + if ((sub = traversedContext.subRoutine()) != null) { + if (subIndex == maxSub) { + System.arraycopy(subroutines, 0, (subroutines = new AstNode[maxSub*=2]), 0, subIndex); // grow + } + subroutines[subIndex++] = sub; + if (sub.cannotReturn()) { + break; + } + } + traversedContext.recordReturnFrom(flowInfo.unconditionalInits()); + + AstNode node; + if ((node = traversedContext.associatedNode) instanceof TryStatement) { + TryStatement tryStatement = (TryStatement) node; + flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits + } else if (traversedContext == targetContext) { + // only record break info once accumulated through subroutines, and only against target context + targetContext.recordBreakFrom(flowInfo); + break; + } + } while ((traversedContext = traversedContext.parent) != null); + + // resize subroutines + if (subIndex != maxSub) { + System.arraycopy(subroutines, 0, (subroutines = new AstNode[subIndex]), 0, subIndex); + } + return FlowInfo.DEAD_END; + } + + public String toString(int tab) { + + String s = tabString(tab); + s += "break "; //$NON-NLS-1$ + if (label != null) + s += new String(label); + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockscope) { + + visitor.visit(this, blockscope); + visitor.endVisit(this, blockscope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Case.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Case.java new file mode 100644 index 0000000..afea4db --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Case.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.CaseLabel; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public class Case extends Statement { + + public Expression constantExpression; + public CaseLabel targetLabel; + public Case(int sourceStart, Expression constantExpression) { + this.constantExpression = constantExpression; + this.sourceEnd = constantExpression.sourceEnd; + this.sourceStart = sourceStart; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + if (constantExpression.constant == NotAConstant) + currentScope.problemReporter().caseExpressionMustBeConstant(constantExpression); + + this.constantExpression.analyseCode(currentScope, flowContext, flowInfo); + return flowInfo; + } + + /** + * Case code generation + * + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// targetLabel.place(); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + /** + * No-op : should use resolveCase(...) instead. + */ + public void resolve(BlockScope scope) { + } + + public Constant resolveCase( + BlockScope scope, + TypeBinding switchType, + SwitchStatement switchStatement) { + + // add into the collection of cases of the associated switch statement + switchStatement.cases[switchStatement.caseCount++] = this; + TypeBinding caseType = constantExpression.resolveType(scope); + if (caseType == null || switchType == null) + return null; + if (constantExpression.isConstantValueOfTypeAssignableToType(caseType, switchType)) + return constantExpression.constant; + if (caseType.isCompatibleWith(switchType)) + return constantExpression.constant; + scope.problemReporter().typeMismatchErrorActualTypeExpectedType( + constantExpression, + caseType, + switchType); + return null; + } + + public String toString(int tab) { + + String s = tabString(tab); + s = s + "case " + constantExpression.toStringExpression() + " : "; //$NON-NLS-1$ //$NON-NLS-2$ + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + constantExpression.traverse(visitor, blockScope); + } + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CastExpression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CastExpression.java new file mode 100644 index 0000000..776c33a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CastExpression.java @@ -0,0 +1,307 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BaseTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.Scope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class CastExpression extends Expression { + + public Expression expression; + public Expression type; + public boolean needRuntimeCheckcast; + + //expression.implicitConversion holds the cast for baseType casting + public CastExpression(Expression e, Expression t) { + expression = e; + type = t; + + //due to the fact an expression may start with ( and that a cast also start with ( + //the field is an expression....it can be a TypeReference OR a NameReference Or + //an expression <--this last one is invalid....... + + // :-( ............. + + //if (type instanceof TypeReference ) + // flag = IsTypeReference ; + //else + // if (type instanceof NameReference) + // flag = IsNameReference ; + // else + // flag = IsExpression ; + + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + return expression + .analyseCode(currentScope, flowContext, flowInfo) + .unconditionalInits(); + } + + public final void areTypesCastCompatible( + BlockScope scope, + TypeBinding castType, + TypeBinding expressionType) { + + // see specifications 5.5 + // handle errors and process constant when needed + + // if either one of the type is null ==> + // some error has been already reported some where ==> + // we then do not report an obvious-cascade-error. + + needRuntimeCheckcast = false; + if (castType == null || expressionType == null) return; + + // identity conversion cannot be performed upfront, due to side-effects + // like constant propagation + + if (castType.isBaseType()) { + if (expressionType.isBaseType()) { + if (expressionType == castType) { + expression.implicitWidening(castType, expressionType); + constant = expression.constant; //use the same constant + return; + } + if (expressionType.isCompatibleWith(castType) + || BaseTypeBinding.isNarrowing(castType.id, expressionType.id)) { + expression.implicitConversion = (castType.id << 4) + expressionType.id; + if (expression.constant != Constant.NotAConstant) + constant = expression.constant.castTo(expression.implicitConversion); + return; + } + } + scope.problemReporter().typeCastError(this, castType, expressionType); + return; + } + + //-----------cast to something which is NOT a base type-------------------------- + if (expressionType == NullBinding) { + // if (castType.isArrayType()){ // 26903 - need checkcast when casting null to array type + // needRuntimeCheckcast = true; + // } + return; //null is compatible with every thing + } + if (expressionType.isBaseType()) { + scope.problemReporter().typeCastError(this, castType, expressionType); + return; + } + + if (expressionType.isArrayType()) { + if (castType == expressionType) return; // identity conversion + + if (castType.isArrayType()) { + //------- (castType.isArray) expressionType.isArray ----------- + TypeBinding exprElementType = ((ArrayBinding) expressionType).elementsType(scope); + if (exprElementType.isBaseType()) { + // <---stop the recursion------- + if (((ArrayBinding) castType).elementsType(scope) == exprElementType) + needRuntimeCheckcast = true; + else + scope.problemReporter().typeCastError(this, castType, expressionType); + return; + } + // recursively on the elements... + areTypesCastCompatible( + scope, + ((ArrayBinding) castType).elementsType(scope), + exprElementType); + return; + } else if ( + castType.isClass()) { + //------(castType.isClass) expressionType.isArray --------------- + if (scope.isJavaLangObject(castType)) + return; + } else { //------- (castType.isInterface) expressionType.isArray ----------- + if (scope.isJavaLangCloneable(castType) || scope.isJavaIoSerializable(castType)) { + needRuntimeCheckcast = true; + return; + } + } + scope.problemReporter().typeCastError(this, castType, expressionType); + return; + } + + if (expressionType.isClass()) { + if (castType.isArrayType()) { + // ---- (castType.isArray) expressionType.isClass ------- + if (scope.isJavaLangObject(expressionType)) { // potential runtime error + needRuntimeCheckcast = true; + return; + } + } else if (castType.isClass()) { // ----- (castType.isClass) expressionType.isClass ------ + if (expressionType.isCompatibleWith(castType)){ // no runtime error + if (castType.id == T_String) constant = expression.constant; // (String) cst is still a constant + return; + } + if (castType.isCompatibleWith(expressionType)) { + // potential runtime error + needRuntimeCheckcast = true; + return; + } + } else { // ----- (castType.isInterface) expressionType.isClass ------- + if (((ReferenceBinding) expressionType).isFinal()) { + // no subclass for expressionType, thus compile-time check is valid + if (expressionType.isCompatibleWith(castType)) + return; + } else { // a subclass may implement the interface ==> no check at compile time + needRuntimeCheckcast = true; + return; + } + } + scope.problemReporter().typeCastError(this, castType, expressionType); + return; + } + + // if (expressionType.isInterface()) { cannot be anything else + if (castType.isArrayType()) { + // ----- (castType.isArray) expressionType.isInterface ------ + if (scope.isJavaLangCloneable(expressionType) + || scope.isJavaIoSerializable(expressionType)) // potential runtime error + needRuntimeCheckcast = true; + else + scope.problemReporter().typeCastError(this, castType, expressionType); + return; + } else if (castType.isClass()) { // ----- (castType.isClass) expressionType.isInterface -------- + if (scope.isJavaLangObject(castType)) // no runtime error + return; + if (((ReferenceBinding) castType).isFinal()) { + // no subclass for castType, thus compile-time check is valid + if (!castType.isCompatibleWith(expressionType)) { + // potential runtime error + scope.problemReporter().typeCastError(this, castType, expressionType); + return; + } + } + } else { // ----- (castType.isInterface) expressionType.isInterface ------- + if (castType == expressionType) return; // identity conversion + if (Scope.compareTypes(castType, expressionType) == NotRelated) { + MethodBinding[] castTypeMethods = ((ReferenceBinding) castType).methods(); + MethodBinding[] expressionTypeMethods = + ((ReferenceBinding) expressionType).methods(); + int exprMethodsLength = expressionTypeMethods.length; + for (int i = 0, castMethodsLength = castTypeMethods.length; i < castMethodsLength; i++) + for (int j = 0; j < exprMethodsLength; j++) { + if ((castTypeMethods[i].returnType != expressionTypeMethods[j].returnType) + && (castTypeMethods[i].selector == expressionTypeMethods[j].selector) + && castTypeMethods[i].areParametersEqual(expressionTypeMethods[j])) { + scope.problemReporter().typeCastError(this, castType, expressionType); + } + } + } + } + needRuntimeCheckcast = true; + return; + } + + /** + * Cast expression code generation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// int pc = codeStream.position; +// if (constant != NotAConstant) { +// if (valueRequired +// || needRuntimeCheckcast) { // Added for: 1F1W9IG: IVJCOM:WINNT - Compiler omits casting check +// codeStream.generateConstant(constant, implicitConversion); +// if (needRuntimeCheckcast) { +// codeStream.checkcast(this.resolvedType); +// if (!valueRequired) +// codeStream.pop(); +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// return; +// } +// expression.generateCode( +// currentScope, +// codeStream, +// valueRequired || needRuntimeCheckcast); +// if (needRuntimeCheckcast) { +// codeStream.checkcast(this.resolvedType); +// if (!valueRequired) +// codeStream.pop(); +// } else { +// if (valueRequired) +// codeStream.generateImplicitConversion(implicitConversion); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public Expression innermostCastedExpression(){ + Expression current = this.expression; + while (current instanceof CastExpression) { + current = ((CastExpression) current).expression; + } + return current; + } + + public TypeBinding resolveType(BlockScope scope) { + // compute a new constant if the cast is effective + + // due to the fact an expression may start with ( and that a cast can also start with ( + // the field is an expression....it can be a TypeReference OR a NameReference Or + // any kind of Expression <-- this last one is invalid....... + + constant = Constant.NotAConstant; + implicitConversion = T_undefined; + if ((type instanceof TypeReference) || (type instanceof NameReference)) { + this.resolvedType = type.resolveType(scope); + TypeBinding castedExpressionType = expression.resolveType(scope); + if (this.resolvedType != null && castedExpressionType != null) { + areTypesCastCompatible(scope, this.resolvedType, castedExpressionType); + } + return this.resolvedType; + } else { // expression as a cast !!!!!!!! + TypeBinding castedExpressionType = expression.resolveType(scope); + if (castedExpressionType == null) return null; + scope.problemReporter().invalidTypeReference(type); + return null; + } + } + + public String toStringExpression() { + + return "(" + type.toString(0) + ") " + //$NON-NLS-2$ //$NON-NLS-1$ + expression.toStringExpression(); + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + type.traverse(visitor, blockScope); + expression.traverse(visitor, blockScope); + } + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CharLiteral.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CharLiteral.java new file mode 100644 index 0000000..b9946df --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CharLiteral.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public class CharLiteral extends NumberLiteral { + char value; +public CharLiteral(char[] token, int s, int e) { + super(token, s, e); + computeValue(); +} +public void computeConstant() { + //The source is a char[3] first and last char are ' + //This is true for both regular char AND unicode char + //BUT not for escape char like '\b' which are char[4].... + + constant = Constant.fromValue(value); +} +private void computeValue() { + //The source is a char[3] first and last char are ' + //This is true for both regular char AND unicode char + //BUT not for escape char like '\b' which are char[4].... + + if ((value = source[1]) != '\\') + return; + char digit; + switch (digit = source[2]) { + case 'b' : + value = '\b'; + break; + case 't' : + value = '\t'; + break; + case 'n' : + value = '\n'; + break; + case 'f' : + value = '\f'; + break; + case 'r' : + value = '\r'; + break; + case '\"' : + value = '\"'; + break; + case '\'' : + value = '\''; + break; + case '\\' : + value = '\\'; + break; + default : //octal (well-formed: ended by a ' ) + int number = Character.getNumericValue(digit); + if ((digit = source[3]) != '\'') + number = (number * 8) + Character.getNumericValue(digit); + else { + constant = Constant.fromValue(value = (char) number); + break; + }; + if ((digit = source[4]) != '\'') + number = (number * 8) + Character.getNumericValue(digit); + value = (char) number; + break; + } +} +/** + * CharLiteral code generation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +//public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { +// int pc = codeStream.position; +// if (valueRequired) +// if ((implicitConversion >> 4) == T_char) +// codeStream.generateInlinedValue(value); +// else +// codeStream.generateConstant(constant, implicitConversion); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +public TypeBinding literalType(BlockScope scope) { + return CharBinding; +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) { + visitor.visit(this, blockScope); + visitor.endVisit(this, blockScope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ClassLiteralAccess.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ClassLiteralAccess.java new file mode 100644 index 0000000..4c24608 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ClassLiteralAccess.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class ClassLiteralAccess extends Expression { + + public TypeReference type; + public TypeBinding targetType; + FieldBinding syntheticField; + + public ClassLiteralAccess(int sourceEnd, TypeReference t) { + type = t; + this.sourceStart = t.sourceStart; + this.sourceEnd = sourceEnd; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + // if reachable, request the addition of a synthetic field for caching the class descriptor + SourceTypeBinding sourceType = + currentScope.outerMostMethodScope().enclosingSourceType(); + if (!(sourceType.isInterface() + // no field generated in interface case (would'nt verify) see 1FHHEZL + || sourceType.isBaseType())) { + syntheticField = sourceType.addSyntheticField(targetType, currentScope); + } + return flowInfo; + } + + /** + * MessageSendDotClass code generation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// int pc = codeStream.position; +// +// // in interface case, no caching occurs, since cannot make a cache field for interface +// if (valueRequired) +// codeStream.generateClassLiteralAccessForType(type.resolvedType, syntheticField); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public TypeBinding resolveType(BlockScope scope) { + + constant = NotAConstant; + if ((targetType = type.resolveType(scope)) == null) + return null; + + if (targetType.isArrayType() + && ((ArrayBinding) targetType).leafComponentType == VoidBinding) { + scope.problemReporter().cannotAllocateVoidArray(this); + return null; + } + + return this.resolvedType = scope.getJavaLangClass(); + } + + public String toStringExpression() { + + String s = ""; //$NON-NLS-1$ + s = s + type.toString(0) + ".class"; //$NON-NLS-1$ + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + type.traverse(visitor, blockScope); + } + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Clinit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Clinit.java new file mode 100644 index 0000000..787f28d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Clinit.java @@ -0,0 +1,256 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.ExceptionHandlingFlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.InitializationFlowContext; +import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.parser.UnitParser; +import net.sourceforge.phpdt.internal.compiler.problem.AbortMethod; + +public class Clinit extends AbstractMethodDeclaration { + + public final static char[] ConstantPoolName = "".toCharArray(); //$NON-NLS-1$ + + private FieldBinding assertionSyntheticFieldBinding = null; + private FieldBinding classLiteralSyntheticField = null; + + public Clinit(CompilationResult compilationResult) { + super(compilationResult); + modifiers = 0; + selector = ConstantPoolName; + } + + public void analyseCode( + ClassScope classScope, + InitializationFlowContext staticInitializerFlowContext, + FlowInfo flowInfo) { + + if (ignoreFurtherInvestigation) + return; + try { + ExceptionHandlingFlowContext clinitContext = + new ExceptionHandlingFlowContext( + staticInitializerFlowContext.parent, + this, + NoExceptions, + scope, + FlowInfo.DEAD_END); + + // check for missing returning path + this.needFreeReturn = flowInfo.isReachable(); + + // check missing blank final field initializations + flowInfo = flowInfo.mergedWith(staticInitializerFlowContext.initsOnReturn); + FieldBinding[] fields = scope.enclosingSourceType().fields(); + for (int i = 0, count = fields.length; i < count; i++) { + FieldBinding field; + if ((field = fields[i]).isStatic() + && field.isFinal() + && (!flowInfo.isDefinitelyAssigned(fields[i]))) { + scope.problemReporter().uninitializedBlankFinalField( + field, + scope.referenceType().declarationOf(field)); + // can complain against the field decl, since only one + } + } + // check static initializers thrown exceptions + staticInitializerFlowContext.checkInitializerExceptions( + scope, + clinitContext, + flowInfo); + } catch (AbortMethod e) { + this.ignoreFurtherInvestigation = true; + } + } + + /** + * Bytecode generation for a method + * + * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope + * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile + */ +// public void generateCode(ClassScope classScope, ClassFile classFile) { +// +// int clinitOffset = 0; +// if (ignoreFurtherInvestigation) { +// // should never have to add any problem method +// return; +// } +// try { +// clinitOffset = classFile.contentsOffset; +// this.generateCode(classScope, classFile, clinitOffset); +// } catch (AbortMethod e) { +// // should never occur +// // the clinit referenceContext is the type declaration +// // All clinit problems will be reported against the type: AbortType instead of AbortMethod +// // reset the contentsOffset to the value before generating the clinit code +// // decrement the number of method info as well. +// // This is done in the addProblemMethod and addProblemConstructor for other +// // cases. +// if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) { +// // a branch target required a goto_w, restart code gen in wide mode. +// try { +// if (statements != null) { +// for (int i = 0, max = statements.length; i < max; i++) +// statements[i].resetStateForCodeGeneration(); +// } +// classFile.contentsOffset = clinitOffset; +// classFile.methodCount--; +// classFile.codeStream.wideMode = true; // request wide mode +// this.generateCode(classScope, classFile, clinitOffset); +// // restart method generation +// } catch (AbortMethod e2) { +// classFile.contentsOffset = clinitOffset; +// classFile.methodCount--; +// } +// } else { +// // produce a problem method accounting for this fatal error +// classFile.contentsOffset = clinitOffset; +// classFile.methodCount--; +// } +// } +// } + + /** + * Bytecode generation for a method + * + * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope + * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile + */ +// private void generateCode( +// ClassScope classScope, +// ClassFile classFile, +// int clinitOffset) { +// +// ConstantPool constantPool = classFile.constantPool; +// int constantPoolOffset = constantPool.currentOffset; +// int constantPoolIndex = constantPool.currentIndex; +// classFile.generateMethodInfoHeaderForClinit(); +// int codeAttributeOffset = classFile.contentsOffset; +// classFile.generateCodeAttributeHeader(); +// CodeStream codeStream = classFile.codeStream; +// this.resolve(classScope); +// +// codeStream.reset(this, classFile); +// TypeDeclaration declaringType = classScope.referenceContext; +// +// // initialize local positions - including initializer scope. +// MethodScope staticInitializerScope = declaringType.staticInitializerScope; +// staticInitializerScope.computeLocalVariablePositions(0, codeStream); +// +// // 1.4 feature +// // This has to be done before any other initialization +// if (this.assertionSyntheticFieldBinding != null) { +// // generate code related to the activation of assertion for this class +// codeStream.generateClassLiteralAccessForType( +// classScope.enclosingSourceType(), +// classLiteralSyntheticField); +// codeStream.invokeJavaLangClassDesiredAssertionStatus(); +// Label falseLabel = new Label(codeStream); +// codeStream.ifne(falseLabel); +// codeStream.iconst_1(); +// Label jumpLabel = new Label(codeStream); +// codeStream.goto_(jumpLabel); +// falseLabel.place(); +// codeStream.iconst_0(); +// jumpLabel.place(); +// codeStream.putstatic(this.assertionSyntheticFieldBinding); +// } +// // generate initializers +// if (declaringType.fields != null) { +// for (int i = 0, max = declaringType.fields.length; i < max; i++) { +// FieldDeclaration fieldDecl; +// if ((fieldDecl = declaringType.fields[i]).isStatic()) { +// fieldDecl.generateCode(staticInitializerScope, codeStream); +// } +// } +// } +// if (codeStream.position == 0) { +// // do not need to output a Clinit if no bytecodes +// // so we reset the offset inside the byte array contents. +// classFile.contentsOffset = clinitOffset; +// // like we don't addd a method we need to undo the increment on the method count +// classFile.methodCount--; +// // reset the constant pool to its state before the clinit +// constantPool.resetForClinit(constantPoolIndex, constantPoolOffset); +// } else { +// if (this.needFreeReturn) { +// int oldPosition = codeStream.position; +// codeStream.return_(); +// codeStream.updateLocalVariablesAttribute(oldPosition); +// } +// // Record the end of the clinit: point to the declaration of the class +// codeStream.recordPositionsFrom(0, declaringType.sourceStart); +// classFile.completeCodeAttributeForClinit(codeAttributeOffset); +// } +// } + + public boolean isClinit() { + + return true; + } + + public boolean isInitializationMethod() { + + return true; + } + + public boolean isStatic() { + + return true; + } + + public void parseStatements(UnitParser parser, CompilationUnitDeclaration unit) { + //the clinit is filled by hand .... + } + + public void resolve(ClassScope scope) { + + this.scope = new MethodScope(scope, scope.referenceContext, true); + } + + public String toString(int tab) { + + String s = ""; //$NON-NLS-1$ + s = s + tabString(tab); + s = s + "()"; //$NON-NLS-1$ + s = s + toStringStatements(tab + 1); + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + ClassScope classScope) { + + visitor.visit(this, classScope); + visitor.endVisit(this, classScope); + } + + // 1.4 feature + public void addSupportForAssertion(FieldBinding assertionSyntheticFieldBinding) { + + this.assertionSyntheticFieldBinding = assertionSyntheticFieldBinding; + + // we need to add the field right now, because the field infos are generated before the methods + SourceTypeBinding sourceType = + this.scope.outerMostMethodScope().enclosingSourceType(); + this.classLiteralSyntheticField = + sourceType.addSyntheticField(sourceType, scope); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CompilationUnitDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CompilationUnitDeclaration.java new file mode 100644 index 0000000..a3aeef4 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CompilationUnitDeclaration.java @@ -0,0 +1,329 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import java.util.ArrayList; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; +import net.sourceforge.phpdt.internal.compiler.lookup.CompilationUnitScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ImportBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalTypeBinding; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilationUnit; +import net.sourceforge.phpdt.internal.compiler.problem.AbortMethod; +import net.sourceforge.phpdt.internal.compiler.problem.AbortType; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities; + +public class CompilationUnitDeclaration extends AstNode implements ProblemSeverities, ReferenceContext { + + public ImportReference currentPackage; + public ImportReference[] imports; + // public TypeDeclaration[] types; + public ArrayList types; + //public char[][] name; + + public boolean ignoreFurtherInvestigation = false; // once pointless to investigate due to errors + public boolean ignoreMethodBodies = false; + public CompilationUnitScope scope; + public ProblemReporter problemReporter; + public CompilationResult compilationResult; + + private LocalTypeBinding[] localTypes; + int localTypeCount = 0; + + public boolean isPropagatingInnerClassEmulation; + + public CompilationUnitDeclaration(ProblemReporter problemReporter, CompilationResult compilationResult, int sourceLength) { + + this.problemReporter = problemReporter; + this.compilationResult = compilationResult; + this.types = new ArrayList(); + //by definition of a compilation unit.... + sourceStart = 0; + sourceEnd = sourceLength - 1; + + } + + /* + * We cause the compilation task to abort to a given extent. + */ + public void abort(int abortLevel) { + + switch (abortLevel) { + case AbortType : + throw new AbortType(compilationResult); + case AbortMethod : + throw new AbortMethod(compilationResult); + default : + throw new AbortCompilationUnit(compilationResult); + } + } + + /* + * Dispatch code analysis AND request saturation of inner emulation + */ + public void analyseCode() { + + if (ignoreFurtherInvestigation) + return; + try { + if (types != null) { + for (int i = 0, count = types.size(); i < count; i++) { + if (types.get(i) instanceof TypeDeclaration) + ((TypeDeclaration) types.get(i)).analyseCode(scope); + } + } + // request inner emulation propagation + propagateInnerEmulationForAllLocalTypes(); + } catch (AbortCompilationUnit e) { + this.ignoreFurtherInvestigation = true; + return; + } + } + + /* + * When unit result is about to be accepted, removed back pointers + * to compiler structures. + */ + public void cleanUp() { + if (this.types != null) { + for (int i = 0, max = this.types.size(); i < max; i++) { + if (this.types.get(i) instanceof TypeDeclaration) { + cleanUp((TypeDeclaration) this.types.get(i)); + } + } + for (int i = 0, max = this.localTypeCount; i < max; i++) { + // null out the type's scope backpointers + localTypes[i].scope = null; // local members are already in the list + } + } + // ClassFile[] classFiles = compilationResult.getClassFiles(); + // for (int i = 0, max = classFiles.length; i < max; i++) { + // // clear the classFile back pointer to the bindings + // ClassFile classFile = classFiles[i]; + // // null out the classfile backpointer to a type binding + // classFile.referenceBinding = null; + // classFile.codeStream = null; // codeStream holds onto ast and scopes + // classFile.innerClassesBindings = null; + // } + } + private void cleanUp(TypeDeclaration type) { + if (type.memberTypes != null) { + for (int i = 0, max = type.memberTypes.length; i < max; i++) { + cleanUp(type.memberTypes[i]); + } + } + if (type.binding != null) { + // null out the type's scope backpointers + type.binding.scope = null; + } + } + + public void checkUnusedImports() { + + if (this.scope.imports != null) { + for (int i = 0, max = this.scope.imports.length; i < max; i++) { + ImportBinding importBinding = this.scope.imports[i]; + ImportReference importReference = importBinding.reference; + if (importReference != null && !importReference.used) { + scope.problemReporter().unusedImport(importReference); + } + } + } + } + + public CompilationResult compilationResult() { + return compilationResult; + } + + /* + * Finds the matching type amoung this compilation unit types. + * Returns null if no type with this name is found. + * The type name is a compound name + * eg. if we're looking for X.A.B then a type name would be {X, A, B} + */ + public TypeDeclaration declarationOfType(char[][] typeName) { + + for (int i = 0; i < this.types.size(); i++) { + if (this.types.get(i) instanceof TypeDeclaration) { + TypeDeclaration typeDecl = ((TypeDeclaration) this.types.get(i)).declarationOfType(typeName); + if (typeDecl != null) { + return typeDecl; + } + } + } + return null; + } + + /** + * Bytecode generation + */ + // public void generateCode() { + // + // if (ignoreFurtherInvestigation) { + // if (types != null) { + // for (int i = 0, count = types.length; i < count; i++) { + // types[i].ignoreFurtherInvestigation = true; + // // propagate the flag to request problem type creation + // types[i].generateCode(scope); + // } + // } + // return; + // } + // try { + // if (types != null) { + // for (int i = 0, count = types.length; i < count; i++) + // types[i].generateCode(scope); + // } + // } catch (AbortCompilationUnit e) { + // } + // } + + public char[] getFileName() { + + return compilationResult.getFileName(); + } + + public char[] getMainTypeName() { + + if (compilationResult.compilationUnit == null) { + char[] fileName = compilationResult.getFileName(); + + int start = CharOperation.lastIndexOf('/', fileName) + 1; + if (start == 0 || start < CharOperation.lastIndexOf('\\', fileName)) + start = CharOperation.lastIndexOf('\\', fileName) + 1; + + int end = CharOperation.lastIndexOf('.', fileName); + if (end == -1) + end = fileName.length; + + return CharOperation.subarray(fileName, start, end); + } else { + return compilationResult.compilationUnit.getMainTypeName(); + } + } + + public boolean isEmpty() { + + return (currentPackage == null) && (imports == null) && (types == null); + } + + public boolean hasErrors() { + return this.ignoreFurtherInvestigation; + } + + /* + * Force inner local types to update their innerclass emulation + */ + public void propagateInnerEmulationForAllLocalTypes() { + + isPropagatingInnerClassEmulation = true; + for (int i = 0, max = this.localTypeCount; i < max; i++) { + + LocalTypeBinding localType = localTypes[i]; + // only propagate for reachable local types + if ((localType.scope.referenceType().bits & IsReachableMASK) != 0) { + localType.updateInnerEmulationDependents(); + } + } + } + + /* + * Keep track of all local types, so as to update their innerclass + * emulation later on. + */ + public void record(LocalTypeBinding localType) { + + if (this.localTypeCount == 0) { + this.localTypes = new LocalTypeBinding[5]; + } else if (this.localTypeCount == this.localTypes.length) { + System.arraycopy( + this.localTypes, + 0, + (this.localTypes = new LocalTypeBinding[this.localTypeCount * 2]), + 0, + this.localTypeCount); + } + this.localTypes[this.localTypeCount++] = localType; + } + + public void resolve() { + + try { + if (types != null) { + for (int i = 0, count = types.size(); i < count; i++) { + if (types.get(i) instanceof TypeDeclaration) { + ((TypeDeclaration) types.get(i)).resolve(scope); + } + } + } +// if (!this.compilationResult.hasSyntaxError()) +// checkUnusedImports(); + } catch (AbortCompilationUnit e) { + this.ignoreFurtherInvestigation = true; + return; + } + } + + public void tagAsHavingErrors() { + ignoreFurtherInvestigation = true; + } + + public String toString(int tab) { + + String s = ""; //$NON-NLS-1$ + if (currentPackage != null) + s = tabString(tab) + "package " + currentPackage.toString(0, false) + ";\n"; //$NON-NLS-1$ //$NON-NLS-2$ + + if (imports != null) + for (int i = 0; i < imports.length; i++) { + s += tabString(tab) + "import " + imports[i].toString() + ";\n"; //$NON-NLS-1$ //$NON-NLS-2$ + }; + + if (types != null) + for (int i = 0; i < types.size(); i++) { + s += ((AstNode) types.get(i)).toString(tab) + "\n"; //$NON-NLS-1$ + } + return s; + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, CompilationUnitScope scope) { + + if (ignoreFurtherInvestigation) + return; + try { + if (visitor.visit(this, scope)) { + if (currentPackage != null) { + currentPackage.traverse(visitor, scope); + } + if (imports != null) { + int importLength = imports.length; + for (int i = 0; i < importLength; i++) { + imports[i].traverse(visitor, scope); + } + } + if (types != null) { + int typesLength = types.size(); + for (int i = 0; i < typesLength; i++) { + if (types.get(i) instanceof TypeDeclaration) { + ((TypeDeclaration) types.get(i)).traverse(visitor, scope); + } + } + } + } + visitor.endVisit(this, scope); + } catch (AbortCompilationUnit e) { + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CompoundAssignment.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CompoundAssignment.java new file mode 100644 index 0000000..fed69c7 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CompoundAssignment.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class CompoundAssignment extends Assignment implements OperatorIds { + public int operator; + public int assignmentImplicitConversion; + + // var op exp is equivalent to var = (varType) var op exp + // assignmentImplicitConversion stores the cast needed for the assignment + +public CompoundAssignment(Expression lhs, Expression expression,int operator, int sourceEnd) { + //lhs is always a reference by construction , + //but is build as an expression ==> the checkcast cannot fail + + super(lhs, expression, sourceEnd); + lhs.bits &= ~IsStrictlyAssignedMASK; // tag lhs as NON assigned - it is also a read access + this.operator = operator ; +} +public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { + // record setting a variable: various scenarii are possible, setting an array reference, + // a field reference, a blank final field reference, a field of an enclosing instance or + // just a local variable. + + return ((Reference) lhs).analyseAssignment(currentScope, flowContext, flowInfo, this, true).unconditionalInits(); +} +//public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { +// +// // various scenarii are possible, setting an array reference, +// // a field reference, a blank final field reference, a field of an enclosing instance or +// // just a local variable. +// +// int pc = codeStream.position; +// ((Reference) lhs).generateCompoundAssignment(currentScope, codeStream, expression, operator, assignmentImplicitConversion, valueRequired); +// if (valueRequired) { +// codeStream.generateImplicitConversion(implicitConversion); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +public String operatorToString() { + switch (operator) { + case PLUS : + return "+="; //$NON-NLS-1$ + case MINUS : + return "-="; //$NON-NLS-1$ + case MULTIPLY : + return "*="; //$NON-NLS-1$ + case DIVIDE : + return "/="; //$NON-NLS-1$ + case AND : + return "&="; //$NON-NLS-1$ + case OR : + return "|="; //$NON-NLS-1$ + case XOR : + return "^="; //$NON-NLS-1$ + case REMAINDER : + return "%="; //$NON-NLS-1$ + case LEFT_SHIFT : + return "<<="; //$NON-NLS-1$ + case RIGHT_SHIFT : + return ">>="; //$NON-NLS-1$ + case UNSIGNED_RIGHT_SHIFT : + return ">>>="; //$NON-NLS-1$ + }; + return "unknown operator"; //$NON-NLS-1$ +} +public TypeBinding resolveType(BlockScope scope) { + constant = NotAConstant; + if (!(this.lhs instanceof Reference)) { + scope.problemReporter().expressionShouldBeAVariable(this.lhs); + } + TypeBinding lhsType = lhs.resolveType(scope); + TypeBinding expressionType = expression.resolveType(scope); + if (lhsType == null || expressionType == null) + return null; + + int lhsId = lhsType.id; + int expressionId = expressionType.id; + if (restrainUsageToNumericTypes() && !lhsType.isNumericType()) { + scope.problemReporter().operatorOnlyValidOnNumericType(this, lhsType, expressionType); + return null; + } + if (lhsId > 15 || expressionId > 15) { + if (lhsId != T_String) { // String += Object is valid wheraas Object -= String is not + scope.problemReporter().invalidOperator(this, lhsType, expressionType); + return null; + } + expressionId = T_Object; // use the Object has tag table + } + + // the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 <<0 + + // the conversion is stored INTO the reference (info needed for the code gen) + int result = OperatorExpression.ResolveTypeTables[operator][ (lhsId << 4) + expressionId]; + if (result == T_undefined) { + scope.problemReporter().invalidOperator(this, lhsType, expressionType); + return null; + } + if (operator == PLUS){ + if(scope.isJavaLangObject(lhsType)) { + // += is illegal + scope.problemReporter().invalidOperator(this, lhsType, expressionType); + return null; + } else if ((lhsType.isNumericType() || lhsId == T_boolean) && !expressionType.isNumericType()){ + // += is illegal + scope.problemReporter().invalidOperator(this, lhsType, expressionType); + return null; + } + } + lhs.implicitConversion = result >>> 12; + expression.implicitConversion = (result >>> 4) & 0x000FF; + assignmentImplicitConversion = (lhsId << 4) + (result & 0x0000F); + return this.resolvedType = lhsType; +} +public boolean restrainUsageToNumericTypes(){ + return false ;} +public String toStringExpressionNoParenthesis() { + + return lhs.toStringExpression() + " " + //$NON-NLS-1$ + operatorToString() + " " + //$NON-NLS-1$ + expression.toStringExpression() ; } +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + if (visitor.visit(this, scope)) { + lhs.traverse(visitor, scope); + expression.traverse(visitor, scope); + } + visitor.endVisit(this, scope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ConditionalExpression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ConditionalExpression.java new file mode 100644 index 0000000..dabfd54 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ConditionalExpression.java @@ -0,0 +1,425 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.UnconditionalFlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BaseTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class ConditionalExpression extends OperatorExpression { + + public Expression condition, valueIfTrue, valueIfFalse; + public Constant optimizedBooleanConstant; + public Constant optimizedIfTrueConstant; + public Constant optimizedIfFalseConstant; + + private int returnTypeSlotSize = 1; + + // for local variables table attributes + int trueInitStateIndex = -1; + int falseInitStateIndex = -1; + int mergedInitStateIndex = -1; + + public ConditionalExpression( + Expression condition, + Expression valueIfTrue, + Expression valueIfFalse) { + this.condition = condition; + this.valueIfTrue = valueIfTrue; + this.valueIfFalse = valueIfFalse; + sourceStart = condition.sourceStart; + sourceEnd = valueIfFalse.sourceEnd; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + Constant cst = this.condition.optimizedBooleanConstant(); + boolean isConditionOptimizedTrue = cst != NotAConstant && cst.booleanValue() == true; + boolean isConditionOptimizedFalse = cst != NotAConstant && cst.booleanValue() == false; + + int mode = flowInfo.reachMode(); + flowInfo = condition.analyseCode(currentScope, flowContext, flowInfo, cst == NotAConstant); + + // process the if-true part + FlowInfo trueFlowInfo = flowInfo.initsWhenTrue().copy(); + if (isConditionOptimizedFalse) { + trueFlowInfo.setReachMode(FlowInfo.UNREACHABLE); + } + trueInitStateIndex = currentScope.methodScope().recordInitializationStates(trueFlowInfo); + trueFlowInfo = valueIfTrue.analyseCode(currentScope, flowContext, trueFlowInfo); + + // process the if-false part + FlowInfo falseFlowInfo = flowInfo.initsWhenFalse().copy(); + if (isConditionOptimizedTrue) { + falseFlowInfo.setReachMode(FlowInfo.UNREACHABLE); + } + falseInitStateIndex = currentScope.methodScope().recordInitializationStates(falseFlowInfo); + falseFlowInfo = valueIfFalse.analyseCode(currentScope, flowContext, falseFlowInfo); + + // merge if-true & if-false initializations + FlowInfo mergedInfo; + if (isConditionOptimizedTrue){ + mergedInfo = trueFlowInfo.addPotentialInitializationsFrom(falseFlowInfo); + } else if (isConditionOptimizedFalse) { + mergedInfo = falseFlowInfo.addPotentialInitializationsFrom(trueFlowInfo); + } else { + // merge using a conditional info - 1GK2BLM + // if ((t && (v = t)) ? t : t && (v = f)) r = v; -- ok + cst = this.optimizedIfTrueConstant; + boolean isValueIfTrueOptimizedTrue = cst != null && cst != NotAConstant && cst.booleanValue() == true; + boolean isValueIfTrueOptimizedFalse = cst != null && cst != NotAConstant && cst.booleanValue() == false; + + cst = this.optimizedIfFalseConstant; + boolean isValueIfFalseOptimizedTrue = cst != null && cst != NotAConstant && cst.booleanValue() == true; + boolean isValueIfFalseOptimizedFalse = cst != null && cst != NotAConstant && cst.booleanValue() == false; + + UnconditionalFlowInfo trueInfoWhenTrue = trueFlowInfo.initsWhenTrue().copy().unconditionalInits(); + if (isValueIfTrueOptimizedFalse) trueInfoWhenTrue.setReachMode(FlowInfo.UNREACHABLE); + + UnconditionalFlowInfo falseInfoWhenTrue = falseFlowInfo.initsWhenTrue().copy().unconditionalInits(); + if (isValueIfFalseOptimizedFalse) falseInfoWhenTrue.setReachMode(FlowInfo.UNREACHABLE); + + UnconditionalFlowInfo trueInfoWhenFalse = trueFlowInfo.initsWhenFalse().copy().unconditionalInits(); + if (isValueIfTrueOptimizedTrue) trueInfoWhenFalse.setReachMode(FlowInfo.UNREACHABLE); + + UnconditionalFlowInfo falseInfoWhenFalse = falseFlowInfo.initsWhenFalse().copy().unconditionalInits(); + if (isValueIfFalseOptimizedTrue) falseInfoWhenFalse.setReachMode(FlowInfo.UNREACHABLE); + + mergedInfo = + FlowInfo.conditional( + trueInfoWhenTrue.mergedWith(falseInfoWhenTrue), + trueInfoWhenFalse.mergedWith(falseInfoWhenFalse)); + } + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(mergedInfo); + mergedInfo.setReachMode(mode); + return mergedInfo; + } + + /** + * Code generation for the conditional operator ?: + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// int pc = codeStream.position; +// Label endifLabel, falseLabel; +// if (constant != NotAConstant) { +// if (valueRequired) +// codeStream.generateConstant(constant, implicitConversion); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// return; +// } +// Constant cst = condition.constant; +// Constant condCst = condition.optimizedBooleanConstant(); +// boolean needTruePart = +// !(((cst != NotAConstant) && (cst.booleanValue() == false)) +// || ((condCst != NotAConstant) && (condCst.booleanValue() == false))); +// boolean needFalsePart = +// !(((cst != NotAConstant) && (cst.booleanValue() == true)) +// || ((condCst != NotAConstant) && (condCst.booleanValue() == true))); +// endifLabel = new Label(codeStream); +// +// // Generate code for the condition +// boolean needConditionValue = (cst == NotAConstant) && (condCst == NotAConstant); +// condition.generateOptimizedBoolean( +// currentScope, +// codeStream, +// null, +// (falseLabel = new Label(codeStream)), +// needConditionValue); +// +// if (trueInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// trueInitStateIndex); +// codeStream.addDefinitelyAssignedVariables(currentScope, trueInitStateIndex); +// } +// // Then code generation +// if (needTruePart) { +// valueIfTrue.generateCode(currentScope, codeStream, valueRequired); +// if (needFalsePart) { +// // Jump over the else part +// int position = codeStream.position; +// codeStream.goto_(endifLabel); +// codeStream.updateLastRecordedEndPC(position); +// // Tune codestream stack size +// if (valueRequired) { +// codeStream.decrStackSize(returnTypeSlotSize); +// } +// } +// } +// if (needFalsePart) { +// falseLabel.place(); +// if (falseInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// falseInitStateIndex); +// codeStream.addDefinitelyAssignedVariables(currentScope, falseInitStateIndex); +// } +// valueIfFalse.generateCode(currentScope, codeStream, valueRequired); +// // End of if statement +// endifLabel.place(); +// } +// // May loose some local variable initializations : affecting the local variable attributes +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// // implicit conversion +// if (valueRequired) +// codeStream.generateImplicitConversion(implicitConversion); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } +// +// /** +// * Optimized boolean code generation for the conditional operator ?: +// */ +// public void generateOptimizedBoolean( +// BlockScope currentScope, +// CodeStream codeStream, +// Label trueLabel, +// Label falseLabel, +// boolean valueRequired) { +// +// if ((constant != Constant.NotAConstant) && (constant.typeID() == T_boolean) // constant +// || (valueIfTrue.implicitConversion >> 4) != T_boolean) { // non boolean values +// super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired); +// return; +// } +// Constant cst = condition.constant; +// Constant condCst = condition.optimizedBooleanConstant(); +// boolean needTruePart = +// !(((cst != NotAConstant) && (cst.booleanValue() == false)) +// || ((condCst != NotAConstant) && (condCst.booleanValue() == false))); +// boolean needFalsePart = +// !(((cst != NotAConstant) && (cst.booleanValue() == true)) +// || ((condCst != NotAConstant) && (condCst.booleanValue() == true))); +// +// Label internalFalseLabel, endifLabel = new Label(codeStream); +// +// // Generate code for the condition +// boolean needConditionValue = (cst == NotAConstant) && (condCst == NotAConstant); +// condition.generateOptimizedBoolean( +// currentScope, +// codeStream, +// null, +// internalFalseLabel = new Label(codeStream), +// needConditionValue); +// +// if (trueInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// trueInitStateIndex); +// codeStream.addDefinitelyAssignedVariables(currentScope, trueInitStateIndex); +// } +// // Then code generation +// if (needTruePart) { +// valueIfTrue.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired); +// +// if (needFalsePart) { +// // Jump over the else part +// int position = codeStream.position; +// codeStream.goto_(endifLabel); +// codeStream.updateLastRecordedEndPC(position); +// // No need to decrement codestream stack size +// // since valueIfTrue was already consumed by branch bytecode +// } +// } +// if (needFalsePart) { +// internalFalseLabel.place(); +// if (falseInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// falseInitStateIndex); +// codeStream.addDefinitelyAssignedVariables(currentScope, falseInitStateIndex); +// } +// valueIfFalse.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired); +// +// // End of if statement +// endifLabel.place(); +// } +// // May loose some local variable initializations : affecting the local variable attributes +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// // no implicit conversion for boolean values +// codeStream.updateLastRecordedEndPC(codeStream.position); +// } +// +// public Constant optimizedBooleanConstant() { +// +// return this.optimizedBooleanConstant == null ? this.constant : this.optimizedBooleanConstant; +// } +// +// public TypeBinding resolveType(BlockScope scope) { +// // specs p.368 +// constant = NotAConstant; +// TypeBinding conditionType = condition.resolveTypeExpecting(scope, BooleanBinding); +// TypeBinding valueIfTrueType = valueIfTrue.resolveType(scope); +// TypeBinding valueIfFalseType = valueIfFalse.resolveType(scope); +// if (conditionType == null || valueIfTrueType == null || valueIfFalseType == null) +// return null; +// +// // Propagate the constant value from the valueIfTrue and valueIFFalse expression if it is possible +// Constant condConstant, trueConstant, falseConstant; +// if ((condConstant = condition.constant) != NotAConstant +// && (trueConstant = valueIfTrue.constant) != NotAConstant +// && (falseConstant = valueIfFalse.constant) != NotAConstant) { +// // all terms are constant expression so we can propagate the constant +// // from valueIFTrue or valueIfFalse to teh receiver constant +// constant = condConstant.booleanValue() ? trueConstant : falseConstant; +// } +// if (valueIfTrueType == valueIfFalseType) { // harmed the implicit conversion +// valueIfTrue.implicitWidening(valueIfTrueType, valueIfTrueType); +// valueIfFalse.implicitConversion = valueIfTrue.implicitConversion; +// if (valueIfTrueType == LongBinding || valueIfTrueType == DoubleBinding) { +// returnTypeSlotSize = 2; +// } +// +// if (valueIfTrueType == BooleanBinding) { +// this.optimizedIfTrueConstant = valueIfTrue.optimizedBooleanConstant(); +// this.optimizedIfFalseConstant = valueIfFalse.optimizedBooleanConstant(); +// +// // Propagate the optimized boolean constant if possible +// if ((condConstant = condition.optimizedBooleanConstant()) != NotAConstant) { +// +// this.optimizedBooleanConstant = condConstant.booleanValue() +// ? optimizedIfTrueConstant +// : optimizedIfFalseConstant; +// } +// } +// return this.resolvedType = valueIfTrueType; +// } +// // Determine the return type depending on argument types +// // Numeric types +// if (valueIfTrueType.isNumericType() && valueIfFalseType.isNumericType()) { +// // (Short x Byte) or (Byte x Short)" +// if ((valueIfTrueType == ByteBinding && valueIfFalseType == ShortBinding) +// || (valueIfTrueType == ShortBinding && valueIfFalseType == ByteBinding)) { +// valueIfTrue.implicitWidening(ShortBinding, valueIfTrueType); +// valueIfFalse.implicitWidening(ShortBinding, valueIfFalseType); +// this.resolvedType = ShortBinding; +// return ShortBinding; +// } +// // x constant(Int) ---> and reciprocally +// if ((valueIfTrueType == ByteBinding || valueIfTrueType == ShortBinding || valueIfTrueType == CharBinding) +// && (valueIfFalseType == IntBinding +// && valueIfFalse.isConstantValueOfTypeAssignableToType(valueIfFalseType, valueIfTrueType))) { +// valueIfTrue.implicitWidening(valueIfTrueType, valueIfTrueType); +// valueIfFalse.implicitWidening(valueIfTrueType, valueIfFalseType); +// this.resolvedType = valueIfTrueType; +// return valueIfTrueType; +// } +// if ((valueIfFalseType == ByteBinding +// || valueIfFalseType == ShortBinding +// || valueIfFalseType == CharBinding) +// && (valueIfTrueType == IntBinding +// && valueIfTrue.isConstantValueOfTypeAssignableToType(valueIfTrueType, valueIfFalseType))) { +// valueIfTrue.implicitWidening(valueIfFalseType, valueIfTrueType); +// valueIfFalse.implicitWidening(valueIfFalseType, valueIfFalseType); +// this.resolvedType = valueIfFalseType; +// return valueIfFalseType; +// } +// // Manual binary numeric promotion +// // int +// if (BaseTypeBinding.isNarrowing(valueIfTrueType.id, T_int) +// && BaseTypeBinding.isNarrowing(valueIfFalseType.id, T_int)) { +// valueIfTrue.implicitWidening(IntBinding, valueIfTrueType); +// valueIfFalse.implicitWidening(IntBinding, valueIfFalseType); +// this.resolvedType = IntBinding; +// return IntBinding; +// } +// // long +// if (BaseTypeBinding.isNarrowing(valueIfTrueType.id, T_long) +// && BaseTypeBinding.isNarrowing(valueIfFalseType.id, T_long)) { +// valueIfTrue.implicitWidening(LongBinding, valueIfTrueType); +// valueIfFalse.implicitWidening(LongBinding, valueIfFalseType); +// returnTypeSlotSize = 2; +// this.resolvedType = LongBinding; +// return LongBinding; +// } +// // float +// if (BaseTypeBinding.isNarrowing(valueIfTrueType.id, T_float) +// && BaseTypeBinding.isNarrowing(valueIfFalseType.id, T_float)) { +// valueIfTrue.implicitWidening(FloatBinding, valueIfTrueType); +// valueIfFalse.implicitWidening(FloatBinding, valueIfFalseType); +// this.resolvedType = FloatBinding; +// return FloatBinding; +// } +// // double +// valueIfTrue.implicitWidening(DoubleBinding, valueIfTrueType); +// valueIfFalse.implicitWidening(DoubleBinding, valueIfFalseType); +// returnTypeSlotSize = 2; +// this.resolvedType = DoubleBinding; +// return DoubleBinding; +// } +// // Type references (null null is already tested) +// if ((valueIfTrueType.isBaseType() && valueIfTrueType != NullBinding) +// || (valueIfFalseType.isBaseType() && valueIfFalseType != NullBinding)) { +// scope.problemReporter().conditionalArgumentsIncompatibleTypes( +// this, +// valueIfTrueType, +// valueIfFalseType); +// return null; +// } +// if (valueIfFalseType.isCompatibleWith(valueIfTrueType)) { +// valueIfTrue.implicitWidening(valueIfTrueType, valueIfTrueType); +// valueIfFalse.implicitWidening(valueIfTrueType, valueIfFalseType); +// this.resolvedType = valueIfTrueType; +// return valueIfTrueType; +// } +// if (valueIfTrueType.isCompatibleWith(valueIfFalseType)) { +// valueIfTrue.implicitWidening(valueIfFalseType, valueIfTrueType); +// valueIfFalse.implicitWidening(valueIfFalseType, valueIfFalseType); +// this.resolvedType = valueIfFalseType; +// return valueIfFalseType; +// } +// scope.problemReporter().conditionalArgumentsIncompatibleTypes( +// this, +// valueIfTrueType, +// valueIfFalseType); +// return null; +// } + + public String toStringExpressionNoParenthesis() { + return condition.toStringExpression() + " ? " + //$NON-NLS-1$ + valueIfTrue.toStringExpression() + " : " + //$NON-NLS-1$ + valueIfFalse.toStringExpression(); + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + if (visitor.visit(this, scope)) { + condition.traverse(visitor, scope); + valueIfTrue.traverse(visitor, scope); + valueIfFalse.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ConstructorDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ConstructorDeclaration.java new file mode 100644 index 0000000..6e62d47 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ConstructorDeclaration.java @@ -0,0 +1,447 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import java.util.ArrayList; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.ExceptionHandlingFlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.InitializationFlowContext; +import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.parser.UnitParser; +import net.sourceforge.phpdt.internal.compiler.problem.AbortMethod; + + +public class ConstructorDeclaration extends AbstractMethodDeclaration { + + public ExplicitConstructorCall constructorCall; + public final static char[] ConstantPoolName = "".toCharArray(); //$NON-NLS-1$ + public boolean isDefaultConstructor = false; + + public ConstructorDeclaration(CompilationResult compilationResult){ + super(compilationResult); + } + + public void analyseCode( + ClassScope classScope, + InitializationFlowContext initializerFlowContext, + FlowInfo flowInfo) { + + if (ignoreFurtherInvestigation) + return; + + if (this.binding != null && this.binding.isPrivate() && !this.binding.isPrivateUsed()) { + if (!classScope.referenceCompilationUnit().compilationResult.hasSyntaxError()) { + scope.problemReporter().unusedPrivateConstructor(this); + } + } + + // check constructor recursion, once all constructor got resolved + if (isRecursive(null /*lazy initialized visited list*/)) { + this.scope.problemReporter().recursiveConstructorInvocation(this.constructorCall); + } + + try { + ExceptionHandlingFlowContext constructorContext = + new ExceptionHandlingFlowContext( + initializerFlowContext.parent, + this, + binding.thrownExceptions, + scope, + FlowInfo.DEAD_END); + initializerFlowContext.checkInitializerExceptions( + scope, + constructorContext, + flowInfo); + + // anonymous constructor can gain extra thrown exceptions from unhandled ones + if (binding.declaringClass.isAnonymousType()) { + ArrayList computedExceptions = constructorContext.extendedExceptions; + if (computedExceptions != null){ + int size; + if ((size = computedExceptions.size()) > 0){ + ReferenceBinding[] actuallyThrownExceptions; + computedExceptions.toArray(actuallyThrownExceptions = new ReferenceBinding[size]); + binding.thrownExceptions = actuallyThrownExceptions; + } + } + } + + // propagate to constructor call + if (constructorCall != null) { + // if calling 'this(...)', then flag all non-static fields as definitely + // set since they are supposed to be set inside other local constructor + if (constructorCall.accessMode == ExplicitConstructorCall.This) { + FieldBinding[] fields = binding.declaringClass.fields(); + for (int i = 0, count = fields.length; i < count; i++) { + FieldBinding field; + if (!(field = fields[i]).isStatic()) { + flowInfo.markAsDefinitelyAssigned(field); + } + } + } + flowInfo = constructorCall.analyseCode(scope, constructorContext, flowInfo); + } + // propagate to statements + if (statements != null) { + boolean didAlreadyComplain = false; + for (int i = 0, count = statements.length; i < count; i++) { + Statement stat; + if (!flowInfo.complainIfUnreachable(stat = statements[i], scope, didAlreadyComplain)) { + flowInfo = stat.analyseCode(scope, constructorContext, flowInfo); + } else { + didAlreadyComplain = true; + } + } + } + // check for missing returning path + this.needFreeReturn = flowInfo.isReachable(); + + // check missing blank final field initializations + if ((constructorCall != null) + && (constructorCall.accessMode != ExplicitConstructorCall.This)) { + flowInfo = flowInfo.mergedWith(constructorContext.initsOnReturn); + FieldBinding[] fields = binding.declaringClass.fields(); + for (int i = 0, count = fields.length; i < count; i++) { + FieldBinding field; + if ((!(field = fields[i]).isStatic()) + && field.isFinal() + && (!flowInfo.isDefinitelyAssigned(fields[i]))) { + scope.problemReporter().uninitializedBlankFinalField( + field, + isDefaultConstructor ? (AstNode) scope.referenceType() : this); + } + } + } + } catch (AbortMethod e) { + this.ignoreFurtherInvestigation = true; + } + } + + /** + * Bytecode generation for a constructor + * + * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope + * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile + */ +// public void generateCode(ClassScope classScope, ClassFile classFile) { +// +// int problemResetPC = 0; +// if (ignoreFurtherInvestigation) { +// if (this.binding == null) +// return; // Handle methods with invalid signature or duplicates +// int problemsLength; +// IProblem[] problems = +// scope.referenceCompilationUnit().compilationResult.getProblems(); +// IProblem[] problemsCopy = new IProblem[problemsLength = problems.length]; +// System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); +// classFile.addProblemConstructor(this, binding, problemsCopy); +// return; +// } +// try { +// problemResetPC = classFile.contentsOffset; +// this.internalGenerateCode(classScope, classFile); +// } catch (AbortMethod e) { +// if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) { +// // a branch target required a goto_w, restart code gen in wide mode. +// try { +// if (statements != null) { +// for (int i = 0, max = statements.length; i < max; i++) +// statements[i].resetStateForCodeGeneration(); +// } +// classFile.contentsOffset = problemResetPC; +// classFile.methodCount--; +// classFile.codeStream.wideMode = true; // request wide mode +// this.internalGenerateCode(classScope, classFile); // restart method generation +// } catch (AbortMethod e2) { +// int problemsLength; +// IProblem[] problems = +// scope.referenceCompilationUnit().compilationResult.getAllProblems(); +// IProblem[] problemsCopy = new IProblem[problemsLength = problems.length]; +// System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); +// classFile.addProblemConstructor(this, binding, problemsCopy, problemResetPC); +// } +// } else { +// int problemsLength; +// IProblem[] problems = +// scope.referenceCompilationUnit().compilationResult.getAllProblems(); +// IProblem[] problemsCopy = new IProblem[problemsLength = problems.length]; +// System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); +// classFile.addProblemConstructor(this, binding, problemsCopy, problemResetPC); +// } +// } +// } +// +// public void generateSyntheticFieldInitializationsIfNecessary( +// MethodScope scope, +// CodeStream codeStream, +// ReferenceBinding declaringClass) { +// +// if (!declaringClass.isNestedType()) return; +// +// NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass; +// +// SyntheticArgumentBinding[] syntheticArgs = nestedType.syntheticEnclosingInstances(); +// for (int i = 0, max = syntheticArgs == null ? 0 : syntheticArgs.length; i < max; i++) { +// SyntheticArgumentBinding syntheticArg; +// if ((syntheticArg = syntheticArgs[i]).matchingField != null) { +// codeStream.aload_0(); +// codeStream.load(syntheticArg); +// codeStream.putfield(syntheticArg.matchingField); +// } +// } +// syntheticArgs = nestedType.syntheticOuterLocalVariables(); +// for (int i = 0, max = syntheticArgs == null ? 0 : syntheticArgs.length; i < max; i++) { +// SyntheticArgumentBinding syntheticArg; +// if ((syntheticArg = syntheticArgs[i]).matchingField != null) { +// codeStream.aload_0(); +// codeStream.load(syntheticArg); +// codeStream.putfield(syntheticArg.matchingField); +// } +// } +// } +// +// private void internalGenerateCode(ClassScope classScope, ClassFile classFile) { +// +// classFile.generateMethodInfoHeader(binding); +// int methodAttributeOffset = classFile.contentsOffset; +// int attributeNumber = classFile.generateMethodInfoAttribute(binding); +// if ((!binding.isNative()) && (!binding.isAbstract())) { +// +// TypeDeclaration declaringType = classScope.referenceContext; +// int codeAttributeOffset = classFile.contentsOffset; +// classFile.generateCodeAttributeHeader(); +// CodeStream codeStream = classFile.codeStream; +// codeStream.reset(this, classFile); +// +// // initialize local positions - including initializer scope. +// ReferenceBinding declaringClass = binding.declaringClass; +// +// int argSlotSize = 1; // this==aload0 +// +// if (declaringClass.isNestedType()){ +// NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass; +// this.scope.extraSyntheticArguments = nestedType.syntheticOuterLocalVariables(); +// scope.computeLocalVariablePositions(// consider synthetic arguments if any +// nestedType.enclosingInstancesSlotSize + 1, +// codeStream); +// argSlotSize += nestedType.enclosingInstancesSlotSize; +// argSlotSize += nestedType.outerLocalVariablesSlotSize; +// } else { +// scope.computeLocalVariablePositions(1, codeStream); +// } +// +// if (arguments != null) { +// for (int i = 0, max = arguments.length; i < max; i++) { +// // arguments initialization for local variable debug attributes +// LocalVariableBinding argBinding; +// codeStream.addVisibleLocalVariable(argBinding = arguments[i].binding); +// argBinding.recordInitializationStartPC(0); +// TypeBinding argType; +// if ((argType = argBinding.type) == LongBinding || (argType == DoubleBinding)) { +// argSlotSize += 2; +// } else { +// argSlotSize++; +// } +// } +// } +// +// MethodScope initializerScope = declaringType.initializerScope; +// initializerScope.computeLocalVariablePositions(argSlotSize, codeStream); // offset by the argument size (since not linked to method scope) +// +// boolean needFieldInitializations = constructorCall == null || constructorCall.accessMode != ExplicitConstructorCall.This; +// +// // post 1.4 source level, synthetic initializations occur prior to explicit constructor call +// boolean preInitSyntheticFields = scope.environment().options.targetJDK >= CompilerOptions.JDK1_4; +// +// if (needFieldInitializations && preInitSyntheticFields){ +// generateSyntheticFieldInitializationsIfNecessary(scope, codeStream, declaringClass); +// } +// // generate constructor call +// if (constructorCall != null) { +// constructorCall.generateCode(scope, codeStream); +// } +// // generate field initialization - only if not invoking another constructor call of the same class +// if (needFieldInitializations) { +// if (!preInitSyntheticFields){ +// generateSyntheticFieldInitializationsIfNecessary(scope, codeStream, declaringClass); +// } +// // generate user field initialization +// if (declaringType.fields != null) { +// for (int i = 0, max = declaringType.fields.length; i < max; i++) { +// FieldDeclaration fieldDecl; +// if (!(fieldDecl = declaringType.fields[i]).isStatic()) { +// fieldDecl.generateCode(initializerScope, codeStream); +// } +// } +// } +// } +// // generate statements +// if (statements != null) { +// for (int i = 0, max = statements.length; i < max; i++) { +// statements[i].generateCode(scope, codeStream); +// } +// } +// if (this.needFreeReturn) { +// codeStream.return_(); +// } +// // local variable attributes +// codeStream.exitUserScope(scope); +// codeStream.recordPositionsFrom(0, this.bodyEnd); +// classFile.completeCodeAttribute(codeAttributeOffset); +// attributeNumber++; +// } +// classFile.completeMethodInfo(methodAttributeOffset, attributeNumber); +// +// // if a problem got reported during code gen, then trigger problem method creation +// if (ignoreFurtherInvestigation) { +// throw new AbortMethod(scope.referenceCompilationUnit().compilationResult); +// } +// } + + public boolean isConstructor() { + + return true; + } + + public boolean isDefaultConstructor() { + + return isDefaultConstructor; + } + + public boolean isInitializationMethod() { + + return true; + } + + /** + * Returns true if the constructor is directly involved in a cycle. + * Given most constructors aren't, we only allocate the visited list + * lazily. + */ + public boolean isRecursive(ArrayList visited) { + + if (this.binding == null + || this.constructorCall == null + || this.constructorCall.binding == null + || this.constructorCall.isSuperAccess() + || !this.constructorCall.binding.isValidBinding()) { + return false; + } + + ConstructorDeclaration targetConstructor = + ((ConstructorDeclaration)this.scope.referenceType().declarationOf(constructorCall.binding)); + if (this == targetConstructor) return true; // direct case + + if (visited == null) { // lazy allocation + visited = new ArrayList(1); + } else { + int index = visited.indexOf(this); + if (index >= 0) return index == 0; // only blame if directly part of the cycle + } + visited.add(this); + + return targetConstructor.isRecursive(visited); + } + + public void parseStatements(UnitParser parser, CompilationUnitDeclaration unit) { + + //fill up the constructor body with its statements + if (ignoreFurtherInvestigation) + return; + if (isDefaultConstructor){ + constructorCall = SuperReference.implicitSuperConstructorCall(); + constructorCall.sourceStart = sourceStart; + constructorCall.sourceEnd = sourceEnd; + return; + } + parser.parse(this, unit); + + } + + /* + * Type checking for constructor, just another method, except for special check + * for recursive constructor invocations. + */ + public void resolveStatements() { + + if (!CharOperation.equals(scope.enclosingSourceType().sourceName, selector)){ + scope.problemReporter().missingReturnType(this); + } + + // if null ==> an error has occurs at parsing time .... + if (this.constructorCall != null) { + // e.g. using super() in java.lang.Object + if (this.binding != null + && this.binding.declaringClass.id == T_Object + && this.constructorCall.accessMode != ExplicitConstructorCall.This) { + if (this.constructorCall.accessMode == ExplicitConstructorCall.Super) { + scope.problemReporter().cannotUseSuperInJavaLangObject(this.constructorCall); + } + this.constructorCall = null; + } else { + this.constructorCall.resolve(this.scope); + } + } + + super.resolveStatements(); + } + + public String toStringStatements(int tab) { + + String s = " {"; //$NON-NLS-1$ + if (constructorCall != null) { + s = s + "\n" + constructorCall.toString(tab) + ";"; //$NON-NLS-1$ //$NON-NLS-2$ + } + if (statements != null) { + for (int i = 0; i < statements.length; i++) { + s = s + "\n" + statements[i].toString(tab); //$NON-NLS-1$ + if (!(statements[i] instanceof Block)) { + s += ";"; //$NON-NLS-1$ + } + } + } + s += "\n" + tabString(tab == 0 ? 0 : tab - 1) + "}"; //$NON-NLS-1$ //$NON-NLS-2$ + //$NON-NLS-2$ //$NON-NLS-1$ + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + ClassScope classScope) { + + if (visitor.visit(this, classScope)) { + if (arguments != null) { + int argumentLength = arguments.length; + for (int i = 0; i < argumentLength; i++) + arguments[i].traverse(visitor, scope); + } + if (thrownExceptions != null) { + int thrownExceptionsLength = thrownExceptions.length; + for (int i = 0; i < thrownExceptionsLength; i++) + thrownExceptions[i].traverse(visitor, scope); + } + if (constructorCall != null) + constructorCall.traverse(visitor, scope); + if (statements != null) { + int statementsLength = statements.length; + for (int i = 0; i < statementsLength; i++) + statements[i].traverse(visitor, scope); + } + } + visitor.endVisit(this, classScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Continue.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Continue.java new file mode 100644 index 0000000..c76da6a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Continue.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; + +public class Continue extends BranchStatement { + + public Continue(char[] l, int s, int e) { + + super(l, s, e); + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + // here requires to generate a sequence of finally blocks invocations depending corresponding + // to each of the traversed try statements, so that execution will terminate properly. + + // lookup the label, this should answer the returnContext + FlowContext targetContext = (label == null) + ? flowContext.getTargetContextForDefaultContinue() + : flowContext.getTargetContextForContinueLabel(label); + + if (targetContext == null) { + if (label == null) { + currentScope.problemReporter().invalidContinue(this); + } else { + currentScope.problemReporter().undefinedLabel(this); + } + return flowInfo; // pretend it did not continue since no actual target + } + + if (targetContext == FlowContext.NotContinuableContext) { + currentScope.problemReporter().invalidContinue(this); + return flowInfo; // pretend it did not continue since no actual target + } + targetLabel = targetContext.continueLabel(); + FlowContext traversedContext = flowContext; + int subIndex = 0, maxSub = 5; + subroutines = new AstNode[maxSub]; + + do { + AstNode sub; + if ((sub = traversedContext.subRoutine()) != null) { + if (subIndex == maxSub) { + System.arraycopy(subroutines, 0, (subroutines = new AstNode[maxSub*=2]), 0, subIndex); // grow + } + subroutines[subIndex++] = sub; + if (sub.cannotReturn()) { + break; + } + } + traversedContext.recordReturnFrom(flowInfo.unconditionalInits()); + + AstNode node; + if ((node = traversedContext.associatedNode) instanceof TryStatement) { + TryStatement tryStatement = (TryStatement) node; + flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits + } else if (traversedContext == targetContext) { + // only record continue info once accumulated through subroutines, and only against target context + targetContext.recordContinueFrom(flowInfo); + break; + } + } while ((traversedContext = traversedContext.parent) != null); + + // resize subroutines + if (subIndex != maxSub) { + System.arraycopy(subroutines, 0, (subroutines = new AstNode[subIndex]), 0, subIndex); + } + return FlowInfo.DEAD_END; + } + + public String toString(int tab) { + + String s = tabString(tab); + s += "continue "; //$NON-NLS-1$ + if (label != null) + s += new String(label); + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + visitor.visit(this, blockScope); + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/DefaultCase.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/DefaultCase.java new file mode 100644 index 0000000..73adba9 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/DefaultCase.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.CaseLabel; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public class DefaultCase extends Statement { + + public CaseLabel targetLabel; + /** + * DefautCase constructor comment. + */ + public DefaultCase(int sourceEnd, int sourceStart) { + + this.sourceStart = sourceStart; + this.sourceEnd = sourceEnd; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + return flowInfo; + } + + /** + * Default case code generation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// targetLabel.place(); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// +// } + /** + * No-op : should use resolveCase(...) instead. + */ + public void resolve(BlockScope scope) { + } + + public Constant resolveCase( + BlockScope scope, + TypeBinding testType, + SwitchStatement switchStatement) { + + // remember the default case into the associated switch statement + if (switchStatement.defaultCase != null) + scope.problemReporter().duplicateDefaultCase(this); + + // on error the last default will be the selected one .... (why not) .... + switchStatement.defaultCase = this; + resolve(scope); + return null; + } + + public String toString(int tab) { + + String s = tabString(tab); + s = s + "default : "; //$NON-NLS-1$ + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + visitor.visit(this, blockScope); + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/DoStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/DoStatement.java new file mode 100644 index 0000000..8dedd3b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/DoStatement.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.LoopingFlowContext; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class DoStatement extends Statement { + + public Expression condition; + public Statement action; + + private Label breakLabel, continueLabel; + + // for local variables table attributes + int mergedInitStateIndex = -1; + + public DoStatement(Expression condition, Statement action, int s, int e) { + + this.sourceStart = s; + this.sourceEnd = e; + this.condition = condition; + this.action = action; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + breakLabel = new Label(); + continueLabel = new Label(); + LoopingFlowContext loopingContext = + new LoopingFlowContext( + flowContext, + this, + breakLabel, + continueLabel, + currentScope); + + Constant cst = condition.constant; + boolean isConditionTrue = cst != NotAConstant && cst.booleanValue() == true; + cst = condition.optimizedBooleanConstant(); + boolean isConditionOptimizedTrue = cst != NotAConstant && cst.booleanValue() == true; + boolean isConditionOptimizedFalse = cst != NotAConstant && cst.booleanValue() == false; + + int previousMode = flowInfo.reachMode(); + + if ((action != null) && !action.isEmptyBlock()) { + flowInfo = action.analyseCode(currentScope, loopingContext, flowInfo); + + // code generation can be optimized when no need to continue in the loop + if (!flowInfo.isReachable() && !loopingContext.initsOnContinue.isReachable()) { + continueLabel = null; + } + } + /* Reset reach mode, to address following scenario. + * final blank; + * do { if (true) break; else blank = 0; } while(false); + * blank = 1; // may be initialized already + */ + flowInfo.setReachMode(previousMode); + + flowInfo = + condition.analyseCode( + currentScope, + loopingContext, + (action == null + ? flowInfo + : (flowInfo.mergedWith(loopingContext.initsOnContinue)))); + if (!isConditionOptimizedFalse && continueLabel != null) { + loopingContext.complainOnFinalAssignmentsInLoop(currentScope, flowInfo); + } + + // infinite loop + FlowInfo mergedInfo; + if (isConditionTrue) { + mergedInfo = loopingContext.initsOnBreak; + if (!mergedInfo.isReachable()) mergedInfo.addPotentialInitializationsFrom(flowInfo.initsWhenFalse()); + } else { + // end of loop: either condition false or break + mergedInfo = + flowInfo.initsWhenFalse().unconditionalInits().mergedWith( + loopingContext.initsOnBreak); + if (isConditionOptimizedTrue && !loopingContext.initsOnBreak.isReachable()) { + mergedInfo.setReachMode(FlowInfo.UNREACHABLE); + } + } + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(mergedInfo); + return mergedInfo; + } + + /** + * Do statement code generation + * + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// +// // labels management +// Label actionLabel = new Label(codeStream); +// actionLabel.place(); +// breakLabel.codeStream = codeStream; +// if (continueLabel != null) { +// continueLabel.codeStream = codeStream; +// } +// +// // generate action +// if (action != null) { +// action.generateCode(currentScope, codeStream); +// } +// // generate condition +// if (continueLabel != null) { +// continueLabel.place(); +// condition.generateOptimizedBoolean( +// currentScope, +// codeStream, +// actionLabel, +// null, +// true); +// } +// breakLabel.place(); +// +// // May loose some local variable initializations : affecting the local variable attributes +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// +// } + + public void resetStateForCodeGeneration() { + if (this.breakLabel != null) { + this.breakLabel.resetStateForCodeGeneration(); + } + if (this.continueLabel != null) { + this.continueLabel.resetStateForCodeGeneration(); + } + } + + public void resolve(BlockScope scope) { + + TypeBinding type = condition.resolveTypeExpecting(scope, BooleanBinding); + condition.implicitWidening(type, type); + if (action != null) + action.resolve(scope); + } + + public String toString(int tab) { + + String inFront, s = tabString(tab); + inFront = s; + s = s + "do"; //$NON-NLS-1$ + if (action == null) + s = s + " {}\n"; //$NON-NLS-1$ + else if (action instanceof Block) + s = s + "\n" + action.toString(tab + 1) + "\n"; //$NON-NLS-2$ //$NON-NLS-1$ + else + s = s + " {\n" + action.toString(tab + 1) + ";}\n"; //$NON-NLS-1$ //$NON-NLS-2$ + s = s + inFront + "while (" + condition.toStringExpression() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + return s; + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + if (action != null) { + action.traverse(visitor, scope); + } + condition.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/DoubleLiteral.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/DoubleLiteral.java new file mode 100644 index 0000000..fbead1b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/DoubleLiteral.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public class DoubleLiteral extends NumberLiteral { + double value; +public DoubleLiteral(char[] token, int s, int e) { + super(token, s,e); +} +public void computeConstant() { + + //the source is correctly formated so the exception should never occurs + + Double computedValue; + try { computedValue = Double.valueOf(String.valueOf(source));} + catch(NumberFormatException e){return ;} //how can it happen ???? + + if (computedValue.doubleValue() > Double.MAX_VALUE) return ; //may be Infinity + if (computedValue.doubleValue() < Double.MIN_VALUE) + { //only a true 0 can be made of zeros + //2.00000000000000000e-324 is illegal .... + label : + for (int i=0;i> 4) == T_double) +// codeStream.generateInlinedValue(value); +// else +// codeStream.generateConstant(constant, implicitConversion); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +public TypeBinding literalType(BlockScope scope) { + return DoubleBinding; +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) { + visitor.visit(this, blockScope); + visitor.endVisit(this, blockScope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/EmptyStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/EmptyStatement.java new file mode 100644 index 0000000..374b220 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/EmptyStatement.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; + +public class EmptyStatement extends Statement { + + public EmptyStatement(int startPosition, int endPosition) { + this.sourceStart = startPosition; + this.sourceEnd = endPosition; + } + + public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { + return flowInfo; + } + +// public void generateCode(BlockScope currentScope, CodeStream codeStream){ +// // no bytecode, no need to check for reachability or recording source positions +// } + + public void resolve(BlockScope scope) { + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); + } + + public String toString(int tab) { + return tabString(tab) + ";"; //$NON-NLS-1$ + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/EqualExpression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/EqualExpression.java new file mode 100644 index 0000000..111af7c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/EqualExpression.java @@ -0,0 +1,561 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.Scope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class EqualExpression extends BinaryExpression { + +public EqualExpression(Expression left, Expression right,int operator) { + super(left,right,operator); +} +public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { + if (((bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) { + if ((left.constant != NotAConstant) && (left.constant.typeID() == T_boolean)) { + if (left.constant.booleanValue()) { // true == anything + // this is equivalent to the right argument inits + return right.analyseCode(currentScope, flowContext, flowInfo); + } else { // false == anything + // this is equivalent to the right argument inits negated + return right.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition(); + } + } + if ((right.constant != NotAConstant) && (right.constant.typeID() == T_boolean)) { + if (right.constant.booleanValue()) { // anything == true + // this is equivalent to the right argument inits + return left.analyseCode(currentScope, flowContext, flowInfo); + } else { // anything == false + // this is equivalent to the right argument inits negated + return left.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition(); + } + } + return right.analyseCode( + currentScope, flowContext, + left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()).unconditionalInits(); + } else { //NOT_EQUAL : + if ((left.constant != NotAConstant) && (left.constant.typeID() == T_boolean)) { + if (!left.constant.booleanValue()) { // false != anything + // this is equivalent to the right argument inits + return right.analyseCode(currentScope, flowContext, flowInfo); + } else { // true != anything + // this is equivalent to the right argument inits negated + return right.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition(); + } + } + if ((right.constant != NotAConstant) && (right.constant.typeID() == T_boolean)) { + if (!right.constant.booleanValue()) { // anything != false + // this is equivalent to the right argument inits + return left.analyseCode(currentScope, flowContext, flowInfo); + } else { // anything != true + // this is equivalent to the right argument inits negated + return left.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition(); + } + } + return right.analyseCode( + currentScope, flowContext, + left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()).asNegatedCondition().unconditionalInits(); + } +} +public final boolean areTypesCastCompatible(BlockScope scope, TypeBinding castType, TypeBinding expressionType) { + //see specifications 5.5 + //A more complete version of this method is provided on + //CastExpression (it deals with constant and need runtime checkcast) + + if (castType == expressionType) return true; + + //========ARRAY=============== + if (expressionType.isArrayType()) { + if (castType.isArrayType()) { //------- (castTb.isArray) expressionTb.isArray ----------- + TypeBinding expressionEltType = ((ArrayBinding) expressionType).elementsType(scope); + if (expressionEltType.isBaseType()) + // <---stop the recursion------- + return ((ArrayBinding) castType).elementsType(scope) == expressionEltType; + //recursivly on the elts... + return areTypesCastCompatible(scope, ((ArrayBinding) castType).elementsType(scope), expressionEltType); + } + if (castType.isBaseType()) { + return false; + } + if (castType.isClass()) { //------(castTb.isClass) expressionTb.isArray --------------- + if (scope.isJavaLangObject(castType)) + return true; + return false; + } + if (castType.isInterface()) { //------- (castTb.isInterface) expressionTb.isArray ----------- + if (scope.isJavaLangCloneable(castType) || scope.isJavaIoSerializable(castType)) { + return true; + } + return false; + } + + return false; + } + + //------------(castType) null-------------- + if (expressionType == NullBinding) { + return !castType.isBaseType(); + } + + //========BASETYPE============== + if (expressionType.isBaseType()) { + return false; + } + + + //========REFERENCE TYPE=================== + + if (expressionType.isClass()) { + if (castType.isArrayType()) { // ---- (castTb.isArray) expressionTb.isClass ------- + if (scope.isJavaLangObject(expressionType)) + return true; + } + if (castType.isBaseType()) { + return false; + } + if (castType.isClass()) { // ----- (castTb.isClass) expressionTb.isClass ------ + if (expressionType.isCompatibleWith(castType)) + return true; + else { + if (castType.isCompatibleWith(expressionType)) { + return true; + } + return false; + } + } + if (castType.isInterface()) { // ----- (castTb.isInterface) expressionTb.isClass ------- + if (((ReferenceBinding) expressionType).isFinal()) { //no subclass for expressionTb, thus compile-time check is valid + if (expressionType.isCompatibleWith(castType)) + return true; + return false; + } else { + return true; + } + } + + return false; + } + if (expressionType.isInterface()) { + if (castType.isArrayType()) { // ----- (castTb.isArray) expressionTb.isInterface ------ + if (scope.isJavaLangCloneable(expressionType) || scope.isJavaIoSerializable(expressionType)) + //potential runtime error + { + return true; + } + return false; + } + if (castType.isBaseType()) { + return false; + } + if (castType.isClass()) { // ----- (castTb.isClass) expressionTb.isInterface -------- + if (scope.isJavaLangObject(castType)) + return true; + if (((ReferenceBinding) castType).isFinal()) { //no subclass for castTb, thus compile-time check is valid + if (castType.isCompatibleWith(expressionType)) { + return true; + } + return false; + } + return true; + } + if (castType.isInterface()) { // ----- (castTb.isInterface) expressionTb.isInterface ------- + if (Scope.compareTypes(castType, expressionType) == NotRelated) { + MethodBinding[] castTbMethods = ((ReferenceBinding) castType).methods(); + int castTbMethodsLength = castTbMethods.length; + MethodBinding[] expressionTbMethods = ((ReferenceBinding) expressionType).methods(); + int expressionTbMethodsLength = expressionTbMethods.length; + for (int i = 0; i < castTbMethodsLength; i++) { + for (int j = 0; j < expressionTbMethodsLength; j++) { + if (castTbMethods[i].selector == expressionTbMethods[j].selector) { + if (castTbMethods[i].returnType != expressionTbMethods[j].returnType) { + if (castTbMethods[i].areParametersEqual(expressionTbMethods[j])) { + return false; + } + } + } + } + } + } + return true; + } + + return false; + } + + return false; +} +public final void computeConstant(TypeBinding leftType, TypeBinding rightType) { + if ((this.left.constant != NotAConstant) && (this.right.constant != NotAConstant)) { + this.constant = + Constant.computeConstantOperationEQUAL_EQUAL( + left.constant, + leftType.id, + EQUAL_EQUAL, + right.constant, + rightType.id); + if (((this.bits & OperatorMASK) >> OperatorSHIFT) == NOT_EQUAL) + constant = Constant.fromValue(!constant.booleanValue()); + } else { + this.constant = NotAConstant; + // no optimization for null == null + } +} +/** + * Normal == or != code generation. + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +//public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { +// +// if (constant != NotAConstant) { +// int pc = codeStream.position; +// if (valueRequired) +// codeStream.generateConstant(constant, implicitConversion); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// return; +// } +// Label falseLabel; +// bits |= OnlyValueRequiredMASK; +// generateOptimizedBoolean( +// currentScope, +// codeStream, +// null, +// falseLabel = new Label(codeStream), +// valueRequired); +// if (falseLabel.hasForwardReferences()) { +// if (valueRequired){ +// // comparison is TRUE +// codeStream.iconst_1(); +// if ((bits & ValueForReturnMASK) != 0){ +// codeStream.ireturn(); +// // comparison is FALSE +// falseLabel.place(); +// codeStream.iconst_0(); +// } else { +// Label endLabel = new Label(codeStream); +// codeStream.goto_(endLabel); +// codeStream.decrStackSize(1); +// // comparison is FALSE +// falseLabel.place(); +// codeStream.iconst_0(); +// endLabel.place(); +// } +// } else { +// falseLabel.place(); +// } +// } +//} +/** + * Boolean operator code generation + * Optimized operations are: == and != + */ +//public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) { +// +// if (constant != Constant.NotAConstant) { +// super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired); +// return; +// } +// if (((bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) { +// if ((left.implicitConversion & 0xF) /*compile-time*/ == T_boolean) { +// generateOptimizedBooleanEqual(currentScope, codeStream, trueLabel, falseLabel, valueRequired); +// } else { +// generateOptimizedNonBooleanEqual(currentScope, codeStream, trueLabel, falseLabel, valueRequired); +// } +// } else { +// if ((left.implicitConversion & 0xF) /*compile-time*/ == T_boolean) { +// generateOptimizedBooleanEqual(currentScope, codeStream, falseLabel, trueLabel, valueRequired); +// } else { +// generateOptimizedNonBooleanEqual(currentScope, codeStream, falseLabel, trueLabel, valueRequired); +// } +// } +//} +/** + * Boolean generation for == with boolean operands + * + * Note this code does not optimize conditional constants !!!! + */ +//public void generateOptimizedBooleanEqual(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) { +// +// // optimized cases: true == x, false == x +// if (left.constant != NotAConstant) { +// boolean inline = left.constant.booleanValue(); +// right.generateOptimizedBoolean(currentScope, codeStream, (inline ? trueLabel : falseLabel), (inline ? falseLabel : trueLabel), valueRequired); +// return; +// } // optimized cases: x == true, x == false +// if (right.constant != NotAConstant) { +// boolean inline = right.constant.booleanValue(); +// left.generateOptimizedBoolean(currentScope, codeStream, (inline ? trueLabel : falseLabel), (inline ? falseLabel : trueLabel), valueRequired); +// return; +// } +// // default case +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// codeStream.if_icmpeq(trueLabel); +// } +// } else { +// // implicit falling through the TRUE case +// if (trueLabel == null) { +// codeStream.if_icmpne(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +//} +///** +// * Boolean generation for == with non-boolean operands +// * +// */ +//public void generateOptimizedNonBooleanEqual(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) { +// +// int pc = codeStream.position; +// Constant inline; +// if ((inline = right.constant) != NotAConstant) { +// // optimized case: x == 0 +// if (((left.implicitConversion >> 4) == T_int) && (inline.intValue() == 0)) { +// left.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// codeStream.ifeq(trueLabel); +// } +// } else { +// // implicit falling through the TRUE case +// if (trueLabel == null) { +// codeStream.ifne(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// return; +// } +// } +// if ((inline = left.constant) != NotAConstant) { +// // optimized case: 0 == x +// if (((left.implicitConversion >> 4) == T_int) +// && (inline.intValue() == 0)) { +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// codeStream.ifeq(trueLabel); +// } +// } else { +// // implicit falling through the TRUE case +// if (trueLabel == null) { +// codeStream.ifne(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// return; +// } +// } +// // null cases +// // optimized case: x == null +// if (right instanceof NullLiteral) { +// if (left instanceof NullLiteral) { +// // null == null +// if (valueRequired) { +// if ((bits & OnlyValueRequiredMASK) != 0) { +// if (((bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) { +// codeStream.iconst_1(); +// } else { +// codeStream.iconst_0(); +// } +// } else { +// if (falseLabel == null) { +// // implicit falling through the FALSE case +// if (trueLabel != null) { +// codeStream.goto_(trueLabel); +// } +// } +// } +// } +// } else { +// left.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// codeStream.ifnull(trueLabel); +// } +// } else { +// // implicit falling through the TRUE case +// if (trueLabel == null) { +// codeStream.ifnonnull(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// return; +// } else if (left instanceof NullLiteral) { // optimized case: null == x +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// codeStream.ifnull(trueLabel); +// } +// } else { +// // implicit falling through the TRUE case +// if (trueLabel == null) { +// codeStream.ifnonnull(falseLabel); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// return; +// } +// +// // default case +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// switch (left.implicitConversion >> 4) { // operand runtime type +// case T_int : +// codeStream.if_icmpeq(trueLabel); +// break; +// case T_float : +// codeStream.fcmpl(); +// codeStream.ifeq(trueLabel); +// break; +// case T_long : +// codeStream.lcmp(); +// codeStream.ifeq(trueLabel); +// break; +// case T_double : +// codeStream.dcmpl(); +// codeStream.ifeq(trueLabel); +// break; +// default : +// codeStream.if_acmpeq(trueLabel); +// } +// } +// } else { +// // implicit falling through the TRUE case +// if (trueLabel == null) { +// switch (left.implicitConversion >> 4) { // operand runtime type +// case T_int : +// codeStream.if_icmpne(falseLabel); +// break; +// case T_float : +// codeStream.fcmpl(); +// codeStream.ifne(falseLabel); +// break; +// case T_long : +// codeStream.lcmp(); +// codeStream.ifne(falseLabel); +// break; +// case T_double : +// codeStream.dcmpl(); +// codeStream.ifne(falseLabel); +// break; +// default : +// codeStream.if_acmpne(falseLabel); +// } +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +public boolean isCompactableOperation() { + return false; +} +public TypeBinding resolveType(BlockScope scope) { + // always return BooleanBinding + TypeBinding leftType = left.resolveType(scope); + TypeBinding rightType = right.resolveType(scope); + if (leftType == null || rightType == null){ + constant = NotAConstant; + return null; + } + + // both base type + if (leftType.isBaseType() && rightType.isBaseType()) { + // the code is an int + // (cast) left == (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 <<0 + int result = ResolveTypeTables[EQUAL_EQUAL][ (leftType.id << 4) + rightType.id]; + left.implicitConversion = result >>> 12; + right.implicitConversion = (result >>> 4) & 0x000FF; + bits |= result & 0xF; + if ((result & 0x0000F) == T_undefined) { + constant = Constant.NotAConstant; + scope.problemReporter().invalidOperator(this, leftType, rightType); + return null; + } + computeConstant(leftType, rightType); + this.resolvedType = BooleanBinding; + return BooleanBinding; + } + + // Object references + // spec 15.20.3 + if (areTypesCastCompatible(scope, rightType, leftType) || areTypesCastCompatible(scope, leftType, rightType)) { + // (special case for String) + if ((rightType.id == T_String) && (leftType.id == T_String)) + computeConstant(leftType, rightType); + else + constant = NotAConstant; + if (rightType.id == T_String) + right.implicitConversion = String2String; + if (leftType.id == T_String) + left.implicitConversion = String2String; + this.resolvedType = BooleanBinding; + return BooleanBinding; + } + constant = NotAConstant; + scope.problemReporter().notCompatibleTypesError(this, leftType, rightType); + return null; +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + if (visitor.visit(this, scope)) { + left.traverse(visitor, scope); + right.traverse(visitor, scope); + } + visitor.endVisit(this, scope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ExplicitConstructorCall.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ExplicitConstructorCall.java new file mode 100644 index 0000000..f72c8bf --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ExplicitConstructorCall.java @@ -0,0 +1,329 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.InvocationSite; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding; + +public class ExplicitConstructorCall + extends Statement + implements InvocationSite { + + public Expression[] arguments; + public Expression qualification; + public MethodBinding binding; + + public int accessMode; + + public final static int ImplicitSuper = 1; + public final static int Super = 2; + public final static int This = 3; + + public VariableBinding[][] implicitArguments; + boolean discardEnclosingInstance; + + MethodBinding syntheticAccessor; + + public ExplicitConstructorCall(int accessMode) { + this.accessMode = accessMode; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + // must verify that exceptions potentially thrown by this expression are caught in the method. + + try { + ((MethodScope) currentScope).isConstructorCall = true; + + // process enclosing instance + if (qualification != null) { + flowInfo = + qualification + .analyseCode(currentScope, flowContext, flowInfo) + .unconditionalInits(); + } + // process arguments + if (arguments != null) { + for (int i = 0, max = arguments.length; i < max; i++) { + flowInfo = + arguments[i] + .analyseCode(currentScope, flowContext, flowInfo) + .unconditionalInits(); + } + } + + ReferenceBinding[] thrownExceptions; + if ((thrownExceptions = binding.thrownExceptions) != NoExceptions) { + // check exceptions + flowContext.checkExceptionHandlers( + thrownExceptions, + (accessMode == ImplicitSuper) + ? (AstNode) currentScope.methodScope().referenceContext + : (AstNode) this, + flowInfo, + currentScope); + } + manageEnclosingInstanceAccessIfNecessary(currentScope); + manageSyntheticAccessIfNecessary(currentScope); + return flowInfo; + } finally { + ((MethodScope) currentScope).isConstructorCall = false; + } + } + + /** + * Constructor call code generation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// try { +// ((MethodScope) currentScope).isConstructorCall = true; +// +// int pc = codeStream.position; +// codeStream.aload_0(); +// +// // handling innerclass constructor invocation +// ReferenceBinding targetType = binding.declaringClass; +// // handling innerclass instance allocation - enclosing instance arguments +// if (targetType.isNestedType()) { +// codeStream.generateSyntheticEnclosingInstanceValues( +// currentScope, +// targetType, +// discardEnclosingInstance ? null : qualification, +// this); +// } +// // regular code gen +// if (arguments != null) { +// for (int i = 0, max = arguments.length; i < max; i++) { +// arguments[i].generateCode(currentScope, codeStream, true); +// } +// } +// // handling innerclass instance allocation - outer local arguments +// if (targetType.isNestedType()) { +// codeStream.generateSyntheticOuterArgumentValues( +// currentScope, +// targetType, +// this); +// } +// if (syntheticAccessor != null) { +// // synthetic accessor got some extra arguments appended to its signature, which need values +// for (int i = 0, +// max = syntheticAccessor.parameters.length - binding.parameters.length; +// i < max; +// i++) { +// codeStream.aconst_null(); +// } +// codeStream.invokespecial(syntheticAccessor); +// } else { +// codeStream.invokespecial(binding); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } finally { +// ((MethodScope) currentScope).isConstructorCall = false; +// } +// } + + public boolean isImplicitSuper() { + //return true if I'm of these compiler added statement super(); + + return (accessMode == ImplicitSuper); + } + + public boolean isSuperAccess() { + + return accessMode != This; + } + + public boolean isTypeAccess() { + + return true; + } + + /* Inner emulation consists in either recording a dependency + * link only, or performing one level of propagation. + * + * Dependency mechanism is used whenever dealing with source target + * types, since by the time we reach them, we might not yet know their + * exact need. + */ + void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) { + ReferenceBinding superType; + + // perform some emulation work in case there is some and we are inside a local type only + if ((superType = binding.declaringClass).isNestedType() + && currentScope.enclosingSourceType().isLocalType()) { + + if (superType.isLocalType()) { + ((LocalTypeBinding) superType).addInnerEmulationDependent(currentScope, qualification != null); + } else { + // locally propagate, since we already now the desired shape for sure + currentScope.propagateInnerEmulation(superType, qualification != null); + } + } + } + + public void manageSyntheticAccessIfNecessary(BlockScope currentScope) { + + // perform some emulation work in case there is some and we are inside a local type only + if (binding.isPrivate() && (accessMode != This)) { + +// if (currentScope +// .environment() +// .options +// .isPrivateConstructorAccessChangingVisibility) { +// binding.tagForClearingPrivateModifier(); +// // constructor will not be dumped as private, no emulation required thus +// } else { + syntheticAccessor = + ((SourceTypeBinding) binding.declaringClass).addSyntheticMethod(binding, isSuperAccess()); + currentScope.problemReporter().needToEmulateMethodAccess(binding, this); +// } + } + } + + public void resolve(BlockScope scope) { + // the return type should be void for a constructor. + // the test is made into getConstructor + + // mark the fact that we are in a constructor call..... + // unmark at all returns + try { + ((MethodScope) scope).isConstructorCall = true; + ReferenceBinding receiverType = scope.enclosingSourceType(); + if (accessMode != This) + receiverType = receiverType.superclass(); + + if (receiverType == null) { + return; + } + + // qualification should be from the type of the enclosingType + if (qualification != null) { + if (accessMode != Super) { + scope.problemReporter().unnecessaryEnclosingInstanceSpecification( + qualification, + receiverType); + } + ReferenceBinding enclosingType = receiverType.enclosingType(); + if (enclosingType == null) { + scope.problemReporter().unnecessaryEnclosingInstanceSpecification( + qualification, + receiverType); + discardEnclosingInstance = true; + } else { + TypeBinding qTb = qualification.resolveTypeExpecting(scope, enclosingType); + qualification.implicitWidening(qTb, qTb); + } + } + + // arguments buffering for the method lookup + TypeBinding[] argTypes = NoParameters; + if (arguments != null) { + boolean argHasError = false; // typeChecks all arguments + int length = arguments.length; + argTypes = new TypeBinding[length]; + for (int i = 0; i < length; i++) + if ((argTypes[i] = arguments[i].resolveType(scope)) == null) + argHasError = true; + if (argHasError) + return; + } + if ((binding = scope.getConstructor(receiverType, argTypes, this)) + .isValidBinding()) { + if (isMethodUseDeprecated(binding, scope)) + scope.problemReporter().deprecatedMethod(binding, this); + + // see for user-implicit widening conversion + if (arguments != null) { + int length = arguments.length; + TypeBinding[] paramTypes = binding.parameters; + for (int i = 0; i < length; i++) + arguments[i].implicitWidening(paramTypes[i], argTypes[i]); + } + if (binding.isPrivate()) { + binding.modifiers |= AccPrivateUsed; + } + } else { + if (binding.declaringClass == null) + binding.declaringClass = receiverType; + scope.problemReporter().invalidConstructor(this, binding); + } + } finally { + ((MethodScope) scope).isConstructorCall = false; + } + } + + public void setActualReceiverType(ReferenceBinding receiverType) { + // ignored + } + + public void setDepth(int depth) { + // ignore for here + } + + public void setFieldIndex(int depth) { + // ignore for here + } + + public String toString(int tab) { + + String s = tabString(tab); + if (qualification != null) + s = s + qualification.toStringExpression() + "."; //$NON-NLS-1$ + if (accessMode == This) { + s = s + "this("; //$NON-NLS-1$ + } else { + s = s + "super("; //$NON-NLS-1$ + } + if (arguments != null) + for (int i = 0; i < arguments.length; i++) { + s = s + arguments[i].toStringExpression(); + if (i != arguments.length - 1) + s = s + ", "; //$NON-NLS-1$ + } + s = s + ")"; //$NON-NLS-1$ + return s; + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + if (qualification != null) { + qualification.traverse(visitor, scope); + } + if (arguments != null) { + int argumentLength = arguments.length; + for (int i = 0; i < argumentLength; i++) + arguments[i].traverse(visitor, scope); + } + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Expression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Expression.java new file mode 100644 index 0000000..cdeb2ae --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Expression.java @@ -0,0 +1,497 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BaseTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; +import net.sourceforge.phpdt.internal.compiler.problem.ShouldNotImplement; +import net.sourceforge.phpdt.internal.compiler.util.Util; + +public abstract class Expression extends Statement { + + //some expression may not be used - from a java semantic point + //of view only - as statements. Other may. In order to avoid the creation + //of wrappers around expression in order to tune them as expression + //Expression is a subclass of Statement. See the message isValidJavaStatement() + + public int implicitConversion; + public TypeBinding resolvedType; + + public Constant constant; + + public Expression() { + super(); + } + + public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { + + return flowInfo; + } + + public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) { + + return analyseCode(currentScope, flowContext, flowInfo); + } + + /** + * Constant usable for bytecode pattern optimizations, but cannot be inlined + * since it is not strictly equivalent to the definition of constant expressions. + * In particular, some side-effects may be required to occur (only the end value + * is known). + * Constant is known to be of boolean type + */ + public Constant optimizedBooleanConstant() { + + return this.constant; + } + + public static final boolean isConstantValueRepresentable( + Constant constant, + int constantTypeID, + int targetTypeID) { + + //true if there is no loss of precision while casting. + // constantTypeID == constant.typeID + if (targetTypeID == constantTypeID) + return true; + switch (targetTypeID) { + case T_char : + switch (constantTypeID) { + case T_char : + return true; + case T_double : + return constant.doubleValue() == constant.charValue(); + case T_float : + return constant.floatValue() == constant.charValue(); + case T_int : + return constant.intValue() == constant.charValue(); + case T_short : + return constant.shortValue() == constant.charValue(); + case T_byte : + return constant.byteValue() == constant.charValue(); + case T_long : + return constant.longValue() == constant.charValue(); + default : + return false;//boolean + } + + case T_float : + switch (constantTypeID) { + case T_char : + return constant.charValue() == constant.floatValue(); + case T_double : + return constant.doubleValue() == constant.floatValue(); + case T_float : + return true; + case T_int : + return constant.intValue() == constant.floatValue(); + case T_short : + return constant.shortValue() == constant.floatValue(); + case T_byte : + return constant.byteValue() == constant.floatValue(); + case T_long : + return constant.longValue() == constant.floatValue(); + default : + return false;//boolean + } + + case T_double : + switch (constantTypeID) { + case T_char : + return constant.charValue() == constant.doubleValue(); + case T_double : + return true; + case T_float : + return constant.floatValue() == constant.doubleValue(); + case T_int : + return constant.intValue() == constant.doubleValue(); + case T_short : + return constant.shortValue() == constant.doubleValue(); + case T_byte : + return constant.byteValue() == constant.doubleValue(); + case T_long : + return constant.longValue() == constant.doubleValue(); + default : + return false; //boolean + } + + case T_byte : + switch (constantTypeID) { + case T_char : + return constant.charValue() == constant.byteValue(); + case T_double : + return constant.doubleValue() == constant.byteValue(); + case T_float : + return constant.floatValue() == constant.byteValue(); + case T_int : + return constant.intValue() == constant.byteValue(); + case T_short : + return constant.shortValue() == constant.byteValue(); + case T_byte : + return true; + case T_long : + return constant.longValue() == constant.byteValue(); + default : + return false; //boolean + } + + case T_short : + switch (constantTypeID) { + case T_char : + return constant.charValue() == constant.shortValue(); + case T_double : + return constant.doubleValue() == constant.shortValue(); + case T_float : + return constant.floatValue() == constant.shortValue(); + case T_int : + return constant.intValue() == constant.shortValue(); + case T_short : + return true; + case T_byte : + return constant.byteValue() == constant.shortValue(); + case T_long : + return constant.longValue() == constant.shortValue(); + default : + return false; //boolean + } + + case T_int : + switch (constantTypeID) { + case T_char : + return constant.charValue() == constant.intValue(); + case T_double : + return constant.doubleValue() == constant.intValue(); + case T_float : + return constant.floatValue() == constant.intValue(); + case T_int : + return true; + case T_short : + return constant.shortValue() == constant.intValue(); + case T_byte : + return constant.byteValue() == constant.intValue(); + case T_long : + return constant.longValue() == constant.intValue(); + default : + return false; //boolean + } + + case T_long : + switch (constantTypeID) { + case T_char : + return constant.charValue() == constant.longValue(); + case T_double : + return constant.doubleValue() == constant.longValue(); + case T_float : + return constant.floatValue() == constant.longValue(); + case T_int : + return constant.intValue() == constant.longValue(); + case T_short : + return constant.shortValue() == constant.longValue(); + case T_byte : + return constant.byteValue() == constant.longValue(); + case T_long : + return true; + default : + return false; //boolean + } + + default : + return false; //boolean + } + } + + /** + * Expression statements are plain expressions, however they generate like + * normal expressions with no value required. + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// generateCode(currentScope, codeStream, false); +// } + + /** + * Every expression is responsible for generating its implicit conversion when necessary. + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// if (constant != NotAConstant) { +// // generate a constant expression +// int pc = codeStream.position; +// codeStream.generateConstant(constant, implicitConversion); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } else { +// // actual non-constant code generation +// throw new ShouldNotImplement(Util.bind("ast.missingCode")); //$NON-NLS-1$ +// } +// } + + /** + * Default generation of a boolean value + */ +// public void generateOptimizedBoolean( +// BlockScope currentScope, +// CodeStream codeStream, +// Label trueLabel, +// Label falseLabel, +// boolean valueRequired) { +// +// // a label valued to nil means: by default we fall through the case... +// // both nil means we leave the value on the stack +// +// if ((constant != Constant.NotAConstant) && (constant.typeID() == T_boolean)) { +// int pc = codeStream.position; +// if (constant.booleanValue() == true) { +// // constant == true +// if (valueRequired) { +// if (falseLabel == null) { +// // implicit falling through the FALSE case +// if (trueLabel != null) { +// codeStream.goto_(trueLabel); +// } +// } +// } +// } else { +// if (valueRequired) { +// if (falseLabel != null) { +// // implicit falling through the TRUE case +// if (trueLabel == null) { +// codeStream.goto_(falseLabel); +// } +// } +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// return; +// } +// generateCode(currentScope, codeStream, valueRequired); +// // branching +// int position = codeStream.position; +// if (valueRequired) { +// if (falseLabel == null) { +// if (trueLabel != null) { +// // Implicit falling through the FALSE case +// codeStream.ifne(trueLabel); +// } +// } else { +// if (trueLabel == null) { +// // Implicit falling through the TRUE case +// codeStream.ifeq(falseLabel); +// } else { +// // No implicit fall through TRUE/FALSE --> should never occur +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(position); +// } +// +// /* Optimized (java) code generation for string concatenations that involve StringBuffer +// * creation: going through this path means that there is no need for a new StringBuffer +// * creation, further operands should rather be only appended to the current one. +// * By default: no optimization. +// */ +// public void generateOptimizedStringBuffer( +// BlockScope blockScope, +// org.eclipse.jdt.internal.compiler.codegen.CodeStream codeStream, +// int typeID) { +// +// generateCode(blockScope, codeStream, true); +// codeStream.invokeStringBufferAppendForType(typeID); +// } + + /* Optimized (java) code generation for string concatenations that involve StringBuffer + * creation: going through this path means that there is no need for a new StringBuffer + * creation, further operands should rather be only appended to the current one. + */ +// public void generateOptimizedStringBufferCreation( +// BlockScope blockScope, +// CodeStream codeStream, +// int typeID) { +// +// // Optimization only for integers and strings +// if (typeID == T_Object) { +// // in the case the runtime value of valueOf(Object) returns null, we have to use append(Object) instead of directly valueOf(Object) +// // append(Object) returns append(valueOf(Object)), which means that the null case is handled by append(String). +// codeStream.newStringBuffer(); +// codeStream.dup(); +// codeStream.invokeStringBufferDefaultConstructor(); +// generateCode(blockScope, codeStream, true); +// codeStream.invokeStringBufferAppendForType(T_Object); +// return; +// } +// codeStream.newStringBuffer(); +// codeStream.dup(); +// if (typeID == T_String || typeID == T_null) { +// if (constant != NotAConstant) { +// codeStream.ldc(constant.stringValue()); +// } else { +// generateCode(blockScope, codeStream, true); +// codeStream.invokeStringValueOf(T_Object); +// } +// } else { +// generateCode(blockScope, codeStream, true); +// codeStream.invokeStringValueOf(typeID); +// } +// codeStream.invokeStringBufferStringConstructor(); +// } + + // Base types need that the widening is explicitly done by the compiler using some bytecode like i2f + public void implicitWidening( + TypeBinding runtimeTimeType, + TypeBinding compileTimeType) { + + if (runtimeTimeType == null || compileTimeType == null) + return; + +// if (compileTimeType.id == T_null) { +// // this case is possible only for constant null +// // The type of runtime is a reference type +// // The code gen use the constant id thus any value +// // for the runtime id (akak the <<4) could be used. +// // T_Object is used as some general T_reference +// implicitConversion = (T_Object << 4) + T_null; +// return; +// } + + switch (runtimeTimeType.id) { + case T_byte : + case T_short : + case T_char : + implicitConversion = (T_int << 4) + compileTimeType.id; + break; + case T_String : + case T_float : + case T_boolean : + case T_double : + case T_int : //implicitConversion may result in i2i which will result in NO code gen + case T_long : + implicitConversion = (runtimeTimeType.id << 4) + compileTimeType.id; + break; + default : //nothing on regular object ref + } + } + + public boolean isCompactableOperation() { + + return false; + } + + //Return true if the conversion is done AUTOMATICALLY by the vm + //while the javaVM is an int based-machine, thus for example pushing + //a byte onto the stack , will automatically creates a int on the stack + //(this request some work d be done by the VM on signed numbers) + public boolean isConstantValueOfTypeAssignableToType( + TypeBinding constantType, + TypeBinding targetType) { + + if (constant == Constant.NotAConstant) + return false; + if (constantType == targetType) + return true; + if (constantType.isBaseType() && targetType.isBaseType()) { + //No free assignment conversion from anything but to integral ones. + if ((constantType == IntBinding + || BaseTypeBinding.isWidening(T_int, constantType.id)) + && (BaseTypeBinding.isNarrowing(targetType.id, T_int))) { + //use current explicit conversion in order to get some new value to compare with current one + return isConstantValueRepresentable(constant, constantType.id, targetType.id); + } + } + return false; + } + + public boolean isTypeReference() { + return false; + } + + public void resolve(BlockScope scope) { + // drops the returning expression's type whatever the type is. + + this.resolveType(scope); + return; + } + + public TypeBinding resolveType(BlockScope scope) { + // by default... subclasses should implement a better TC if required. + + return null; + } + + public TypeBinding resolveTypeExpecting( + BlockScope scope, + TypeBinding expectedType) { + + TypeBinding expressionType = this.resolveType(scope); + if (expressionType == null) return null; + if (expressionType == expectedType) return expressionType; + + if (!expressionType.isCompatibleWith(expectedType)) { + scope.problemReporter().typeMismatchError(expressionType, expectedType, this); + return null; + } + return expressionType; + } + + public String toString(int tab) { + + //Subclass re-define toStringExpression + String s = tabString(tab); + if (constant != null) + //before TC has runned + if (constant != NotAConstant) + //after the TC has runned + s += " /*cst:" + constant.toString() + "*/ "; //$NON-NLS-1$ //$NON-NLS-2$ + return s + toStringExpression(tab); + } + + //Subclass re-define toStringExpression + //This method is abstract and should never be called + //but we provide some code that is running.....just in case + //of developpement time (while every thing is not built) + public String toStringExpression() { + + return super.toString(0); + } + + public String toStringExpression(int tab) { + // default is regular toString expression (qualified allocation expressions redifine this method) + return this.toStringExpression(); + } + + public Expression toTypeReference() { + //by default undefined + + //this method is meanly used by the parser in order to transform + //an expression that is used as a type reference in a cast .... + //--appreciate the fact that castExpression and ExpressionWithParenthesis + //--starts with the same pattern..... + + return this; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ExtendedStringLiteral.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ExtendedStringLiteral.java new file mode 100644 index 0000000..3911796 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ExtendedStringLiteral.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; + +public class ExtendedStringLiteral extends StringLiteral { + + /** + * Build a string+char literal + */ + public ExtendedStringLiteral(StringLiteral str, CharLiteral character) { + + super(str.source, str.sourceStart, str.sourceEnd); + extendWith(character); + } + + /** + * Build a two-strings literal + * */ + public ExtendedStringLiteral(StringLiteral str1, StringLiteral str2) { + + super(str1.source, str1.sourceStart, str1.sourceEnd); + extendWith(str2); + } + + /** + * Add the lit source to mine, just as if it was mine + */ + public ExtendedStringLiteral extendWith(CharLiteral lit) { + + //update the source + int length = source.length; + System.arraycopy(source, 0, (source = new char[length + 1]), 0, length); + source[length] = lit.value; + //position at the end of all literals + sourceEnd = lit.sourceEnd; + return this; + } + + /** + * Add the lit source to mine, just as if it was mine + */ + public ExtendedStringLiteral extendWith(StringLiteral lit) { + + //uddate the source + int length = source.length; + System.arraycopy( + source, + 0, + source = new char[length + lit.source.length], + 0, + length); + System.arraycopy(lit.source, 0, source, length, lit.source.length); + //position at the end of all literals + sourceEnd = lit.sourceEnd; + return this; + } + + public String toStringExpression() { + + String str = "ExtendedStringLiteral{" + new String(source) + "}"; //$NON-NLS-2$ //$NON-NLS-1$ + return str; + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + visitor.visit(this, scope); + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/FalseLiteral.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/FalseLiteral.java new file mode 100644 index 0000000..1d6283f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/FalseLiteral.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class FalseLiteral extends MagicLiteral { + static final char[] source = {'f', 'a', 'l', 's', 'e'}; +public FalseLiteral(int s , int e) { + super(s,e); +} +public void computeConstant() { + + constant = Constant.fromValue(false);} +/** + * Code generation for false literal + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +//public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { +// int pc = codeStream.position; +// if (valueRequired) +// codeStream.iconst_0(); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +//public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) { +// +// // falseLabel being not nil means that we will not fall through into the FALSE case +// +// int pc = codeStream.position; +// if (valueRequired) { +// if (falseLabel != null) { +// // implicit falling through the TRUE case +// if (trueLabel == null) { +// codeStream.goto_(falseLabel); +// } +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +public TypeBinding literalType(BlockScope scope) { + return BooleanBinding; +} +/** + * + */ +public char[] source() { + return source; +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/FieldDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/FieldDeclaration.java new file mode 100644 index 0000000..2fac9eb --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/FieldDeclaration.java @@ -0,0 +1,222 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BaseTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpdt.internal.compiler.lookup.Scope; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class FieldDeclaration extends AbstractVariableDeclaration { + public FieldBinding binding; + boolean hasBeenResolved = false; + + //allows to retrieve both the "type" part of the declaration (part1) + //and also the part that decribe the name and the init and optionally + //some other dimension ! .... + //public int[] a, b[] = X, c ; + //for b that would give for + // - part1 : public int[] + // - part2 : b[] = X, + + public int endPart1Position; + public int endPart2Position; + + public FieldDeclaration() { + } + + public FieldDeclaration( + Expression initialization, + char[] name, + int sourceStart, + int sourceEnd) { + + this.initialization = initialization; + this.name = name; + + //due to some declaration like + // int x, y = 3, z , x ; + //the sourceStart and the sourceEnd is ONLY on the name + this.sourceStart = sourceStart; + this.sourceEnd = sourceEnd; + } + + public FlowInfo analyseCode( + MethodScope initializationScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + if (this.binding != null && this.binding.isPrivate() && !this.binding.isPrivateUsed()) { + if (!initializationScope.referenceCompilationUnit().compilationResult.hasSyntaxError()) { + initializationScope.problemReporter().unusedPrivateField(this); + } + } + // cannot define static non-constant field inside nested class + if (binding != null + && binding.isValidBinding() + && binding.isStatic() + && binding.constant == NotAConstant + && binding.declaringClass.isNestedType() + && binding.declaringClass.isClass() + && !binding.declaringClass.isStatic()) { + initializationScope.problemReporter().unexpectedStaticModifierForField( + (SourceTypeBinding) binding.declaringClass, + this); + } + + if (initialization != null) { + flowInfo = + initialization + .analyseCode(initializationScope, flowContext, flowInfo) + .unconditionalInits(); + flowInfo.markAsDefinitelyAssigned(binding); + } + return flowInfo; + } + + /** + * Code generation for a field declaration: + * standard assignment to a field + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// // do not generate initialization code if final and static (constant is then +// // recorded inside the field itself). +// int pc = codeStream.position; +// boolean isStatic; +// if (initialization != null +// && !((isStatic = binding.isStatic()) && binding.constant != NotAConstant)) { +// // non-static field, need receiver +// if (!isStatic) +// codeStream.aload_0(); +// // generate initialization value +// initialization.generateCode(currentScope, codeStream, true); +// // store into field +// if (isStatic) { +// codeStream.putstatic(binding); +// } else { +// codeStream.putfield(binding); +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public TypeBinding getTypeBinding(Scope scope) { + + return type.getTypeBinding(scope); + } + + public boolean isField() { + + return true; + } + + public boolean isStatic() { + + if (binding != null) + return binding.isStatic(); + return (modifiers & AccStatic) != 0; + } + + public String name() { + + return String.valueOf(name); + } + + public void resolve(MethodScope initializationScope) { + + // the two could be regrouped into + // a single line but it is clearer to have two lines while the reason of their + // existence is not at all the same. See comment for the second one. + + //-------------------------------------------------------- + if (!this.hasBeenResolved && binding != null && this.binding.isValidBinding()) { + + this.hasBeenResolved = true; + + if (isTypeUseDeprecated(this.binding.type, initializationScope)) + initializationScope.problemReporter().deprecatedType(this.binding.type, this.type); + + this.type.resolvedType = this.binding.type; // update binding for type reference + + // the resolution of the initialization hasn't been done + if (this.initialization == null) { + this.binding.constant = Constant.NotAConstant; + } else { + int previous = initializationScope.fieldDeclarationIndex; + try { + initializationScope.fieldDeclarationIndex = this.binding.id; + + // break dead-lock cycles by forcing constant to NotAConstant + this.binding.constant = Constant.NotAConstant; + + TypeBinding typeBinding = this.binding.type; + TypeBinding initializationTypeBinding; + + if (initialization instanceof ArrayInitializer) { + + if ((initializationTypeBinding = this.initialization.resolveTypeExpecting(initializationScope, typeBinding)) != null) { + ((ArrayInitializer) this.initialization).binding = (ArrayBinding) initializationTypeBinding; + this.initialization.implicitWidening(typeBinding, initializationTypeBinding); + } + } else if ((initializationTypeBinding = initialization.resolveType(initializationScope)) != null) { + + if (this.initialization.isConstantValueOfTypeAssignableToType(initializationTypeBinding, typeBinding) + || (typeBinding.isBaseType() && BaseTypeBinding.isWidening(typeBinding.id, initializationTypeBinding.id))) { + + this.initialization.implicitWidening(typeBinding, initializationTypeBinding); + + } else if (initializationTypeBinding.isCompatibleWith(typeBinding)) { + this.initialization.implicitWidening(typeBinding, initializationTypeBinding); + + } else { + initializationScope.problemReporter().typeMismatchError(initializationTypeBinding, typeBinding, this); + } + if (this.binding.isFinal()){ // cast from constant actual type to variable type + this.binding.constant = + this.initialization.constant.castTo( + (this.binding.type.id << 4) + this.initialization.constant.typeID()); + } + } else { + this.binding.constant = NotAConstant; + } + } finally { + initializationScope.fieldDeclarationIndex = previous; + if (this.binding.constant == null) + this.binding.constant = Constant.NotAConstant; + } + } + } + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, MethodScope scope) { + + if (visitor.visit(this, scope)) { + type.traverse(visitor, scope); + if (initialization != null) + initialization.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/FieldReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/FieldReference.java new file mode 100644 index 0000000..6a384f5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/FieldReference.java @@ -0,0 +1,552 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BindingIds; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.InvocationSite; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.Scope; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class FieldReference extends Reference implements InvocationSite { + + public Expression receiver; + public char[] token; + public FieldBinding binding, codegenBinding; + public long nameSourcePosition; //(start<<32)+end + MethodBinding syntheticReadAccessor, syntheticWriteAccessor; + public TypeBinding receiverType; + + public FieldReference(char[] source, long pos) { + + token = source; + nameSourcePosition = pos; + //by default the position are the one of the field (not true for super access) + sourceStart = (int) (pos >>> 32); + sourceEnd = (int) (pos & 0x00000000FFFFFFFFL); + bits |= BindingIds.FIELD; + + } + + public FlowInfo analyseAssignment( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo, + Assignment assignment, + boolean isCompound) { + + // compound assignment extra work + if (isCompound) { // check the variable part is initialized if blank final + if (binding.isBlankFinal() + && receiver.isThis() + && currentScope.allowBlankFinalFieldAssignment(binding) + && (!flowInfo.isDefinitelyAssigned(binding))) { + currentScope.problemReporter().uninitializedBlankFinalField(binding, this); + // we could improve error msg here telling "cannot use compound assignment on final blank field" + } + manageSyntheticReadAccessIfNecessary(currentScope); + } + flowInfo = + receiver + .analyseCode(currentScope, flowContext, flowInfo, !binding.isStatic()) + .unconditionalInits(); + if (assignment.expression != null) { + flowInfo = + assignment + .expression + .analyseCode(currentScope, flowContext, flowInfo) + .unconditionalInits(); + } + manageSyntheticWriteAccessIfNecessary(currentScope); + + // check if assigning a final field + if (binding.isFinal()) { + // in a context where it can be assigned? + if (binding.isBlankFinal() + && !isCompound + && receiver.isThis() + && !(receiver instanceof QualifiedThisReference) + && ((receiver.bits & ParenthesizedMASK) == 0) // (this).x is forbidden + && currentScope.allowBlankFinalFieldAssignment(binding)) { + if (flowInfo.isPotentiallyAssigned(binding)) { + currentScope.problemReporter().duplicateInitializationOfBlankFinalField( + binding, + this); + } else { + flowContext.recordSettingFinal(binding, this); + } + flowInfo.markAsDefinitelyAssigned(binding); + } else { + // assigning a final field outside an initializer or constructor or wrong reference + currentScope.problemReporter().cannotAssignToFinalField(binding, this); + } + } + return flowInfo; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + return analyseCode(currentScope, flowContext, flowInfo, true); + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo, + boolean valueRequired) { + + receiver.analyseCode(currentScope, flowContext, flowInfo, !binding.isStatic()); + if (valueRequired) { + manageSyntheticReadAccessIfNecessary(currentScope); + } + return flowInfo; + } + + public FieldBinding fieldBinding() { + + return binding; + } + +// public void generateAssignment( +// BlockScope currentScope, +// CodeStream codeStream, +// Assignment assignment, +// boolean valueRequired) { +// +// receiver.generateCode( +// currentScope, +// codeStream, +// !this.codegenBinding.isStatic()); +// assignment.expression.generateCode(currentScope, codeStream, true); +// fieldStore( +// codeStream, +// this.codegenBinding, +// syntheticWriteAccessor, +// valueRequired); +// if (valueRequired) { +// codeStream.generateImplicitConversion(assignment.implicitConversion); +// } +// } + + /** + * Field reference code generation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// int pc = codeStream.position; +// if (constant != NotAConstant) { +// if (valueRequired) { +// codeStream.generateConstant(constant, implicitConversion); +// } +// } else { +// boolean isStatic = this.codegenBinding.isStatic(); +// receiver.generateCode(currentScope, codeStream, !isStatic); +// if (valueRequired) { +// if (this.codegenBinding.constant == NotAConstant) { +// if (this.codegenBinding.declaringClass == null) { // array length +// codeStream.arraylength(); +// } else { +// if (syntheticReadAccessor == null) { +// if (isStatic) { +// codeStream.getstatic(this.codegenBinding); +// } else { +// codeStream.getfield(this.codegenBinding); +// } +// } else { +// codeStream.invokestatic(syntheticReadAccessor); +// } +// } +// codeStream.generateImplicitConversion(implicitConversion); +// } else { +// if (!isStatic) { +// codeStream.invokeObjectGetClass(); // perform null check +// codeStream.pop(); +// } +// codeStream.generateConstant(this.codegenBinding.constant, implicitConversion); +// } +// } else { +// if (!isStatic){ +// codeStream.invokeObjectGetClass(); // perform null check +// codeStream.pop(); +// } +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } +// +// public void generateCompoundAssignment( +// BlockScope currentScope, +// CodeStream codeStream, +// Expression expression, +// int operator, +// int assignmentImplicitConversion, +// boolean valueRequired) { +// +// boolean isStatic; +// receiver.generateCode( +// currentScope, +// codeStream, +// !(isStatic = this.codegenBinding.isStatic())); +// if (isStatic) { +// if (syntheticReadAccessor == null) { +// codeStream.getstatic(this.codegenBinding); +// } else { +// codeStream.invokestatic(syntheticReadAccessor); +// } +// } else { +// codeStream.dup(); +// if (syntheticReadAccessor == null) { +// codeStream.getfield(this.codegenBinding); +// } else { +// codeStream.invokestatic(syntheticReadAccessor); +// } +// } +// int operationTypeID; +// if ((operationTypeID = implicitConversion >> 4) == T_String) { +// codeStream.generateStringAppend(currentScope, null, expression); +// } else { +// // promote the array reference to the suitable operation type +// codeStream.generateImplicitConversion(implicitConversion); +// // generate the increment value (will by itself be promoted to the operation value) +// if (expression == IntLiteral.One) { // prefix operation +// codeStream.generateConstant(expression.constant, implicitConversion); +// } else { +// expression.generateCode(currentScope, codeStream, true); +// } +// // perform the operation +// codeStream.sendOperator(operator, operationTypeID); +// // cast the value back to the array reference type +// codeStream.generateImplicitConversion(assignmentImplicitConversion); +// } +// fieldStore( +// codeStream, +// this.codegenBinding, +// syntheticWriteAccessor, +// valueRequired); +// } +// +// public void generatePostIncrement( +// BlockScope currentScope, +// CodeStream codeStream, +// CompoundAssignment postIncrement, +// boolean valueRequired) { +// +// boolean isStatic; +// receiver.generateCode( +// currentScope, +// codeStream, +// !(isStatic = this.codegenBinding.isStatic())); +// if (isStatic) { +// if (syntheticReadAccessor == null) { +// codeStream.getstatic(this.codegenBinding); +// } else { +// codeStream.invokestatic(syntheticReadAccessor); +// } +// } else { +// codeStream.dup(); +// if (syntheticReadAccessor == null) { +// codeStream.getfield(this.codegenBinding); +// } else { +// codeStream.invokestatic(syntheticReadAccessor); +// } +// } +// if (valueRequired) { +// if (isStatic) { +// if ((this.codegenBinding.type == LongBinding) +// || (this.codegenBinding.type == DoubleBinding)) { +// codeStream.dup2(); +// } else { +// codeStream.dup(); +// } +// } else { // Stack: [owner][old field value] ---> [old field value][owner][old field value] +// if ((this.codegenBinding.type == LongBinding) +// || (this.codegenBinding.type == DoubleBinding)) { +// codeStream.dup2_x1(); +// } else { +// codeStream.dup_x1(); +// } +// } +// } +// codeStream.generateConstant( +// postIncrement.expression.constant, +// implicitConversion); +// codeStream.sendOperator(postIncrement.operator, this.codegenBinding.type.id); +// codeStream.generateImplicitConversion( +// postIncrement.assignmentImplicitConversion); +// fieldStore(codeStream, this.codegenBinding, syntheticWriteAccessor, false); +// } + + public static final Constant getConstantFor( + FieldBinding binding, + Reference reference, + boolean isImplicit, + Scope referenceScope) { + + //propagation of the constant. + + //ref can be a FieldReference, a SingleNameReference or a QualifiedNameReference + //indexInQualification may have a value greater than zero only for QualifiednameReference + //if ref==null then indexInQualification==0 AND implicitReceiver == false. This case is a + //degenerated case where a fake reference field (null) + //is associted to a real FieldBinding in order + //to allow its constant computation using the regular path (in other words, find the fieldDeclaration + //and proceed to its type resolution). As implicitReceiver is false, no error reporting + //against ref will be used ==> no nullPointerException risk .... + + //special treatment for langage-built-in field (their declaring class is null) + if (binding.declaringClass == null) { + //currently only one field "length" : the constant computation is never done + return NotAConstant; + } + if (!binding.isFinal()) { + return binding.constant = NotAConstant; + } + if (binding.constant != null) { + if (isImplicit || (reference instanceof QualifiedNameReference + && binding == ((QualifiedNameReference)reference).binding)) { + return binding.constant; + } + return NotAConstant; + } + + //The field has not been yet type checked. + //It also means that the field is not coming from a class that + //has already been compiled. It can only be from a class within + //compilation units to process. Thus the field is NOT from a BinaryTypeBinbing + + SourceTypeBinding typeBinding = (SourceTypeBinding) binding.declaringClass; + TypeDeclaration typeDecl = typeBinding.scope.referenceContext; + FieldDeclaration fieldDecl = typeDecl.declarationOf(binding); + + fieldDecl.resolve(binding.isStatic() //side effect on binding + ? typeDecl.staticInitializerScope + : typeDecl.initializerScope); + + if (isImplicit || (reference instanceof QualifiedNameReference + && binding == ((QualifiedNameReference)reference).binding)) { + return binding.constant; + } + return NotAConstant; + } + + public boolean isSuperAccess() { + + return receiver.isSuper(); + } + + public boolean isTypeAccess() { + + return receiver != null && receiver.isTypeReference(); + } + + /* + * No need to emulate access to protected fields since not implicitly accessed + */ + public void manageSyntheticReadAccessIfNecessary(BlockScope currentScope) { + + if (binding.isPrivate()) { + if ((currentScope.enclosingSourceType() != binding.declaringClass) + && (binding.constant == NotAConstant)) { + syntheticReadAccessor = + ((SourceTypeBinding) binding.declaringClass).addSyntheticMethod(binding, true); + currentScope.problemReporter().needToEmulateFieldReadAccess(binding, this); + return; + } + + } else if (receiver instanceof QualifiedSuperReference) { // qualified super + + // qualified super need emulation always + SourceTypeBinding destinationType = + (SourceTypeBinding) (((QualifiedSuperReference) receiver) + .currentCompatibleType); + syntheticReadAccessor = destinationType.addSyntheticMethod(binding, true); + currentScope.problemReporter().needToEmulateFieldReadAccess(binding, this); + return; + + } else if (binding.isProtected()) { + + SourceTypeBinding enclosingSourceType; + if (((bits & DepthMASK) != 0) + && binding.declaringClass.getPackage() + != (enclosingSourceType = currentScope.enclosingSourceType()).getPackage()) { + + SourceTypeBinding currentCompatibleType = + (SourceTypeBinding) enclosingSourceType.enclosingTypeAt( + (bits & DepthMASK) >> DepthSHIFT); + syntheticReadAccessor = currentCompatibleType.addSyntheticMethod(binding, true); + currentScope.problemReporter().needToEmulateFieldReadAccess(binding, this); + return; + } + } + // if the binding declaring class is not visible, need special action + // for runtime compatibility on 1.2 VMs : change the declaring class of the binding + // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type +// if (binding.declaringClass != this.receiverType +// && !this.receiverType.isArrayType() +// && binding.declaringClass != null // array.length +// && binding.constant == NotAConstant +// && ((currentScope.environment().options.targetJDK >= CompilerOptions.JDK1_2 +// && binding.declaringClass.id != T_Object) +// //no change for Object fields (in case there was) +// || !binding.declaringClass.canBeSeenBy(currentScope))) { +// this.codegenBinding = +// currentScope.enclosingSourceType().getUpdatedFieldBinding( +// binding, +// (ReferenceBinding) this.receiverType); +// } + } + + /* + * No need to emulate access to protected fields since not implicitly accessed + */ + public void manageSyntheticWriteAccessIfNecessary(BlockScope currentScope) { + + if (binding.isPrivate()) { + if (currentScope.enclosingSourceType() != binding.declaringClass) { + syntheticWriteAccessor = + ((SourceTypeBinding) binding.declaringClass).addSyntheticMethod(binding, false); + currentScope.problemReporter().needToEmulateFieldWriteAccess(binding, this); + return; + } + + } else if (receiver instanceof QualifiedSuperReference) { // qualified super + + // qualified super need emulation always + SourceTypeBinding destinationType = + (SourceTypeBinding) (((QualifiedSuperReference) receiver) + .currentCompatibleType); + syntheticWriteAccessor = destinationType.addSyntheticMethod(binding, false); + currentScope.problemReporter().needToEmulateFieldWriteAccess(binding, this); + return; + + } else if (binding.isProtected()) { + + SourceTypeBinding enclosingSourceType; + if (((bits & DepthMASK) != 0) + && binding.declaringClass.getPackage() + != (enclosingSourceType = currentScope.enclosingSourceType()).getPackage()) { + + SourceTypeBinding currentCompatibleType = + (SourceTypeBinding) enclosingSourceType.enclosingTypeAt( + (bits & DepthMASK) >> DepthSHIFT); + syntheticWriteAccessor = + currentCompatibleType.addSyntheticMethod(binding, false); + currentScope.problemReporter().needToEmulateFieldWriteAccess(binding, this); + return; + } + } + // if the binding declaring class is not visible, need special action + // for runtime compatibility on 1.2 VMs : change the declaring class of the binding + // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type +// if (binding.declaringClass != this.receiverType +// && !this.receiverType.isArrayType() +// && binding.declaringClass != null // array.length +// && binding.constant == NotAConstant +// && ((currentScope.environment().options.targetJDK >= CompilerOptions.JDK1_2 +// && binding.declaringClass.id != T_Object) +// //no change for Object fields (in case there was) +// || !binding.declaringClass.canBeSeenBy(currentScope))) { +// this.codegenBinding = +// currentScope.enclosingSourceType().getUpdatedFieldBinding( +// binding, +// (ReferenceBinding) this.receiverType); +// } + } + + public TypeBinding resolveType(BlockScope scope) { + + // Answer the signature type of the field. + // constants are propaged when the field is final + // and initialized with a (compile time) constant + + // regular receiver reference + this.receiverType = receiver.resolveType(scope); + if (this.receiverType == null) { + constant = NotAConstant; + return null; + } + // the case receiverType.isArrayType and token = 'length' is handled by the scope API + this.codegenBinding = + this.binding = scope.getField(this.receiverType, token, this); + if (!binding.isValidBinding()) { + constant = NotAConstant; + scope.problemReporter().invalidField(this, this.receiverType); + return null; + } + + if (isFieldUseDeprecated(binding, scope)) + scope.problemReporter().deprecatedField(binding, this); + + boolean isImplicitThisRcv = receiver.isImplicitThis(); + constant = FieldReference.getConstantFor(binding, this, isImplicitThisRcv, scope); + if (!isImplicitThisRcv) { + constant = NotAConstant; + } + if (binding.isStatic()) { + // static field accessed through receiver? legal but unoptimal (optional warning) + if (!(isImplicitThisRcv + || receiver.isSuper() + || (receiver instanceof NameReference + && (((NameReference) receiver).bits & BindingIds.TYPE) != 0))) { + scope.problemReporter().unnecessaryReceiverForStaticField(this, binding); + } + } + return this.resolvedType = binding.type; + } + + public void setActualReceiverType(ReferenceBinding receiverType) { + // ignored + } + + public void setDepth(int depth) { + + bits &= ~DepthMASK; // flush previous depth if any + if (depth > 0) { + bits |= (depth & 0xFF) << DepthSHIFT; // encoded on 8 bits + } + } + + public void setFieldIndex(int index) { + // ignored + } + + public String toStringExpression() { + + return receiver.toString() + "." //$NON-NLS-1$ + + new String(token); + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + receiver.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/FloatLiteral.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/FloatLiteral.java new file mode 100644 index 0000000..446aa9d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/FloatLiteral.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public class FloatLiteral extends NumberLiteral { + float value; + final static float Float_MIN_VALUE = Float.intBitsToFloat(1); // work-around VAJ problem 1F6IGUU +public FloatLiteral(char[] token, int s, int e) { + super(token, s,e); +} +public void computeConstant() { + + //the source is correctly formated so the exception should never occurs + + Float computedValue; + try { + computedValue = Float.valueOf(String.valueOf(source)); + } catch (NumberFormatException e) { + return; + } + + if (computedValue.doubleValue() > Float.MAX_VALUE){ + return; //may be Infinity + } + if (computedValue.floatValue() < Float_MIN_VALUE){ + // see 1F6IGUU + //only a true 0 can be made of zeros + //1.00000000e-46f is illegal .... + label : for (int i = 0; i < source.length; i++) { + switch (source[i]) { + case '.' : + case 'f' : + case 'F' : + case '0' : + break; + case 'e' : + case 'E' : + break label; //exposant are valid !.... + default : + return; //error + + + } + } + } + constant = Constant.fromValue(value = computedValue.floatValue()); +} +/** + * Code generation for float literal + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +//public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { +// int pc = codeStream.position; +// if (valueRequired) +// if ((implicitConversion >> 4) == T_float) +// codeStream.generateInlinedValue(value); +// else +// codeStream.generateConstant(constant, implicitConversion); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +public TypeBinding literalType(BlockScope scope) { + return FloatBinding; +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) { + visitor.visit(this, blockScope); + visitor.endVisit(this, blockScope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ForStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ForStatement.java new file mode 100644 index 0000000..5bbaa9f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ForStatement.java @@ -0,0 +1,353 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.LoopingFlowContext; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class ForStatement extends Statement { + + public Statement[] initializations; + public Expression condition; + public Statement[] increments; + public Statement action; + + //when there is no local declaration, there is no need of a new scope + //scope is positionned either to a new scope, or to the "upper"scope (see resolveType) + public boolean neededScope; + public BlockScope scope; + + private Label breakLabel, continueLabel; + + // for local variables table attributes + int preCondInitStateIndex = -1; + int condIfTrueInitStateIndex = -1; + int mergedInitStateIndex = -1; + + public ForStatement( + Statement[] initializations, + Expression condition, + Statement[] increments, + Statement action, + boolean neededScope, + int s, + int e) { + + this.sourceStart = s; + this.sourceEnd = e; + this.initializations = initializations; + this.condition = condition; + this.increments = increments; + this.action = action; + this.neededScope = neededScope; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + breakLabel = new Label(); + continueLabel = new Label(); + + // process the initializations + if (initializations != null) { + int count = initializations.length, i = 0; + while (i < count) { + flowInfo = initializations[i++].analyseCode(scope, flowContext, flowInfo); + } + } + preCondInitStateIndex = + currentScope.methodScope().recordInitializationStates(flowInfo); + + Constant cst = this.condition == null ? null : this.condition.constant; + boolean isConditionTrue = cst == null || (cst != NotAConstant && cst.booleanValue() == true); + boolean isConditionFalse = cst != null && (cst != NotAConstant && cst.booleanValue() == false); + + cst = this.condition == null ? null : this.condition.optimizedBooleanConstant(); + boolean isConditionOptimizedTrue = cst == null || (cst != NotAConstant && cst.booleanValue() == true); + boolean isConditionOptimizedFalse = cst != null && (cst != NotAConstant && cst.booleanValue() == false); + + // process the condition + LoopingFlowContext condLoopContext = null; + if (condition != null) { + if (!isConditionTrue) { + flowInfo = + condition.analyseCode( + scope, + (condLoopContext = + new LoopingFlowContext(flowContext, this, null, null, scope)), + flowInfo); + } + } + + // process the action + LoopingFlowContext loopingContext; + FlowInfo actionInfo; + if (action == null ){ +// || (action.isEmptyBlock() && currentScope.environment().options.complianceLevel <= CompilerOptions.JDK1_3)) { + if (condLoopContext != null) + condLoopContext.complainOnFinalAssignmentsInLoop(scope, flowInfo); + if (isConditionTrue) { + return FlowInfo.DEAD_END; + } else { + if (isConditionFalse){ + continueLabel = null; // for(;false;p()); + } + actionInfo = flowInfo.initsWhenTrue().copy(); + loopingContext = + new LoopingFlowContext(flowContext, this, breakLabel, continueLabel, scope); + } + } else { + loopingContext = + new LoopingFlowContext(flowContext, this, breakLabel, continueLabel, scope); + FlowInfo initsWhenTrue = flowInfo.initsWhenTrue(); + condIfTrueInitStateIndex = + currentScope.methodScope().recordInitializationStates(initsWhenTrue); + + if (isConditionFalse) { + actionInfo = FlowInfo.DEAD_END; + } else { + actionInfo = initsWhenTrue.copy(); + if (isConditionOptimizedFalse){ + actionInfo.setReachMode(FlowInfo.UNREACHABLE); + } + } + if (!actionInfo.complainIfUnreachable(action, scope, false)) { + actionInfo = action.analyseCode(scope, loopingContext, actionInfo); + } + + // code generation can be optimized when no need to continue in the loop + if (!actionInfo.isReachable() && !loopingContext.initsOnContinue.isReachable()) { + continueLabel = null; + } else { + if (condLoopContext != null) + condLoopContext.complainOnFinalAssignmentsInLoop(scope, flowInfo); + loopingContext.complainOnFinalAssignmentsInLoop(scope, actionInfo); + actionInfo = + actionInfo.mergedWith(loopingContext.initsOnContinue.unconditionalInits()); + // for increments + } + } + if ((continueLabel != null) && (increments != null)) { + LoopingFlowContext loopContext = + new LoopingFlowContext(flowContext, this, null, null, scope); + int i = 0, count = increments.length; + while (i < count) + actionInfo = increments[i++].analyseCode(scope, loopContext, actionInfo); + loopContext.complainOnFinalAssignmentsInLoop(scope, actionInfo); + } + + // infinite loop + FlowInfo mergedInfo; + if (isConditionOptimizedTrue) { + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates( + mergedInfo = loopingContext.initsOnBreak); + return mergedInfo; + } + + //end of loop: either condition false or break + mergedInfo = + flowInfo.initsWhenFalse().unconditionalInits().mergedWith( + loopingContext.initsOnBreak.unconditionalInits()); + if (isConditionOptimizedTrue && continueLabel == null){ + mergedInfo.setReachMode(FlowInfo.UNREACHABLE); + } + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(mergedInfo); + return mergedInfo; + } + + /** + * For statement code generation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// +// // generate the initializations +// if (initializations != null) { +// for (int i = 0, max = initializations.length; i < max; i++) { +// initializations[i].generateCode(scope, codeStream); +// } +// } +// +// // label management +// Label actionLabel = new Label(codeStream); +// Label conditionLabel = new Label(codeStream); +// breakLabel.codeStream = codeStream; +// if (continueLabel != null) { +// continueLabel.codeStream = codeStream; +// } +// // jump over the actionBlock +// if ((condition != null) +// && (condition.constant == NotAConstant) +// && !((action == null || action.isEmptyBlock()) && (increments == null))) { +// int jumpPC = codeStream.position; +// codeStream.goto_(conditionLabel); +// codeStream.recordPositionsFrom(jumpPC, condition.sourceStart); +// } +// // generate the loop action +// actionLabel.place(); +// if (action != null) { +// // Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect +// if (condIfTrueInitStateIndex != -1) { +// // insert all locals initialized inside the condition into the action generated prior to the condition +// codeStream.addDefinitelyAssignedVariables( +// currentScope, +// condIfTrueInitStateIndex); +// } +// action.generateCode(scope, codeStream); +// } +// // continuation point +// if (continueLabel != null) { +// continueLabel.place(); +// // generate the increments for next iteration +// if (increments != null) { +// for (int i = 0, max = increments.length; i < max; i++) { +// increments[i].generateCode(scope, codeStream); +// } +// } +// } +// +// // May loose some local variable initializations : affecting the local variable attributes +// if (preCondInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// preCondInitStateIndex); +// } +// +// // generate the condition +// conditionLabel.place(); +// if ((condition != null) && (condition.constant == NotAConstant)) { +// condition.generateOptimizedBoolean(scope, codeStream, actionLabel, null, true); +// } else { +// if (continueLabel != null) { +// codeStream.goto_(actionLabel); +// } +// } +// breakLabel.place(); +// +// // May loose some local variable initializations : affecting the local variable attributes +// if (neededScope) { +// codeStream.exitUserScope(scope); +// } +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public void resetStateForCodeGeneration() { + if (this.breakLabel != null) { + this.breakLabel.resetStateForCodeGeneration(); + } + if (this.continueLabel != null) { + this.continueLabel.resetStateForCodeGeneration(); + } + } + + public void resolve(BlockScope upperScope) { + + // use the scope that will hold the init declarations + scope = neededScope ? new BlockScope(upperScope) : upperScope; + if (initializations != null) + for (int i = 0, length = initializations.length; i < length; i++) + initializations[i].resolve(scope); + if (condition != null) { + TypeBinding type = condition.resolveTypeExpecting(scope, BooleanBinding); + condition.implicitWidening(type, type); + } + if (increments != null) + for (int i = 0, length = increments.length; i < length; i++) + increments[i].resolve(scope); + if (action != null) + action.resolve(scope); + } + + public String toString(int tab) { + + String s = tabString(tab) + "for ("; //$NON-NLS-1$ + if (!neededScope) + s = s + " //--NO upperscope scope needed\n" + tabString(tab) + " "; //$NON-NLS-2$ //$NON-NLS-1$ + //inits + if (initializations != null) { + for (int i = 0; i < initializations.length; i++) { + //nice only with expressions + s = s + initializations[i].toString(0); + if (i != (initializations.length - 1)) + s = s + " , "; //$NON-NLS-1$ + } + }; + s = s + "; "; //$NON-NLS-1$ + //cond + if (condition != null) + s = s + condition.toStringExpression(); + s = s + "; "; //$NON-NLS-1$ + //updates + if (increments != null) { + for (int i = 0; i < increments.length; i++) { + //nice only with expressions + s = s + increments[i].toString(0); + if (i != (increments.length - 1)) + s = s + " , "; //$NON-NLS-1$ + } + }; + s = s + ") "; //$NON-NLS-1$ + //block + if (action == null) + s = s + "{}"; //$NON-NLS-1$ + else + s = s + "\n" + action.toString(tab + 1); //$NON-NLS-1$ + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + if (initializations != null) { + int initializationsLength = initializations.length; + for (int i = 0; i < initializationsLength; i++) + initializations[i].traverse(visitor, scope); + } + + if (condition != null) + condition.traverse(visitor, scope); + + if (increments != null) { + int incrementsLength = increments.length; + for (int i = 0; i < incrementsLength; i++) + increments[i].traverse(visitor, scope); + } + + if (action != null) + action.traverse(visitor, scope); + } + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/IfStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/IfStatement.java new file mode 100644 index 0000000..74b907b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/IfStatement.java @@ -0,0 +1,274 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class IfStatement extends Statement { + + //this class represents the case of only one statement in + //either else and/or then branches. + + public Expression condition; + public Statement thenStatement; + public Statement elseStatement; + + boolean thenExit; + + // for local variables table attributes + int thenInitStateIndex = -1; + int elseInitStateIndex = -1; + int mergedInitStateIndex = -1; + + public IfStatement( + Expression condition, + Statement thenStatement, + int s, + int e) { + + this.condition = condition; + this.thenStatement = thenStatement; + sourceStart = s; + sourceEnd = e; + } + + public IfStatement( + Expression condition, + Statement thenStatement, + Statement elseStatement, + int s, + int e) { + + this.condition = condition; + this.thenStatement = thenStatement; + this.elseStatement = elseStatement; + sourceEnd = e; + sourceStart = s; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + // process the condition + flowInfo = condition.analyseCode(currentScope, flowContext, flowInfo); + + Constant cst = this.condition.optimizedBooleanConstant(); + boolean isConditionOptimizedTrue = cst != NotAConstant && cst.booleanValue() == true; + boolean isConditionOptimizedFalse = cst != NotAConstant && cst.booleanValue() == false; + + // process the THEN part + FlowInfo thenFlowInfo = flowInfo.initsWhenTrue().copy(); + if (isConditionOptimizedFalse) { + thenFlowInfo.setReachMode(FlowInfo.UNREACHABLE); + } + if (this.thenStatement != null) { + // Save info for code gen + thenInitStateIndex = + currentScope.methodScope().recordInitializationStates(thenFlowInfo); + if (!thenFlowInfo.complainIfUnreachable(thenStatement, currentScope, false)) { + thenFlowInfo = + thenStatement.analyseCode(currentScope, flowContext, thenFlowInfo); + } + }; + // optimizing the jump around the ELSE part + this.thenExit = !thenFlowInfo.isReachable(); + + // process the ELSE part + FlowInfo elseFlowInfo = flowInfo.initsWhenFalse().copy(); + if (isConditionOptimizedTrue) { + elseFlowInfo.setReachMode(FlowInfo.UNREACHABLE); + } + if (this.elseStatement != null) { + // Save info for code gen + elseInitStateIndex = + currentScope.methodScope().recordInitializationStates(elseFlowInfo); + if (!elseFlowInfo.complainIfUnreachable(elseStatement, currentScope, false)) { + elseFlowInfo = + elseStatement.analyseCode(currentScope, flowContext, elseFlowInfo); + } + } + + boolean elseExit = !elseFlowInfo.isReachable(); + + // merge THEN & ELSE initializations + FlowInfo mergedInfo; +// if (isConditionOptimizedTrue){ +// if (!this.thenExit) { +// mergedInfo = thenFlowInfo; +// } else { +// mergedInfo = elseFlowInfo.setReachMode(FlowInfo.UNREACHABLE); +// } +// +// } else if (isConditionOptimizedFalse) { +// if (!elseExit) { +// mergedInfo = elseFlowInfo; +// } else { +// mergedInfo = thenFlowInfo.setReachMode(FlowInfo.UNREACHABLE); +// } +// +// } else { +// mergedInfo = thenFlowInfo.mergedWith(elseFlowInfo.unconditionalInits()); +// } + if (isConditionOptimizedTrue){ + if (!this.thenExit) { + mergedInfo = thenFlowInfo.addPotentialInitializationsFrom(elseFlowInfo); + } else { + mergedInfo = elseFlowInfo.setReachMode(FlowInfo.UNREACHABLE); + } + + } else if (isConditionOptimizedFalse) { + if (!elseExit) { + mergedInfo = elseFlowInfo.addPotentialInitializationsFrom(thenFlowInfo); + } else { + mergedInfo = thenFlowInfo.setReachMode(FlowInfo.UNREACHABLE); + } + + } else { + mergedInfo = thenFlowInfo.mergedWith(elseFlowInfo.unconditionalInits()); + } + + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(mergedInfo); + return mergedInfo; + } + + /** + * If code generation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((this.bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// Label endifLabel = new Label(codeStream); +// +// // optimizing the then/else part code gen +// Constant cst; +// boolean hasThenPart = +// !(((cst = this.condition.optimizedBooleanConstant()) != NotAConstant +// && cst.booleanValue() == false) +// || this.thenStatement == null +// || this.thenStatement.isEmptyBlock()); +// boolean hasElsePart = +// !((cst != NotAConstant && cst.booleanValue() == true) +// || this.elseStatement == null +// || this.elseStatement.isEmptyBlock()); +// +// if (hasThenPart) { +// Label falseLabel; +// // generate boolean condition +// this.condition.generateOptimizedBoolean( +// currentScope, +// codeStream, +// null, +// (falseLabel = new Label(codeStream)), +// true); +// // May loose some local variable initializations : affecting the local variable attributes +// if (thenInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// thenInitStateIndex); +// codeStream.addDefinitelyAssignedVariables(currentScope, thenInitStateIndex); +// } +// // generate then statement +// this.thenStatement.generateCode(currentScope, codeStream); +// // jump around the else statement +// if (hasElsePart && !thenExit) { +// this.thenStatement.branchChainTo(endifLabel); +// int position = codeStream.position; +// codeStream.goto_(endifLabel); +// codeStream.updateLastRecordedEndPC(position); +// //goto is tagged as part of the thenAction block +// } +// falseLabel.place(); +// } else { +// if (hasElsePart) { +// // generate boolean condition +// this.condition.generateOptimizedBoolean( +// currentScope, +// codeStream, +// endifLabel, +// null, +// true); +// } else { +// // generate condition side-effects +// this.condition.generateCode(currentScope, codeStream, false); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } +// } +// // generate else statement +// if (hasElsePart) { +// // May loose some local variable initializations : affecting the local variable attributes +// if (elseInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// elseInitStateIndex); +// codeStream.addDefinitelyAssignedVariables(currentScope, elseInitStateIndex); +// } +// this.elseStatement.generateCode(currentScope, codeStream); +// } +// endifLabel.place(); +// // May loose some local variable initializations : affecting the local variable attributes +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public void resolve(BlockScope scope) { + + TypeBinding type = condition.resolveTypeExpecting(scope, BooleanBinding); + condition.implicitWidening(type, type); + if (thenStatement != null) + thenStatement.resolve(scope); + if (elseStatement != null) + elseStatement.resolve(scope); + } + + public String toString(int tab) { + + String inFront, s = tabString(tab); + inFront = s; + s = s + "if (" + condition.toStringExpression() + ") \n"; //$NON-NLS-1$ //$NON-NLS-2$ + s = s + thenStatement.toString(tab + 2) + ";"; //$NON-NLS-1$ + if (elseStatement != null) + s = s + "\n" + inFront + "else\n" + elseStatement.toString(tab + 2) + ";"; //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-3$ + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + condition.traverse(visitor, blockScope); + if (thenStatement != null) + thenStatement.traverse(visitor, blockScope); + if (elseStatement != null) + elseStatement.traverse(visitor, blockScope); + } + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ImportReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ImportReference.java new file mode 100644 index 0000000..d4b0966 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ImportReference.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.CompilationUnitScope; + +public class ImportReference extends AstNode { + + public char[][] tokens; + public long[] sourcePositions; //each entry is using the code : (start<<32) + end + public boolean onDemand = true; //most of the time + public int declarationEnd;// doesn't include an potential trailing comment + public int declarationSourceStart; + public int declarationSourceEnd; + public boolean used; + +public ImportReference(char[][] sources , long[] poss , boolean d) { + tokens = sources ; + sourcePositions = poss ; + onDemand = d; + sourceEnd = (int)(sourcePositions[sourcePositions.length-1] & 0x00000000FFFFFFFF); + sourceStart = (int)(sourcePositions[0]>>>32) ; +} +/** + * @return char[][] + */ +public char[][] getImportName() { + return tokens; +} +public String toString(int tab ){ + + return toString(tab,true); +} +public String toString(int tab, boolean withOnDemand) { + /* when withOnDemand is false, only the name is printed */ + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < tokens.length; i++) { + buffer.append(tokens[i]); + if (i < (tokens.length - 1)) { + buffer.append("."); //$NON-NLS-1$ + } + } + if (withOnDemand && onDemand) { + buffer.append(".*"); //$NON-NLS-1$ + } + return buffer.toString(); +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, CompilationUnitScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Initializer.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Initializer.java new file mode 100644 index 0000000..6058eb7 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Initializer.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.parser.UnitParser; + +public class Initializer extends FieldDeclaration { + + public Block block; + public int lastFieldID; + public int bodyStart; + public Initializer(Block block, int modifiers) { + this.block = block; + this.modifiers = modifiers; + + declarationSourceStart = sourceStart = bodyStart = block.sourceStart; + } + + public FlowInfo analyseCode( + MethodScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + return block.analyseCode(currentScope, flowContext, flowInfo); + } + + /** + * Code generation for a non-static initializer: + * standard block code gen + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// block.generateCode(currentScope, codeStream); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public boolean isField() { + + return false; + } + + public boolean isStatic() { + + return (modifiers & AccStatic) != 0; + } + + public void parseStatements( + UnitParser parser, + TypeDeclaration type, + CompilationUnitDeclaration unit) { + + //fill up the method body with statement + parser.parse(this, type, unit); + } + + public void resolve(MethodScope scope) { + + int previous = scope.fieldDeclarationIndex; + try { + scope.fieldDeclarationIndex = lastFieldID; + if (isStatic()) { + ReferenceBinding declaringType = scope.enclosingSourceType(); + if (declaringType.isNestedType() && !declaringType.isStatic()) + scope.problemReporter().innerTypesCannotDeclareStaticInitializers( + declaringType, + this); + } + block.resolve(scope); + } finally { + scope.fieldDeclarationIndex = previous; + } + } + + public String toString(int tab) { + + if (modifiers != 0) { + StringBuffer buffer = new StringBuffer(); + buffer.append(tabString(tab)); + buffer.append(modifiersString(modifiers)); + buffer.append("{\n"); //$NON-NLS-1$ + buffer.append(block.toStringStatements(tab)); + buffer.append(tabString(tab)); + buffer.append("}"); //$NON-NLS-1$ + return buffer.toString(); + } else { + return block.toString(tab); + } + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, MethodScope scope) { + + if (visitor.visit(this, scope)) { + block.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/InnerTypeDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/InnerTypeDeclaration.java new file mode 100644 index 0000000..fdce37d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/InnerTypeDeclaration.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.CompilationResult; + +public class InnerTypeDeclaration extends TypeDeclaration { + + public InnerTypeDeclaration(CompilationResult compilationResult){ + super(compilationResult); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/InstanceOfExpression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/InstanceOfExpression.java new file mode 100644 index 0000000..0d9ce97 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/InstanceOfExpression.java @@ -0,0 +1,254 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.Scope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public class InstanceOfExpression extends OperatorExpression { + + public Expression expression; + public TypeReference type; + + public InstanceOfExpression( + Expression expression, + TypeReference type, + int operator) { + + this.expression = expression; + this.type = type; + this.bits |= operator << OperatorSHIFT; + this.sourceStart = expression.sourceStart; + this.sourceEnd = type.sourceEnd; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + return expression + .analyseCode(currentScope, flowContext, flowInfo) + .unconditionalInits(); + } + + public final boolean areTypesCastCompatible( + BlockScope scope, + TypeBinding castType, + TypeBinding expressionType) { + + // see specifications p.68 + //A more cpmplete version of this method is provided on + //CastExpression (it deals with constant and need runtime checkcast) + + if (castType == expressionType) return true; + + //by grammatical construction, the first test is ALWAYS false + //if (castTb.isBaseType()) + //{ if (expressionTb.isBaseType()) + // { if (expression.isConstantValueOfTypeAssignableToType(expressionTb,castTb)) + // { return true;} + // else + // { if (expressionTb==castTb) + // { return true;} + // else + // { if (scope.areTypesCompatible(expressionTb,castTb)) + // { return true; } + // + // if (BaseTypeBinding.isNarrowing(castTb.id,expressionTb.id)) + // { return true;} + // return false;}}} + // else + // { return false; }} + //else + { //-------------checkcast to something which is NOT a basetype---------------------------------- + + //null is compatible with every thing .... + if (NullBinding == expressionType) { + return true; + } + if (expressionType.isArrayType()) { + if (castType.isArrayType()) { + //------- (castTb.isArray) expressionTb.isArray ----------- + TypeBinding expressionEltTb = ((ArrayBinding) expressionType).elementsType(scope); + if (expressionEltTb.isBaseType()) + // <---stop the recursion------- + return ((ArrayBinding) castType).elementsType(scope) == expressionEltTb; + //recursivly on the elts... + return areTypesCastCompatible( + scope, + ((ArrayBinding) castType).elementsType(scope), + expressionEltTb); + } + if (castType.isClass()) { + //------(castTb.isClass) expressionTb.isArray --------------- + if (scope.isJavaLangObject(castType)) + return true; + return false; + } + if (castType.isInterface()) { + //------- (castTb.isInterface) expressionTb.isArray ----------- + if (scope.isJavaLangCloneable(castType) || scope.isJavaIoSerializable(castType)) { + return true; + } + return false; + } + + return false; + } + if (expressionType.isBaseType()) { + return false; + } + if (expressionType.isClass()) { + if (castType.isArrayType()) { + // ---- (castTb.isArray) expressionTb.isClass ------- + if (scope.isJavaLangObject(expressionType)) { + return true; + } else { + return false; + } + } + if (castType.isClass()) { // ----- (castTb.isClass) expressionTb.isClass ------ + if (expressionType.isCompatibleWith(castType)) + return true; + else { + if (castType.isCompatibleWith(expressionType)) { + return true; + } + return false; + } + } + if (castType.isInterface()) { + // ----- (castTb.isInterface) expressionTb.isClass ------- + if (((ReferenceBinding) expressionType).isFinal()) { + //no subclass for expressionTb, thus compile-time check is valid + if (expressionType.isCompatibleWith(castType)) + return true; + return false; + } else { + return true; + } + } + + return false; + } + if (expressionType.isInterface()) { + if (castType.isArrayType()) { + // ----- (castTb.isArray) expressionTb.isInterface ------ + if (scope.isJavaLangCloneable(expressionType) + || scope.isJavaIoSerializable(expressionType)) + //potential runtime error + { + return true; + } + return false; + } + if (castType.isClass()) { + // ----- (castTb.isClass) expressionTb.isInterface -------- + if (scope.isJavaLangObject(castType)) + return true; + if (((ReferenceBinding) castType).isFinal()) { + //no subclass for castTb, thus compile-time check is valid + if (castType.isCompatibleWith(expressionType)) { + return true; + } + return false; + } + return true; + } + if (castType.isInterface()) { + // ----- (castTb.isInterface) expressionTb.isInterface ------- + if ((Scope.compareTypes(castType, expressionType) == NotRelated)) { + MethodBinding[] castTbMethods = ((ReferenceBinding) castType).methods(); + int castTbMethodsLength = castTbMethods.length; + MethodBinding[] expressionTbMethods = + ((ReferenceBinding) expressionType).methods(); + int expressionTbMethodsLength = expressionTbMethods.length; + for (int i = 0; i < castTbMethodsLength; i++) { + for (int j = 0; j < expressionTbMethodsLength; j++) { + if (castTbMethods[i].selector == expressionTbMethods[j].selector) { + if (castTbMethods[i].returnType != expressionTbMethods[j].returnType) { + if (castTbMethods[i].areParametersEqual(expressionTbMethods[j])) { + return false; + } + } + } + } + } + } + return true; + } + + return false; + } + + return false; + } + } + /** + * Code generation for instanceOfExpression + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// int pc = codeStream.position; +// expression.generateCode(currentScope, codeStream, true); +// codeStream.instance_of(type.resolvedType); +// if (!valueRequired) +// codeStream.pop(); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public TypeBinding resolveType(BlockScope scope) { + + constant = NotAConstant; + TypeBinding expressionType = expression.resolveType(scope); + TypeBinding checkType = type.resolveType(scope); + if (expressionType == null || checkType == null) + return null; + + if (!areTypesCastCompatible(scope, checkType, expressionType)) { + scope.problemReporter().notCompatibleTypesError(this, expressionType, checkType); + return null; + } + this.resolvedType = BooleanBinding; + return BooleanBinding; + } + + public String toStringExpressionNoParenthesis() { + + return expression.toStringExpression() + " instanceof " + //$NON-NLS-1$ + type.toString(0); + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + expression.traverse(visitor, scope); + type.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/IntLiteral.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/IntLiteral.java new file mode 100644 index 0000000..1c6ce09 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/IntLiteral.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.impl.DoubleConstant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public class IntLiteral extends NumberLiteral { + public int value; + + public static final IntLiteral + One = new IntLiteral(new char[]{'1'},0,0,1);//used for ++ and -- + + static final Constant FORMAT_ERROR = new DoubleConstant(1.0/0.0); // NaN; +public IntLiteral(char[] token, int s, int e) { + super(token, s,e); +} +public IntLiteral(char[] token, int s,int e, int value) { + this(token, s,e); + this.value = value; +} +public IntLiteral(int intValue) { + //special optimized constructor : the cst is the argument + + //value that should not be used + // tokens = null ; + // sourceStart = 0; + // sourceEnd = 0; + super(null,0,0); + constant = Constant.fromValue(intValue); + value = intValue; + +} +public void computeConstant() { + //a special constant is use for the potential Integer.MAX_VALUE+1 + //which is legal if used with a - as prefix....cool.... + //notice that Integer.MIN_VALUE == -2147483648 + + long MAX = Integer.MAX_VALUE; + if (this == One) { constant = Constant.One; return ;} + + int length = source.length; + long computedValue = 0L; + if (source[0] == '0') + { MAX = 0xFFFFFFFFL ; //a long in order to be positive ! + if (length == 1) { constant = Constant.fromValue(0); return ;} + final int shift,radix; + int j ; + if ( (source[1] == 'x') | (source[1] == 'X') ) + { shift = 4 ; j = 2; radix = 16;} + else + { shift = 3 ; j = 1; radix = 8;} + while (source[j]=='0') + { j++; //jump over redondant zero + if (j == length) + { //watch for 000000000000000000 :-( + constant = Constant.fromValue(value = (int)computedValue); + return ;}} + + while (j MAX) return /*constant stays null*/ ;}} + else + { //-----------regular case : radix = 10----------- + for (int i = 0 ; i < length;i++) + { int digitValue ; + if ((digitValue = Character.digit(source[i],10)) < 0 ) + { constant = FORMAT_ERROR; return ;} + computedValue = 10*computedValue + digitValue; + if (computedValue > MAX) return /*constant stays null*/ ; }} + + constant = Constant.fromValue(value = (int)computedValue); + +} +/** + * Code generation for int literal + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +//public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { +// int pc = codeStream.position; +// if (valueRequired) +// if ((implicitConversion >> 4) == T_int) +// codeStream.generateInlinedValue(value); +// else +// codeStream.generateConstant(constant, implicitConversion); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +public TypeBinding literalType(BlockScope scope) { + return IntBinding; +} +public final boolean mayRepresentMIN_VALUE(){ + //a special autorized int literral is 2147483648 + //which is ONE over the limit. This special case + //only is used in combinaison with - to denote + //the minimal value of int -2147483648 + + return ((source.length == 10) && + (source[0] == '2') && + (source[1] == '1') && + (source[2] == '4') && + (source[3] == '7') && + (source[4] == '4') && + (source[5] == '8') && + (source[6] == '3') && + (source[7] == '6') && + (source[8] == '4') && + (source[9] == '8'));} +public TypeBinding resolveType(BlockScope scope) { + // the format may be incorrect while the scanner could detect + // such an error only on painfull tests...easier and faster here + + TypeBinding tb = super.resolveType(scope); + if (constant == FORMAT_ERROR) { + constant = NotAConstant; + scope.problemReporter().constantOutOfFormat(this); + this.resolvedType = null; + return null; + } + return tb; +} +public String toStringExpression(){ + + if (source == null) + /* special optimized IntLiteral that are created by the compiler */ + return String.valueOf(value); + + return super.toStringExpression();} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/IntLiteralMinValue.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/IntLiteralMinValue.java new file mode 100644 index 0000000..76c4c02 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/IntLiteralMinValue.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.impl.Constant; + + +public class IntLiteralMinValue extends IntLiteral { + + final static char[] CharValue = new char[]{'-','2','1','4','7','4','8','3','6','4','8'}; + final static Constant MIN_VALUE = Constant.fromValue(Integer.MIN_VALUE) ; + +public IntLiteralMinValue() { + super(CharValue,0,0,Integer.MIN_VALUE); + constant = MIN_VALUE; +} +public void computeConstant(){ + + /*precomputed at creation time*/ } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LabeledStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LabeledStatement.java new file mode 100644 index 0000000..154aa8f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LabeledStatement.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.LabelFlowContext; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; + + +public class LabeledStatement extends Statement { + + public Statement statement; + public char[] label; + public Label targetLabel; + + // for local variables table attributes + int mergedInitStateIndex = -1; + + /** + * LabeledStatement constructor comment. + */ + public LabeledStatement(char[] l, Statement st, int s, int e) { + + this.statement = st; + this.label = l; + this.sourceStart = s; + this.sourceEnd = e; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + // need to stack a context to store explicit label, answer inits in case of normal completion merged + // with those relative to the exit path from break statement occurring inside the labeled statement. + if (statement == null) { + return flowInfo; + } else { + LabelFlowContext labelContext; + FlowInfo mergedInfo = + statement + .analyseCode( + currentScope, + (labelContext = + new LabelFlowContext( + flowContext, + this, + label, + (targetLabel = new Label()), + currentScope)), + flowInfo) + .mergedWith(labelContext.initsOnBreak); + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(mergedInfo); + return mergedInfo; + } + } + + public AstNode concreteStatement() { + + // return statement.concreteStatement(); // for supporting nested labels: a:b:c: someStatement (see 21912) + return statement; + } + + /** + * Code generation for labeled statement + * + * may not need actual source positions recording + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// int pc = codeStream.position; +// if (targetLabel != null) { +// targetLabel.codeStream = codeStream; +// if (statement != null) { +// statement.generateCode(currentScope, codeStream); +// } +// targetLabel.place(); +// } +// // May loose some local variable initializations : affecting the local variable attributes +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public void resolve(BlockScope scope) { + + statement.resolve(scope); + } + + public String toString(int tab) { + + String s = tabString(tab); + s += new String(label) + ": " + statement.toString(0); //$NON-NLS-1$ + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + statement.traverse(visitor, blockScope); + } + visitor.endVisit(this, blockScope); + } + + public void resetStateForCodeGeneration() { + if (this.targetLabel != null) { + this.targetLabel.resetStateForCodeGeneration(); + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Literal.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Literal.java new file mode 100644 index 0000000..7e1d239 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Literal.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public abstract class Literal extends Expression { + +public Literal(int s,int e) { + sourceStart = s ; + sourceEnd= e; +} + +public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { + return flowInfo; +} + +public abstract void computeConstant() ; + //ON ERROR constant STAYS NULL +public abstract TypeBinding literalType(BlockScope scope); +public TypeBinding resolveType(BlockScope scope) { + // compute the real value, which must range its type's range + + computeConstant(); + if (constant == null) { + scope.problemReporter().constantOutOfRange(this); + constant = Constant.NotAConstant; + return null; + } + this.resolvedType = literalType(scope); + return this.resolvedType; +} +public abstract char[] source() ; +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LocalDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LocalDeclaration.java new file mode 100644 index 0000000..0cb726c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LocalDeclaration.java @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BaseTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public class LocalDeclaration extends AbstractVariableDeclaration { + + public LocalVariableBinding binding; + + public LocalDeclaration( + Expression expr, + char[] name, + int sourceStart, + int sourceEnd) { + + initialization = expr; + this.name = name; + this.sourceStart = sourceStart; + this.sourceEnd = sourceEnd; + if (initialization != null) { + this.declarationSourceEnd = initialization.sourceEnd; + this.declarationEnd = initialization.sourceEnd; + } else { + this.declarationEnd = sourceEnd; + } + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + // record variable initialization if any + if (flowInfo.isReachable()) { + bits |= IsLocalDeclarationReachableMASK; // only set if actually reached + } + if (initialization == null) + return flowInfo; + + flowInfo = + initialization + .analyseCode(currentScope, flowContext, flowInfo) + .unconditionalInits(); + + // final int i = (i = 0); + // no need to complain since (i = 0) part will get the blame + //if (binding.isFinal() && flowInfo.isPotentiallyAssigned(binding)) { + // currentScope.problemReporter().duplicateInitializationOfFinalLocal(binding, this); + //} + + flowInfo.markAsDefinitelyAssigned(binding); + return flowInfo; + } + + public void checkModifiers() { + + //only potential valid modifier is <> + if (((modifiers & AccJustFlag) & ~AccFinal) != 0) + //AccModifierProblem -> other (non-visibility problem) + //AccAlternateModifierProblem -> duplicate modifier + //AccModifierProblem | AccAlternateModifierProblem -> visibility problem" + + modifiers = (modifiers & ~AccAlternateModifierProblem) | AccModifierProblem; + } + + /** + * Code generation for a local declaration: + * normal assignment to a local variable + unused variable handling + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// // even if not reachable, variable must be added to visible if allocated (28298) +// if (binding.resolvedPosition != -1) { +// codeStream.addVisibleLocalVariable(binding); +// } +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// Constant inlinedValue; +// +// // something to initialize? +// if (initialization != null) { +// // initialize to constant value? +// if ((inlinedValue = initialization.constant) != NotAConstant) { +// // forget initializing unused or final locals set to constant value (final ones are inlined) +// if (binding.resolvedPosition != -1) { // may need to preserve variable +// int initPC = codeStream.position; +// codeStream.generateConstant(inlinedValue, initialization.implicitConversion); +// codeStream.recordPositionsFrom(initPC, initialization.sourceStart); +// codeStream.store(binding, false); +// binding.recordInitializationStartPC(codeStream.position); +// // codeStream.lastInitStateIndexWhenRemovingInits = -2; // reinitialize remove index +// // codeStream.lastInitStateIndexWhenAddingInits = -2; // reinitialize add index +// } +// } else { // initializing to non-constant value +// initialization.generateCode(currentScope, codeStream, true); +// // if binding unused generate then discard the value +// if (binding.resolvedPosition != -1) { +// // 26903, need extra cast to store null in array local var +// if (binding.type.isArrayType() +// && (initialization.resolvedType == NullBinding // arrayLoc = null +// || ((initialization instanceof CastExpression) // arrayLoc = (type[])null +// && (((CastExpression)initialization).innermostCastedExpression().resolvedType == NullBinding)))){ +// codeStream.checkcast(binding.type); +// } +// codeStream.store(binding, false); +// if (binding.initializationCount == 0) { +// /* Variable may have been initialized during the code initializing it +// e.g. int i = (i = 1); +// */ +// binding.recordInitializationStartPC(codeStream.position); +// // codeStream.lastInitStateIndexWhenRemovingInits = -2; // reinitialize remove index +// // codeStream.lastInitStateIndexWhenAddingInits = -2; // reinitialize add index +// } +// } else { +// if ((binding.type == LongBinding) || (binding.type == DoubleBinding)) { +// codeStream.pop2(); +// } else { +// codeStream.pop(); +// } +// } +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public String name() { + + return String.valueOf(name); + } + + public void resolve(BlockScope scope) { + + // create a binding and add it to the scope + TypeBinding tb = type.resolveType(scope); + + checkModifiers(); + + if (tb != null) { + if (tb == VoidBinding) { + scope.problemReporter().variableTypeCannotBeVoid(this); + return; + } + if (tb.isArrayType() && ((ArrayBinding) tb).leafComponentType == VoidBinding) { + scope.problemReporter().variableTypeCannotBeVoidArray(this); + return; + } + } + + // duplicate checks + if ((binding = scope.duplicateName(name)) != null) { + // the name already exists... may carry on with the first binding... + scope.problemReporter().redefineLocal(this); + } else { + if ((modifiers & AccFinal)!= 0 && this.initialization == null) { + modifiers |= AccBlankFinal; + } + binding = new LocalVariableBinding(this, tb, modifiers, false); + scope.addLocalVariable(binding); + binding.constant = NotAConstant; + // allow to recursivelly target the binding.... + // the correct constant is harmed if correctly computed at the end of this method + } + + if (tb == null) { + if (initialization != null) + initialization.resolveType(scope); // want to report all possible errors + return; + } + + // store the constant for final locals + if (initialization != null) { + if (initialization instanceof ArrayInitializer) { + TypeBinding initTb = initialization.resolveTypeExpecting(scope, tb); + if (initTb != null) { + ((ArrayInitializer) initialization).binding = (ArrayBinding) initTb; + initialization.implicitWidening(tb, initTb); + } + } else { + TypeBinding initTb = initialization.resolveType(scope); + if (initTb != null) { + if (initialization.isConstantValueOfTypeAssignableToType(initTb, tb) + || (tb.isBaseType() && BaseTypeBinding.isWidening(tb.id, initTb.id)) + || initTb.isCompatibleWith(tb)) + initialization.implicitWidening(tb, initTb); + else + scope.problemReporter().typeMismatchError(initTb, tb, this); + } + } + + // change the constant in the binding when it is final + // (the optimization of the constant propagation will be done later on) + // cast from constant actual type to variable type + binding.constant = + binding.isFinal() + ? initialization.constant.castTo((tb.id << 4) + initialization.constant.typeID()) + : NotAConstant; + } + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + type.traverse(visitor, scope); + if (initialization != null) + initialization.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LocalTypeDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LocalTypeDeclaration.java new file mode 100644 index 0000000..6dbdb9c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LocalTypeDeclaration.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.problem.AbortType; + +public class LocalTypeDeclaration extends InnerTypeDeclaration { + public AbstractMethodDeclaration enclosingMethod; + +public LocalTypeDeclaration(CompilationResult compilationResult){ + super(compilationResult); +} + +/** + * Iteration for a local innertype + * + */ +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) { + if (ignoreFurtherInvestigation) + return; + try { + if (visitor.visit(this, blockScope)) { + if (superclass != null) + superclass.traverse(visitor, scope); + if (superInterfaces != null) { + int superInterfaceLength = superInterfaces.length; + for (int i = 0; i < superInterfaceLength; i++) + superInterfaces[i].traverse(visitor, scope); + } + if (memberTypes != null) { + int memberTypesLength = memberTypes.length; + for (int i = 0; i < memberTypesLength; i++) + memberTypes[i].traverse(visitor, scope); + } + if (fields != null) { + int fieldsLength = fields.length; + for (int i = 0; i < fieldsLength; i++) { + FieldDeclaration field; + if ((field = fields[i]).isStatic()) { + // local type cannot have static fields + } else { + field.traverse(visitor, initializerScope); + } + } + } + if (methods != null) { + int methodsLength = methods.length; + for (int i = 0; i < methodsLength; i++) + methods[i].traverse(visitor, scope); + } + } + visitor.endVisit(this, blockScope); + } catch (AbortType e) { + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LongLiteral.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LongLiteral.java new file mode 100644 index 0000000..f2a85b8 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LongLiteral.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.impl.DoubleConstant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public class LongLiteral extends NumberLiteral { + long value; + + static final Constant FORMAT_ERROR = new DoubleConstant(1.0/0.0); // NaN; + +public LongLiteral(char[] token, int s,int e) { + super(token, s,e); +} +public LongLiteral(char[] token, int s,int e, long value) { + this(token, s,e); + this.value = value; +} +public void computeConstant() { + //the overflow (when radix=10) is tested using the fact that + //the value should always grow during its computation + + int length = source.length - 1; //minus one because the last char is 'l' or 'L' + + long computedValue ; + if (source[0] == '0') + { if (length == 1) { constant = Constant.fromValue(0L); return; } + final int shift,radix; + int j ; + if ( (source[1] == 'x') | (source[1] == 'X') ) + { shift = 4 ; j = 2; radix = 16;} + else + { shift = 3 ; j = 1; radix = 8;} + int nbDigit = 0; + while (source[j]=='0') + { j++; //jump over redondant zero + if ( j == length) + { //watch for 0000000000000L + constant = Constant.fromValue(value = 0L); + return ;}} + + int digitValue ; + if ((digitValue = Character.digit(source[j++],radix)) < 0 ) + { constant = FORMAT_ERROR; return ;} + if (digitValue >= 8) nbDigit = 4; + else if (digitValue >= 4) nbDigit = 3; + else if (digitValue >= 2) nbDigit = 2; + else nbDigit = 1; //digitValue is not 0 + computedValue = digitValue ; + while (j 64) return /*constant stays null*/ ; + computedValue = (computedValue< computedValue) return /*constant stays null*/;}} + + constant = Constant.fromValue(value = computedValue); +} +/** + * Code generation for long literal + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +//public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { +// int pc = codeStream.position; +// if (valueRequired) +// if ((implicitConversion >> 4) == T_long) +// codeStream.generateInlinedValue(value); +// else +// codeStream.generateConstant(constant, implicitConversion); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +public TypeBinding literalType(BlockScope scope) { + return LongBinding; +} +public final boolean mayRepresentMIN_VALUE(){ + //a special autorized int literral is 9223372036854775808L + //which is ONE over the limit. This special case + //only is used in combinaison with - to denote + //the minimal value of int -9223372036854775808L + + return ((source.length == 20) && + (source[0] == '9') && + (source[1] == '2') && + (source[2] == '2') && + (source[3] == '3') && + (source[4] == '3') && + (source[5] == '7') && + (source[6] == '2') && + (source[7] == '0') && + (source[8] == '3') && + (source[9] == '6') && + (source[10] == '8') && + (source[11] == '5') && + (source[12] == '4') && + (source[13] == '7') && + (source[14] == '7') && + (source[15] == '5') && + (source[16] == '8') && + (source[17] == '0') && + (source[18] == '8'));} +public TypeBinding resolveType(BlockScope scope) { + // the format may be incorrect while the scanner could detect + // such error only on painfull tests...easier and faster here + + TypeBinding tb = super.resolveType(scope); + if (constant == FORMAT_ERROR) { + constant = NotAConstant; + scope.problemReporter().constantOutOfFormat(this); + this.resolvedType = null; + return null; + } + return tb; +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LongLiteralMinValue.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LongLiteralMinValue.java new file mode 100644 index 0000000..38cdfc4 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/LongLiteralMinValue.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.impl.Constant; + + +public class LongLiteralMinValue extends LongLiteral { + + final static char[] CharValue = new char[]{'-', '9','2','2','3','3','7','2','0','3','6','8','5','4','7','7','5','8','0','8','L'}; + final static Constant MIN_VALUE = Constant.fromValue(Long.MIN_VALUE) ; + +public LongLiteralMinValue(){ + super(CharValue,0,0,Long.MIN_VALUE); + constant = MIN_VALUE; +} +public void computeConstant() { + + /*precomputed at creation time*/} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/MagicLiteral.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/MagicLiteral.java new file mode 100644 index 0000000..5acab73 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/MagicLiteral.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +public abstract class MagicLiteral extends Literal { +public MagicLiteral(int s , int e) { + super(s,e); +} +public boolean isValidJavaStatement(){ + //should never be reach, but with a bug in the ast tree.... + //see comment on the Statement class + + return false ;} +/** + * source method comment. + */ +public char[] source() { + return null; +} +public String toStringExpression(){ + + return new String(source()) ; } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/MemberTypeDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/MemberTypeDeclaration.java new file mode 100644 index 0000000..aa901e8 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/MemberTypeDeclaration.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope; +import net.sourceforge.phpdt.internal.compiler.problem.AbortType; + +public class MemberTypeDeclaration extends InnerTypeDeclaration { + public TypeDeclaration enclosingType; + +public MemberTypeDeclaration(CompilationResult compilationResult){ + super(compilationResult); +} +/** + * Iteration for a member innertype + * + */ +public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope classScope) { + if (ignoreFurtherInvestigation) + return; + try { + if (visitor.visit(this, classScope)) { + if (superclass != null) + superclass.traverse(visitor, scope); + if (superInterfaces != null) { + int superInterfaceLength = superInterfaces.length; + for (int i = 0; i < superInterfaceLength; i++) + superInterfaces[i].traverse(visitor, scope); + } + if (memberTypes != null) { + int memberTypesLength = memberTypes.length; + for (int i = 0; i < memberTypesLength; i++) + memberTypes[i].traverse(visitor, scope); + } + if (fields != null) { + int fieldsLength = fields.length; + for (int i = 0; i < fieldsLength; i++) { + FieldDeclaration field; + if ((field = fields[i]).isStatic()) { + field.traverse(visitor, staticInitializerScope); + } else { + field.traverse(visitor, initializerScope); + } + } + } + if (methods != null) { + int methodsLength = methods.length; + for (int i = 0; i < methodsLength; i++) + methods[i].traverse(visitor, scope); + } + } + visitor.endVisit(this, classScope); + } catch (AbortType e) { + } +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/MessageSend.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/MessageSend.java new file mode 100644 index 0000000..bf10b1e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/MessageSend.java @@ -0,0 +1,301 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BindingIds; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.InvocationSite; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ProblemMethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class MessageSend extends Expression implements InvocationSite { + public Expression receiver ; + public char[] selector ; + public Expression[] arguments ; + public MethodBinding binding, codegenBinding; + + public long nameSourcePosition ; //(start<<32)+end + + MethodBinding syntheticAccessor; + + public TypeBinding receiverType, qualifyingType; + +public MessageSend() { + +} +public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { + + flowInfo = receiver.analyseCode(currentScope, flowContext, flowInfo, !binding.isStatic()).unconditionalInits(); + if (arguments != null) { + int length = arguments.length; + for (int i = 0; i < length; i++) { + flowInfo = arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits(); + } + } + ReferenceBinding[] thrownExceptions; + if ((thrownExceptions = binding.thrownExceptions) != NoExceptions) { + // must verify that exceptions potentially thrown by this expression are caught in the method + flowContext.checkExceptionHandlers(thrownExceptions, this, flowInfo, currentScope); + } + manageSyntheticAccessIfNecessary(currentScope); + return flowInfo; +} +/** + * MessageSend code generation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +//public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { +// +// int pc = codeStream.position; +// +// // generate receiver/enclosing instance access +// boolean isStatic = codegenBinding.isStatic(); +// // outer access ? +// if (!isStatic && ((bits & DepthMASK) != 0) && receiver.isImplicitThis()){ +// // outer method can be reached through emulation if implicit access +// ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT); +// Object[] path = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/); +// codeStream.generateOuterAccess(path, this, targetType, currentScope); +// } else { +// receiver.generateCode(currentScope, codeStream, !isStatic); +// } +// // generate arguments +// if (arguments != null){ +// for (int i = 0, max = arguments.length; i < max; i++){ +// arguments[i].generateCode(currentScope, codeStream, true); +// } +// } +// // actual message invocation +// if (syntheticAccessor == null){ +// if (isStatic){ +// codeStream.invokestatic(codegenBinding); +// } else { +// if( (receiver.isSuper()) || codegenBinding.isPrivate()){ +// codeStream.invokespecial(codegenBinding); +// } else { +// if (codegenBinding.declaringClass.isInterface()){ +// codeStream.invokeinterface(codegenBinding); +// } else { +// codeStream.invokevirtual(codegenBinding); +// } +// } +// } +// } else { +// codeStream.invokestatic(syntheticAccessor); +// } +// // operation on the returned value +// if (valueRequired){ +// // implicit conversion if necessary +// codeStream.generateImplicitConversion(implicitConversion); +// } else { +// // pop return value if any +// switch(binding.returnType.id){ +// case T_long : +// case T_double : +// codeStream.pop2(); +// break; +// case T_void : +// break; +// default: +// codeStream.pop(); +// } +// } +// codeStream.recordPositionsFrom(pc, (int)(this.nameSourcePosition >>> 32)); // highlight selector +//} +public boolean isSuperAccess() { + return receiver.isSuper(); +} +public boolean isTypeAccess() { + return receiver != null && receiver.isTypeReference(); +} +public void manageSyntheticAccessIfNecessary(BlockScope currentScope){ + + if (binding.isPrivate()){ + + // depth is set for both implicit and explicit access (see MethodBinding#canBeSeenBy) + if (currentScope.enclosingSourceType() != binding.declaringClass){ + + syntheticAccessor = ((SourceTypeBinding)binding.declaringClass).addSyntheticMethod(binding, isSuperAccess()); + currentScope.problemReporter().needToEmulateMethodAccess(binding, this); + return; + } + + } else if (receiver instanceof QualifiedSuperReference){ // qualified super + + // qualified super need emulation always + SourceTypeBinding destinationType = (SourceTypeBinding)(((QualifiedSuperReference)receiver).currentCompatibleType); + syntheticAccessor = destinationType.addSyntheticMethod(binding, isSuperAccess()); + currentScope.problemReporter().needToEmulateMethodAccess(binding, this); + return; + + } else if (binding.isProtected()){ + + SourceTypeBinding enclosingSourceType; + if (((bits & DepthMASK) != 0) + && binding.declaringClass.getPackage() + != (enclosingSourceType = currentScope.enclosingSourceType()).getPackage()){ + + SourceTypeBinding currentCompatibleType = (SourceTypeBinding)enclosingSourceType.enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT); + syntheticAccessor = currentCompatibleType.addSyntheticMethod(binding, isSuperAccess()); + currentScope.problemReporter().needToEmulateMethodAccess(binding, this); + return; + } + } + // if the binding declaring class is not visible, need special action + // for runtime compatibility on 1.2 VMs : change the declaring class of the binding + // NOTE: from target 1.2 on, method's declaring class is touched if any different from receiver type + // and not from Object or implicit static method call. +// if (binding.declaringClass != this.qualifyingType +// && !this.qualifyingType.isArrayType() +// && ((currentScope.environment().options.targetJDK >= CompilerOptions.JDK1_2 +// && (!receiver.isImplicitThis() || !binding.isStatic()) +// && binding.declaringClass.id != T_Object) // no change for Object methods +// || !binding.declaringClass.canBeSeenBy(currentScope))) { +// +// this.codegenBinding = currentScope.enclosingSourceType().getUpdatedMethodBinding(binding, (ReferenceBinding) this.qualifyingType); +// } +} + +public TypeBinding resolveType(BlockScope scope) { + // Answer the signature return type + // Base type promotion + + constant = NotAConstant; + this.qualifyingType = this.receiverType = receiver.resolveType(scope); + + // will check for null after args are resolved + TypeBinding[] argumentTypes = NoParameters; + if (arguments != null) { + boolean argHasError = false; // typeChecks all arguments + int length = arguments.length; + argumentTypes = new TypeBinding[length]; + for (int i = 0; i < length; i++){ + if ((argumentTypes[i] = arguments[i].resolveType(scope)) == null){ + argHasError = true; + } + } + if (argHasError){ + if(receiverType instanceof ReferenceBinding) { + // record any selector match, for clients who may still need hint about possible method match + this.codegenBinding = this.binding = scope.findMethod((ReferenceBinding)receiverType, selector, new TypeBinding[]{}, this); + } + return null; + } + } + if (this.receiverType == null) + return null; + + // base type cannot receive any message + if (this.receiverType.isBaseType()) { + scope.problemReporter().errorNoMethodFor(this, this.receiverType, argumentTypes); + return null; + } + + this.codegenBinding = this.binding = + receiver.isImplicitThis() + ? scope.getImplicitMethod(selector, argumentTypes, this) + : scope.getMethod(this.receiverType, selector, argumentTypes, this); + if (!binding.isValidBinding()) { + if (binding.declaringClass == null) { + if (this.receiverType instanceof ReferenceBinding) { + binding.declaringClass = (ReferenceBinding) this.receiverType; + } else { + scope.problemReporter().errorNoMethodFor(this, this.receiverType, argumentTypes); + return null; + } + } + scope.problemReporter().invalidMethod(this, binding); + // record the closest match, for clients who may still need hint about possible method match + if (binding instanceof ProblemMethodBinding){ + MethodBinding closestMatch = ((ProblemMethodBinding)binding).closestMatch; + if (closestMatch != null) this.codegenBinding = this.binding = closestMatch; + } + return binding == null ? null : binding.returnType; + } + if (!binding.isStatic()) { + // the "receiver" must not be a type, in other words, a NameReference that the TC has bound to a Type + if (receiver instanceof NameReference + && (((NameReference) receiver).bits & BindingIds.TYPE) != 0) { + scope.problemReporter().mustUseAStaticMethod(this, binding); + } + } else { + // static message invoked through receiver? legal but unoptimal (optional warning). + if (!(receiver.isImplicitThis() + || receiver.isSuper() + || (receiver instanceof NameReference + && (((NameReference) receiver).bits & BindingIds.TYPE) != 0))) { + scope.problemReporter().unnecessaryReceiverForStaticMethod(this, binding); + } + } + if (arguments != null) + for (int i = 0; i < arguments.length; i++) + arguments[i].implicitWidening(binding.parameters[i], argumentTypes[i]); + + //-------message send that are known to fail at compile time----------- + if (binding.isAbstract()) { + if (receiver.isSuper()) { + scope.problemReporter().cannotDireclyInvokeAbstractMethod(this, binding); + } + // abstract private methods cannot occur nor abstract static............ + } + if (isMethodUseDeprecated(binding, scope)) + scope.problemReporter().deprecatedMethod(binding, this); + + return this.resolvedType = binding.returnType; +} +public void setActualReceiverType(ReferenceBinding receiverType) { + this.qualifyingType = receiverType; +} +public void setDepth(int depth) { + bits &= ~DepthMASK; // flush previous depth if any + if (depth > 0) { + bits |= (depth & 0xFF) << DepthSHIFT; // encoded on 8 bits + } +} +public void setFieldIndex(int depth) { + // ignore for here +} + +public String toStringExpression(){ + + String s = ""; //$NON-NLS-1$ + if (!receiver.isImplicitThis()) + s = s + receiver.toStringExpression()+"."; //$NON-NLS-1$ + s = s + new String(selector) + "(" ; //$NON-NLS-1$ + if (arguments != null) + for (int i = 0; i < arguments.length ; i ++) + { s = s + arguments[i].toStringExpression(); + if ( i != arguments.length -1 ) s = s + " , " ;};; //$NON-NLS-1$ + s =s + ")" ; //$NON-NLS-1$ + return s; +} + +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) { + if (visitor.visit(this, blockScope)) { + receiver.traverse(visitor, blockScope); + if (arguments != null) { + int argumentsLength = arguments.length; + for (int i = 0; i < argumentsLength; i++) + arguments[i].traverse(visitor, blockScope); + } + } + visitor.endVisit(this, blockScope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/MethodDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/MethodDeclaration.java new file mode 100644 index 0000000..e63c662 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/MethodDeclaration.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.ExceptionHandlingFlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.InitializationFlowContext; +import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; +import net.sourceforge.phpdt.internal.compiler.parser.UnitParser; +import net.sourceforge.phpdt.internal.compiler.problem.AbortMethod; + +public class MethodDeclaration extends AbstractMethodDeclaration { + + public TypeReference returnType; + + /** + * MethodDeclaration constructor comment. + */ + public MethodDeclaration(CompilationResult compilationResult) { + super(compilationResult); + } + + public void analyseCode(ClassScope classScope, InitializationFlowContext initializationContext, FlowInfo flowInfo) { + + // starting of the code analysis for methods + if (ignoreFurtherInvestigation) + return; + try { + if (binding == null) + return; + + if (this.binding.isPrivate() && !this.binding.isPrivateUsed()) { + if (!classScope.referenceCompilationUnit().compilationResult.hasSyntaxError()) { + scope.problemReporter().unusedPrivateMethod(this); + } + } + + // may be in a non necessary for innerclass with static final constant fields + if (binding.isAbstract()) // || binding.isNative()) + return; + + ExceptionHandlingFlowContext methodContext = + new ExceptionHandlingFlowContext(initializationContext, this, binding.thrownExceptions, scope, FlowInfo.DEAD_END); + + // propagate to statements + if (statements != null) { + boolean didAlreadyComplain = false; + for (int i = 0, count = statements.length; i < count; i++) { + Statement stat; + if (!flowInfo.complainIfUnreachable((stat = statements[i]), scope, didAlreadyComplain)) { + flowInfo = stat.analyseCode(scope, methodContext, flowInfo); + } else { + didAlreadyComplain = true; + } + } + } + // check for missing returning path + TypeBinding returnType = binding.returnType; + if ((returnType == VoidBinding) || isAbstract()) { + this.needFreeReturn = flowInfo.isReachable(); + } else { + if (flowInfo != FlowInfo.DEAD_END) { + scope.problemReporter().shouldReturn(returnType, this); + } + } + } catch (AbortMethod e) { + this.ignoreFurtherInvestigation = true; + } + } + + public void parseStatements(UnitParser parser, CompilationUnitDeclaration unit) { + + //fill up the method body with statement + if (ignoreFurtherInvestigation) + return; + parser.parse(this, unit); + } + + public void resolveStatements() { + + // ========= abort on fatal error ============= + if (this.returnType != null && this.binding != null) { + this.returnType.resolvedType = this.binding.returnType; + // record the return type binding + } + // look if the name of the method is correct + if (binding != null && isTypeUseDeprecated(binding.returnType, scope)) + scope.problemReporter().deprecatedType(binding.returnType, returnType); + + if (scope != null) { + if (CharOperation.equals(scope.enclosingSourceType().sourceName, selector)) + scope.problemReporter().methodWithConstructorName(this); + + // by grammatical construction, interface methods are always abstract + if (!scope.enclosingSourceType().isInterface()) { + + // if a method has an semicolon body and is not declared as abstract==>error + // native methods may have a semicolon body + // if ((modifiers & AccSemicolonBody) != 0) { + // if ((modifiers & AccNative) == 0) + // if ((modifiers & AccAbstract) == 0) + // scope.problemReporter().methodNeedingAbstractModifier(this); + // } else { + // // the method HAS a body --> abstract native modifiers are forbiden + // if (((modifiers & AccNative) != 0) || ((modifiers & AccAbstract) != 0)) + // scope.problemReporter().methodNeedingNoBody(this); + // } + } + } + super.resolveStatements(); + } + + public String returnTypeToString(int tab) { + + if (returnType == null) + return ""; //$NON-NLS-1$ + return returnType.toString(tab) + " "; //$NON-NLS-1$ + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope classScope) { + + if (visitor.visit(this, classScope)) { + if (returnType != null) + returnType.traverse(visitor, scope); + if (arguments != null) { + int argumentLength = arguments.length; + for (int i = 0; i < argumentLength; i++) + arguments[i].traverse(visitor, scope); + } + if (thrownExceptions != null) { + int thrownExceptionsLength = thrownExceptions.length; + for (int i = 0; i < thrownExceptionsLength; i++) + thrownExceptions[i].traverse(visitor, scope); + } + if (statements != null) { + int statementsLength = statements.length; + for (int i = 0; i < statementsLength; i++) + statements[i].traverse(visitor, scope); + } + } + visitor.endVisit(this, classScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/NameReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/NameReference.java new file mode 100644 index 0000000..1080fa1 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/NameReference.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.lookup.Binding; +import net.sourceforge.phpdt.internal.compiler.lookup.BindingIds; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.InvocationSite; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public abstract class NameReference extends Reference implements InvocationSite, BindingIds { + + public Binding binding, codegenBinding; //may be aTypeBinding-aFieldBinding-aLocalVariableBinding + + public TypeBinding receiverType; // raw receiver type + public TypeBinding actualReceiverType; // modified receiver type - actual one according to namelookup + + //the error printing + //some name reference are build as name reference but + //only used as type reference. When it happens, instead of + //creating a new objet (aTypeReference) we just flag a boolean + //This concesion is valuable while their are cases when the NameReference + //will be a TypeReference (static message sends.....) and there is + //no changeClass in java. +public NameReference() { + super(); + bits |= TYPE | VARIABLE; // restrictiveFlag + +} +public FieldBinding fieldBinding() { + //this method should be sent ONLY after a check against isFieldReference() + //check its use doing senders......... + + return (FieldBinding) binding ; +} +public boolean isSuperAccess() { + return false; +} +public boolean isTypeAccess() { + // null is acceptable when we are resolving the first part of a reference + return binding == null || binding instanceof ReferenceBinding; +} +public boolean isTypeReference() { + return binding instanceof ReferenceBinding; +} +public void setActualReceiverType(ReferenceBinding receiverType) { + this.actualReceiverType = receiverType; +} +public void setDepth(int depth) { + bits &= ~DepthMASK; // flush previous depth if any + if (depth > 0) { + bits |= (depth & 0xFF) << DepthSHIFT; // encoded on 8 bits + } +} +public void setFieldIndex(int index){ + // ignored +} + +public abstract String unboundReferenceErrorName(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/NullLiteral.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/NullLiteral.java new file mode 100644 index 0000000..86bdb79 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/NullLiteral.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class NullLiteral extends MagicLiteral { + + static final char[] source = {'n' , 'u' , 'l' , 'l'}; + + public NullLiteral(int s , int e) { + + super(s,e); + } + + public void computeConstant() { + + constant = NotAConstant; + } + + /** + * Code generation for the null literal + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { +// int pc = codeStream.position; +// if (valueRequired) +// codeStream.aconst_null(); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + public TypeBinding literalType(BlockScope scope) { + return NullBinding; + } + + /** + * + */ + public char[] source() { + return source; + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/NumberLiteral.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/NumberLiteral.java new file mode 100644 index 0000000..4e29d26 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/NumberLiteral.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +public abstract class NumberLiteral extends Literal { + char[] source; +public NumberLiteral(char[] token, int s, int e) { + this(s,e) ; + source = token ; +} +public NumberLiteral(int s, int e) { + super (s,e) ; +} +public boolean isValidJavaStatement(){ + //should never be reach, but with a bug in the ast tree.... + //see comment on the Statement class + + return false ;} +public char[] source(){ + return source;} +public String toStringExpression(){ + + return new String(source);} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/OR_OR_Expression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/OR_OR_Expression.java new file mode 100644 index 0000000..2dc01c1 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/OR_OR_Expression.java @@ -0,0 +1,306 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; + +//dedicated treatment for the || +public class OR_OR_Expression extends BinaryExpression { + + int rightInitStateIndex = -1; + int mergedInitStateIndex = -1; + + public OR_OR_Expression(Expression left, Expression right, int operator) { + super(left, right, operator); + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + Constant cst = this.left.optimizedBooleanConstant(); + boolean isLeftOptimizedTrue = cst != NotAConstant && cst.booleanValue() == true; + boolean isLeftOptimizedFalse = cst != NotAConstant && cst.booleanValue() == false; + + if (isLeftOptimizedFalse) { + // FALSE || anything + // need to be careful of scenario: + // (x || y) || !z, if passing the left info to the right, it would be swapped by the ! + FlowInfo mergedInfo = left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits(); + mergedInfo = right.analyseCode(currentScope, flowContext, mergedInfo); + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(mergedInfo); + return mergedInfo; + } + + FlowInfo leftInfo = left.analyseCode(currentScope, flowContext, flowInfo); + + // need to be careful of scenario: + // (x || y) || !z, if passing the left info to the right, it would be swapped by the ! + FlowInfo rightInfo = leftInfo.initsWhenFalse().unconditionalInits().copy(); + rightInitStateIndex = + currentScope.methodScope().recordInitializationStates(rightInfo); + + int previousMode = rightInfo.reachMode(); + if (isLeftOptimizedTrue){ + rightInfo.setReachMode(FlowInfo.UNREACHABLE); + } + rightInfo = right.analyseCode(currentScope, flowContext, rightInfo); + FlowInfo falseMergedInfo = rightInfo.initsWhenFalse().copy(); + rightInfo.setReachMode(previousMode); // reset after falseMergedInfo got extracted + + FlowInfo mergedInfo = FlowInfo.conditional( + // merging two true initInfos for such a negative case: if ((t && (b = t)) || f) r = b; // b may not have been initialized + leftInfo.initsWhenTrue().copy().unconditionalInits().mergedWith( + rightInfo.initsWhenTrue().copy().unconditionalInits()), + falseMergedInfo); + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(mergedInfo); + return mergedInfo; + } + + /** + * Code generation for a binary operation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// int pc = codeStream.position; +// Label falseLabel, endLabel; +// if (constant != Constant.NotAConstant) { +// if (valueRequired) +// codeStream.generateConstant(constant, implicitConversion); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// return; +// } +// bits |= OnlyValueRequiredMASK; +// generateOptimizedBoolean( +// currentScope, +// codeStream, +// null, +// (falseLabel = new Label(codeStream)), +// valueRequired); +// /* improving code gen for such a case: boolean b = i < 0 || true; +// * since the label has never been used, we have the inlined value on the stack. */ +// if (falseLabel.hasForwardReferences()) { +// if (valueRequired) { +// codeStream.iconst_1(); +// if ((bits & ValueForReturnMASK) != 0) { +// codeStream.ireturn(); +// falseLabel.place(); +// codeStream.iconst_0(); +// } else { +// codeStream.goto_(endLabel = new Label(codeStream)); +// codeStream.decrStackSize(1); +// falseLabel.place(); +// codeStream.iconst_0(); +// endLabel.place(); +// } +// } else { +// falseLabel.place(); +// } +// } +// if (valueRequired) { +// codeStream.generateImplicitConversion(implicitConversion); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } +// +// /** +// * Boolean operator code generation +// * Optimized operations are: || +// */ +// public void generateOptimizedBoolean( +// BlockScope currentScope, +// CodeStream codeStream, +// Label trueLabel, +// Label falseLabel, +// boolean valueRequired) { +// if (constant != Constant.NotAConstant) { +// super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired); +// return; +// } +// Constant condConst; +// if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) { +// if (condConst.booleanValue() == true) { +// // || x +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// if (valueRequired) { +// if ((bits & OnlyValueRequiredMASK) != 0) { +// codeStream.iconst_1(); +// } else { +// if (trueLabel != null) { +// codeStream.goto_(trueLabel); +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// } else { +// // || x +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// if (rightInitStateIndex != -1) { +// codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex); +// } +// if ((bits & OnlyValueRequiredMASK) != 0) { +// right.generateCode(currentScope, codeStream, valueRequired); +// } else { +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// } +// } +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// return; +// } +// if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) { +// if (condConst.booleanValue() == true) { +// // x || +// Label internalFalseLabel = new Label(codeStream); +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// null, +// internalFalseLabel, // will be true in the end +// false); +// if (rightInitStateIndex != -1) { +// codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex); +// } +// internalFalseLabel.place(); +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// if (valueRequired) { +// if ((bits & OnlyValueRequiredMASK) != 0) { +// codeStream.iconst_1(); +// } else { +// if (trueLabel != null) { +// codeStream.goto_(trueLabel); +// } +// } +// } +// // reposition the endPC +// codeStream.updateLastRecordedEndPC(codeStream.position); +// } else { +// // x || +// if ((bits & OnlyValueRequiredMASK) != 0) { +// left.generateCode(currentScope, codeStream, valueRequired); +// } else { +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// } +// if (rightInitStateIndex != -1) { +// codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex); +// } +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// false); +// } +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// return; +// } +// // default case +// if (falseLabel == null) { +// if (trueLabel != null) { +// // implicit falling through the FALSE case +// left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null, true); +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// null, +// valueRequired); +// } +// } else { +// // implicit falling through the TRUE case +// if (trueLabel == null) { +// Label internalTrueLabel = new Label(codeStream); +// left.generateOptimizedBoolean( +// currentScope, +// codeStream, +// internalTrueLabel, +// null, +// true); +// if (rightInitStateIndex != -1) { +// codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex); +// } +// right.generateOptimizedBoolean( +// currentScope, +// codeStream, +// null, +// falseLabel, +// valueRequired); +// internalTrueLabel.place(); +// } else { +// // no implicit fall through TRUE/FALSE --> should never occur +// } +// } +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// } + + public boolean isCompactableOperation() { + return false; + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + if (visitor.visit(this, scope)) { + left.traverse(visitor, scope); + right.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/OperatorExpression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/OperatorExpression.java new file mode 100644 index 0000000..0c17dc7 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/OperatorExpression.java @@ -0,0 +1,1564 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +public abstract class OperatorExpression extends Expression implements OperatorIds { + + public static int[][] ResolveTypeTables = new int[NumberOfTables][]; + + static {classInitialize();} + + /** + * OperatorExpression constructor comment. + */ + public OperatorExpression() { + super(); + } + public static final void classInitialize() { + ResolveTypeTables[AND] = get_AND(); + ResolveTypeTables[AND_AND] = get_AND_AND(); + ResolveTypeTables[DIVIDE] = get_DIVIDE(); + ResolveTypeTables[EQUAL_EQUAL] = get_EQUAL_EQUAL(); + ResolveTypeTables[GREATER] = get_GREATER(); + ResolveTypeTables[GREATER_EQUAL] = get_GREATER_EQUAL(); + ResolveTypeTables[LEFT_SHIFT] = get_LEFT_SHIFT(); + ResolveTypeTables[LESS] = get_LESS(); + ResolveTypeTables[LESS_EQUAL] = get_LESS_EQUAL(); + ResolveTypeTables[MINUS] = get_MINUS(); + ResolveTypeTables[MULTIPLY] = get_MULTIPLY(); + ResolveTypeTables[OR] = get_OR(); + ResolveTypeTables[OR_OR] = get_OR_OR(); + ResolveTypeTables[PLUS] = get_PLUS(); + ResolveTypeTables[REMAINDER] = get_REMAINDER(); + ResolveTypeTables[RIGHT_SHIFT] = get_RIGHT_SHIFT(); + ResolveTypeTables[UNSIGNED_RIGHT_SHIFT] = get_UNSIGNED_RIGHT_SHIFT(); + ResolveTypeTables[XOR] = get_XOR(); + } + + public static final String generateTableTestCase(){ + //return a String which is a java method allowing to test + //the non zero entries of all tables + + /* + org.eclipse.jdt.internal.compiler.ast. + OperatorExpression.generateTableTestCase(); + */ + + int[] operators = new int[]{AND,AND_AND,DIVIDE,GREATER,GREATER_EQUAL, + LEFT_SHIFT,LESS,LESS_EQUAL,MINUS,MULTIPLY,OR,OR_OR,PLUS,REMAINDER, + RIGHT_SHIFT,UNSIGNED_RIGHT_SHIFT,XOR}; + + class Decode { + public final String constant(int code){ + switch(code){ + case T_boolean : return "true" ; //$NON-NLS-1$ + case T_byte : return "((byte) 3)" ; //$NON-NLS-1$ + case T_char : return "'A'" ; //$NON-NLS-1$ + case T_double : return "300.0d" ; //$NON-NLS-1$ + case T_float : return "100.0f" ; //$NON-NLS-1$ + case T_int : return "1" ; //$NON-NLS-1$ + case T_long : return "7L" ; //$NON-NLS-1$ + case T_String : return "\"hello-world\"" ; //$NON-NLS-1$ + case T_null : return "null"; //$NON-NLS-1$ + case T_short : return "((short) 5)"; //$NON-NLS-1$ + case T_Object : return "null";} //$NON-NLS-1$ + return "";} //$NON-NLS-1$ + + public final String type(int code){ + switch(code){ + case T_boolean : return "z" ; //$NON-NLS-1$ + case T_byte : return "b" ; //$NON-NLS-1$ + case T_char : return "c" ; //$NON-NLS-1$ + case T_double : return "d" ; //$NON-NLS-1$ + case T_float : return "f" ; //$NON-NLS-1$ + case T_int : return "i" ; //$NON-NLS-1$ + case T_long : return "l" ; //$NON-NLS-1$ + case T_String : return "str" ; //$NON-NLS-1$ + case T_null : return "null"; //$NON-NLS-1$ + case T_short : return "s"; //$NON-NLS-1$ + case T_Object : return "obj";} //$NON-NLS-1$ + return "xxx";} //$NON-NLS-1$ + + public final String operator(int operator){ + switch (operator) { + case EQUAL_EQUAL : return "=="; //$NON-NLS-1$ + case LESS_EQUAL : return "<="; //$NON-NLS-1$ + case GREATER_EQUAL :return ">="; //$NON-NLS-1$ + case LEFT_SHIFT : return "<<"; //$NON-NLS-1$ + case RIGHT_SHIFT : return ">>"; //$NON-NLS-1$ + case UNSIGNED_RIGHT_SHIFT : return ">>>"; //$NON-NLS-1$ + case OR_OR :return "||"; //$NON-NLS-1$ + case AND_AND : return "&&"; //$NON-NLS-1$ + case PLUS : return "+"; //$NON-NLS-1$ + case MINUS : return "-"; //$NON-NLS-1$ + case NOT : return "!"; //$NON-NLS-1$ + case REMAINDER : return "%"; //$NON-NLS-1$ + case XOR : return "^"; //$NON-NLS-1$ + case AND : return "&"; //$NON-NLS-1$ + case MULTIPLY : return "*"; //$NON-NLS-1$ + case OR : return "|"; //$NON-NLS-1$ + case TWIDDLE : return "~"; //$NON-NLS-1$ + case DIVIDE : return "/"; //$NON-NLS-1$ + case GREATER : return ">"; //$NON-NLS-1$ + case LESS : return "<"; }; //$NON-NLS-1$ + return "????";} //$NON-NLS-1$ + } + + + Decode decode = new Decode(); + String s ; + + s = "\tpublic static void binaryOperationTablesTestCase(){\n" + //$NON-NLS-1$ + + "\t\t//TC test : all binary operation (described in tables)\n"+ //$NON-NLS-1$ + "\t\t//method automatically generated by\n"+ //$NON-NLS-1$ + "\t\t//org.eclipse.jdt.internal.compiler.ast.OperatorExpression.generateTableTestCase();\n"+ //$NON-NLS-1$ + + "\t\tString str0 ;\t String str\t= "+decode.constant(T_String)+";\n"+ //$NON-NLS-1$ //$NON-NLS-2$ + "\t\tint i0 ;\t int i\t= "+decode.constant(T_int)+" ;\n"+ //$NON-NLS-1$ //$NON-NLS-2$ + "\t\tboolean z0;\t boolean z\t= "+decode.constant(T_boolean)+";\n"+ //$NON-NLS-1$ //$NON-NLS-2$ + "\t\tchar c0; \t char c\t= "+decode.constant(T_char)+" ;\n"+ //$NON-NLS-1$ //$NON-NLS-2$ + "\t\tfloat f0; \t float f\t= "+decode.constant(T_float)+" ;\n"+ //$NON-NLS-1$ //$NON-NLS-2$ + "\t\tdouble d0;\t double d\t= "+decode.constant(T_double)+" ;\n"+ //$NON-NLS-1$ //$NON-NLS-2$ + "\t\tbyte b0; \t byte b\t= "+decode.constant(T_byte)+";\n"+ //$NON-NLS-1$ //$NON-NLS-2$ + "\t\tshort s0; \t short s\t= "+decode.constant(T_short)+";\n"+ //$NON-NLS-1$ //$NON-NLS-2$ + "\t\tlong l0; \t long l\t= "+decode.constant(T_long)+" ;\n"+ //$NON-NLS-1$ //$NON-NLS-2$ + "\t\tObject obj0; \t Object obj\t= "+decode.constant(T_Object)+" ;\n"+ //$NON-NLS-1$ //$NON-NLS-2$ + "\n"; //$NON-NLS-1$ + + int error = 0; + for (int i=0; i < operators.length ; i++) + { int operator = operators[i]; + for (int left=0; left<16;left++) + for (int right=0; right<16;right++) + { int result = (ResolveTypeTables[operator][(left<<4)+right]) & 0x0000F; + if (result != T_undefined) + + //1/ First regular computation then 2/ comparaison + //with a compile time constant (generated by the compiler) + // z0 = s >= s; + // if ( z0 != (((short) 5) >= ((short) 5))) + // System.out.println(155); + + { s += "\t\t"+decode.type(result)+"0"+" = "+decode.type(left); //$NON-NLS-1$ //$NON-NLS-3$ //$NON-NLS-2$ + s += " "+decode.operator(operator)+" "+decode.type(right)+";\n"; //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-3$ + String begin = result == T_String ? "\t\tif (! " : "\t\tif ( "; //$NON-NLS-2$ //$NON-NLS-1$ + String test = result == T_String ? ".equals(" : " != (" ; //$NON-NLS-2$ //$NON-NLS-1$ + s += begin +decode.type(result)+"0"+test //$NON-NLS-1$ + +decode.constant(left)+" " //$NON-NLS-1$ + +decode.operator(operator)+" " //$NON-NLS-1$ + +decode.constant(right)+"))\n"; //$NON-NLS-1$ + s += "\t\t\tSystem.out.println("+ (++error) +");\n"; //$NON-NLS-1$ //$NON-NLS-2$ + + } + } + } + + return s += "\n\t\tSystem.out.println(\"binary tables test : done\");}" ; //$NON-NLS-1$ + } + + public static final int[] get_AND(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + int[] table = new int[16*16] ; + + // table[(T_undefined<<4)+T_undefined] = T_undefined ; + // table[(T_undefined<<4)+T_byte] = T_undefined ; + // table[(T_undefined<<4)+T_long] = T_undefined ; + // table[(T_undefined<<4)+T_short] = T_undefined ; + // table[(T_undefined<<4)+T_void] = T_undefined ; + // table[(T_undefined<<4)+T_String] = T_undefined ; + // table[(T_undefined<<4)+T_Object] = T_undefined ; + // table[(T_undefined<<4)+T_double] = T_undefined ; + // table[(T_undefined<<4)+T_float] = T_undefined ; + // table[(T_undefined<<4)+T_boolean] = T_undefined ; + // table[(T_undefined<<4)+T_char] = T_undefined ; + // table[(T_undefined<<4)+T_int] = T_undefined ; + // table[(T_undefined<<4)+T_null] = T_undefined ; + + // table[(T_byte<<4)+T_undefined] = T_undefined ; + table[(T_byte<<4)+T_byte] = (Byte2Int<<12) +(Byte2Int<<4) +T_int ; + table[(T_byte<<4)+T_long] = (Byte2Long<<12)+(Long2Long<<4)+T_long ; + table[(T_byte<<4)+T_short] = (Byte2Int<<12) +(Short2Int<<4)+T_int; + // table[(T_byte<<4)+T_void] = T_undefined ; + // table[(T_byte<<4)+T_String] = T_undefined ; + // table[(T_byte<<4)+T_Object] = T_undefined ; + // table[(T_byte<<4)+T_double] = T_undefined ; + // table[(T_byte<<4)+T_float] = T_undefined ; + // table[(T_byte<<4)+T_boolean] = T_undefined ; + table[(T_byte<<4)+T_char] = (Byte2Int<<12) +(Char2Int<<4) +T_int ; + table[(T_byte<<4)+T_int] = (Byte2Int<<12) +(Int2Int<<4) +T_int ; + // table[(T_byte<<4)+T_null] = T_undefined ; + + // table[(T_long<<4)+T_undefined] = T_undefined ; + table[(T_long<<4)+T_byte] = (Long2Long<<12)+(Byte2Long<<4)+T_long; + table[(T_long<<4)+T_long] = (Long2Long<<12)+(Long2Long<<4)+T_long ; + table[(T_long<<4)+T_short] = (Long2Long<<12)+(Short2Long<<4)+T_long; ; + // table[(T_long<<4)+T_void] = T_undefined ; + // table[(T_long<<4)+T_String] = T_undefined ; + // table[(T_long<<4)+T_Object] = T_undefined ; + // table[(T_long<<4)+T_double] = T_undefined ; + // table[(T_long<<4)+T_float] = T_undefined ; + // table[(T_long<<4)+T_boolean] = T_undefined ; + table[(T_long<<4)+T_char] = (Long2Long<<12)+(Char2Long<<4)+T_long ; + table[(T_long<<4)+T_int] = (Long2Long<<12)+(Int2Long<<4)+T_long ; + // table[(T_long<<4)+T_null] = T_undefined ; + + // table[(T_short<<4)+T_undefined] = T_undefined ; + table[(T_short<<4)+T_byte] = (Short2Int<<12)+(Byte2Int<<4)+T_int ; + table[(T_short<<4)+T_long] = (Short2Long<<12)+(Long2Long<<4)+T_long ; + table[(T_short<<4)+T_short] = (Short2Int<<12)+(Short2Int<<4)+T_int ; + // table[(T_short<<4)+T_void] = T_undefined ; + // table[(T_short<<4)+T_String] = T_undefined ; + // table[(T_short<<4)+T_Object] = T_undefined ; + // table[(T_short<<4)+T_double] = T_undefined ; + // table[(T_short<<4)+T_float] = T_undefined ; + // table[(T_short<<4)+T_boolean] = T_undefined ; + table[(T_short<<4)+T_char] = (Short2Int<<12)+(Char2Int<<4)+T_int ; + table[(T_short<<4)+T_int] = (Short2Int<<12)+(Int2Int<<4)+T_int ; + // table[(T_short<<4)+T_null] = T_undefined ; + + // table[(T_void<<4)+T_undefined] = T_undefined ; + // table[(T_void<<4)+T_byte] = T_undefined ; + // table[(T_void<<4)+T_long] = T_undefined ; + // table[(T_void<<4)+T_short] = T_undefined ; + // table[(T_void<<4)+T_void] = T_undefined ; + // table[(T_void<<4)+T_String] = T_undefined ; + // table[(T_void<<4)+T_Object] = T_undefined ; + // table[(T_void<<4)+T_double] = T_undefined ; + // table[(T_void<<4)+T_float] = T_undefined ; + // table[(T_void<<4)+T_boolean] = T_undefined ; + // table[(T_void<<4)+T_char] = T_undefined ; + // table[(T_void<<4)+T_int] = T_undefined ; + // table[(T_void<<4)+T_null] = T_undefined ; + + // table[(T_String<<4)+T_undefined] = T_undefined ; + // table[(T_String<<4)+T_byte] = T_undefined ; + // table[(T_String<<4)+T_long] = T_undefined ; + // table[(T_String<<4)+T_short] = T_undefined ; + // table[(T_String<<4)+T_void] = T_undefined ; + // table[(T_String<<4)+T_String] = T_undefined ; + // table[(T_String<<4)+T_Object] = T_undefined ; + // table[(T_String<<4)+T_double] = T_undefined ; + // table[(T_String<<4)+T_float] = T_undefined ; + // table[(T_String<<4)+T_boolean] = T_undefined ; + // table[(T_String<<4)+T_char] = T_undefined ; + // table[(T_String<<4)+T_int] = T_undefined ; + // table[(T_String<<4)+T_null] = T_undefined ; + + // table[(T_Object<<4)+T_undefined] = T_undefined ; + // table[(T_Object<<4)+T_byte] = T_undefined ; + // table[(T_Object<<4)+T_long] = T_undefined ; + // table[(T_Object<<4)+T_short] = T_undefined ; + // table[(T_Object<<4)+T_void] = T_undefined ; + // table[(T_Object<<4)+T_String] = T_undefined ; + // table[(T_Object<<4)+T_Object] = T_undefined ; + // table[(T_Object<<4)+T_double] = T_undefined ; + // table[(T_Object<<4)+T_float] = T_undefined ; + // table[(T_Object<<4)+T_boolean] = T_undefined ; + // table[(T_Object<<4)+T_char] = T_undefined ; + // table[(T_Object<<4)+T_int] = T_undefined ; + // table[(T_Object<<4)+T_null] = T_undefined ; + + // table[(T_double<<4)+T_undefined] = T_undefined ; + // table[(T_double<<4)+T_byte] = T_undefined ; + // table[(T_double<<4)+T_long] = T_undefined ; + // table[(T_double<<4)+T_short] = T_undefined ; + // table[(T_double<<4)+T_void] = T_undefined ; + // table[(T_double<<4)+T_String] = T_undefined ; + // table[(T_double<<4)+T_Object] = T_undefined ; + // table[(T_double<<4)+T_double] = T_undefined ; + // table[(T_double<<4)+T_float] = T_undefined ; + // table[(T_double<<4)+T_boolean] = T_undefined ; + // table[(T_double<<4)+T_char] = T_undefined ; + // table[(T_double<<4)+T_int] = T_undefined; + // table[(T_double<<4)+T_null] = T_undefined ; + + // table[(T_float<<4)+T_undefined] = T_undefined ; + // table[(T_float<<4)+T_byte] = T_undefined ; + // table[(T_float<<4)+T_long] = T_undefined ; + // table[(T_float<<4)+T_short] = T_undefined ; + // table[(T_float<<4)+T_void] = T_undefined ; + // table[(T_float<<4)+T_String] = T_undefined ; + // table[(T_float<<4)+T_Object] = T_undefined ; + // table[(T_float<<4)+T_double] = T_undefined ; + // table[(T_float<<4)+T_float] = T_undefined ; + // table[(T_float<<4)+T_boolean] = T_undefined ; + // table[(T_float<<4)+T_char] = T_undefined ; + // table[(T_float<<4)+T_int] = T_undefined ; + // table[(T_float<<4)+T_null] = T_undefined ; + + // table[(T_boolean<<4)+T_undefined] = T_undefined ; + // table[(T_boolean<<4)+T_byte] = T_undefined ; + // table[(T_boolean<<4)+T_long] = T_undefined ; + // table[(T_boolean<<4)+T_short] = T_undefined ; + // table[(T_boolean<<4)+T_void] = T_undefined ; + // table[(T_boolean<<4)+T_String] = T_undefined ; + // table[(T_boolean<<4)+T_Object] = T_undefined ; + // table[(T_boolean<<4)+T_double] = T_undefined ; + // table[(T_boolean<<4)+T_float] = T_undefined ; + table[(T_boolean<<4)+T_boolean] = (Boolean2Boolean << 12)+(Boolean2Boolean << 4)+T_boolean ; + // table[(T_boolean<<4)+T_char] = T_undefined ; + // table[(T_boolean<<4)+T_int] = T_undefined ; + // table[(T_boolean<<4)+T_null] = T_undefined ; + + // table[(T_char<<4)+T_undefined] = T_undefined ; + table[(T_char<<4)+T_byte] = (Char2Int<<12)+(Byte2Int<<4)+T_int ; + table[(T_char<<4)+T_long] = (Char2Long<<12)+(Long2Long<<4)+T_long; + table[(T_char<<4)+T_short] = (Char2Int<<12)+(Short2Int<<4)+T_int ; + // table[(T_char<<4)+T_void] = T_undefined ; + // table[(T_char<<4)+T_String] = T_undefined ; + // table[(T_char<<4)+T_Object] = T_undefined ; + // table[(T_char<<4)+T_double] = T_undefined ; + // table[(T_char<<4)+T_float] = T_undefined ; + // table[(T_char<<4)+T_boolean] = T_undefined ; + table[(T_char<<4)+T_char] = (Char2Int<<12)+(Char2Int<<4)+T_int ; + table[(T_char<<4)+T_int] = (Char2Int<<12)+(Int2Int<<4)+T_int ; + // table[(T_char<<4)+T_null] = T_undefined ; + + // table[(T_int<<4)+T_undefined] = T_undefined ; + table[(T_int<<4)+T_byte] = (Int2Int<<12)+(Byte2Int<<4)+T_int ; + table[(T_int<<4)+T_long] = (Int2Long<<12)+(Long2Long<<4)+T_long ; + table[(T_int<<4)+T_short] = (Int2Int<<12)+(Short2Int<<4)+T_int ; + // table[(T_int<<4)+T_void] = T_undefined ; + // table[(T_int<<4)+T_String] = T_undefined ; + // table[(T_int<<4)+T_Object] = T_undefined ; + // table[(T_int<<4)+T_double] = T_undefined ; + // table[(T_int<<4)+T_float] = T_undefined ; + // table[(T_int<<4)+T_boolean] = T_undefined ; + table[(T_int<<4)+T_char] = (Int2Int<<12)+(Char2Int<<4)+T_int ; + table[(T_int<<4)+T_int] = (Int2Int<<12)+(Int2Int<<4)+T_int ; + // table[(T_int<<4)+T_null] = T_undefined ; + + // table[(T_null<<4)+T_undefined] = T_undefined ; + // table[(T_null<<4)+T_byte] = T_undefined ; + // table[(T_null<<4)+T_long] = T_undefined ; + // table[(T_null<<4)+T_short] = T_undefined ; + // table[(T_null<<4)+T_void] = T_undefined ; + // table[(T_null<<4)+T_String] = T_undefined ; + // table[(T_null<<4)+T_Object] = T_undefined ; + // table[(T_null<<4)+T_double] = T_undefined ; + // table[(T_null<<4)+T_float] = T_undefined ; + // table[(T_null<<4)+T_boolean] = T_undefined ; + // table[(T_null<<4)+T_char] = T_undefined ; + // table[(T_null<<4)+T_int] = T_undefined ; + // table[(T_null<<4)+T_null] = T_undefined ; + + return table ; + } + + public static final int[] get_AND_AND(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + int[] table = new int[16*16] ; + + // table[(T_undefined<<4)+T_undefined] = T_undefined ; + // table[(T_undefined<<4)+T_byte] = T_undefined ; + // table[(T_undefined<<4)+T_long] = T_undefined ; + // table[(T_undefined<<4)+T_short] = T_undefined ; + // table[(T_undefined<<4)+T_void] = T_undefined ; + // table[(T_undefined<<4)+T_String] = T_undefined ; + // table[(T_undefined<<4)+T_Object] = T_undefined ; + // table[(T_undefined<<4)+T_double] = T_undefined ; + // table[(T_undefined<<4)+T_float] = T_undefined ; + // table[(T_undefined<<4)+T_boolean] = T_undefined ; + // table[(T_undefined<<4)+T_char] = T_undefined ; + // table[(T_undefined<<4)+T_int] = T_undefined ; + // table[(T_undefined<<4)+T_null] = T_undefined ; + + // table[(T_byte<<4)+T_undefined] = T_undefined ; + // table[(T_byte<<4)+T_byte] = T_undefined ; + // table[(T_byte<<4)+T_long] = T_undefined ; + // table[(T_byte<<4)+T_short] = T_undefined ; + // table[(T_byte<<4)+T_void] = T_undefined ; + // table[(T_byte<<4)+T_String] = T_undefined ; + // table[(T_byte<<4)+T_Object] = T_undefined ; + // table[(T_byte<<4)+T_double] = T_undefined ; + // table[(T_byte<<4)+T_float] = T_undefined ; + // table[(T_byte<<4)+T_boolean] = T_undefined ; + // table[(T_byte<<4)+T_char] = T_undefined ; + // table[(T_byte<<4)+T_int] = T_undefined ; + // table[(T_byte<<4)+T_null] = T_undefined ; + + // table[(T_long<<4)+T_undefined] = T_undefined ; + // table[(T_long<<4)+T_byte] = T_undefined; + // table[(T_long<<4)+T_long] = T_undefined ; + // table[(T_long<<4)+T_short] = T_undefined ; + // table[(T_long<<4)+T_void] = T_undefined ; + // table[(T_long<<4)+T_String] = T_undefined ; + // table[(T_long<<4)+T_Object] = T_undefined ; + // table[(T_long<<4)+T_double] = T_undefined ; + // table[(T_long<<4)+T_float] = T_undefined ; + // table[(T_long<<4)+T_boolean] = T_undefined ; + // table[(T_long<<4)+T_char] = T_undefined ; + // table[(T_long<<4)+T_int] = T_undefined ; + // table[(T_long<<4)+T_null] = T_undefined ; + + // table[(T_short<<4)+T_undefined] = T_undefined ; + // table[(T_short<<4)+T_byte] = T_undefined ; + // table[(T_short<<4)+T_long] = T_undefined ; + // table[(T_short<<4)+T_short] = T_undefined ; + // table[(T_short<<4)+T_void] = T_undefined ; + // table[(T_short<<4)+T_String] = T_undefined ; + // table[(T_short<<4)+T_Object] = T_undefined ; + // table[(T_short<<4)+T_double] = T_undefined ; + // table[(T_short<<4)+T_float] = T_undefined ; + // table[(T_short<<4)+T_boolean] = T_undefined ; + // table[(T_short<<4)+T_char] = T_undefined ; + // table[(T_short<<4)+T_int] = T_undefined ; + // table[(T_short<<4)+T_null] = T_undefined ; + + // table[(T_void<<4)+T_undefined] = T_undefined ; + // table[(T_void<<4)+T_byte] = T_undefined ; + // table[(T_void<<4)+T_long] = T_undefined ; + // table[(T_void<<4)+T_short] = T_undefined ; + // table[(T_void<<4)+T_void] = T_undefined ; + // table[(T_void<<4)+T_String] = T_undefined ; + // table[(T_void<<4)+T_Object] = T_undefined ; + // table[(T_void<<4)+T_double] = T_undefined ; + // table[(T_void<<4)+T_float] = T_undefined ; + // table[(T_void<<4)+T_boolean] = T_undefined ; + // table[(T_void<<4)+T_char] = T_undefined ; + // table[(T_void<<4)+T_int] = T_undefined ; + // table[(T_void<<4)+T_null] = T_undefined ; + + // table[(T_String<<4)+T_undefined] = T_undefined ; + // table[(T_String<<4)+T_byte] = T_undefined ; + // table[(T_String<<4)+T_long] = T_undefined ; + // table[(T_String<<4)+T_short] = T_undefined ; + // table[(T_String<<4)+T_void] = T_undefined ; + // table[(T_String<<4)+T_String] = T_undefined ; + // table[(T_String<<4)+T_Object] = T_undefined ; + // table[(T_String<<4)+T_double] = T_undefined ; + // table[(T_String<<4)+T_float] = T_undefined ; + // table[(T_String<<4)+T_boolean] = T_undefined ; + // table[(T_String<<4)+T_char] = T_undefined ; + // table[(T_String<<4)+T_int] = T_undefined ; + // table[(T_String<<4)+T_null] = T_undefined ; + + // table[(T_Object<<4)+T_undefined] = T_undefined ; + // table[(T_Object<<4)+T_byte] = T_undefined ; + // table[(T_Object<<4)+T_long] = T_undefined ; + // table[(T_Object<<4)+T_short] = T_undefined ; + // table[(T_Object<<4)+T_void] = T_undefined ; + // table[(T_Object<<4)+T_String] = T_undefined ; + // table[(T_Object<<4)+T_Object] = T_undefined ; + // table[(T_Object<<4)+T_double] = T_undefined ; + // table[(T_Object<<4)+T_float] = T_undefined ; + // table[(T_Object<<4)+T_boolean] = T_undefined ; + // table[(T_Object<<4)+T_char] = T_undefined ; + // table[(T_Object<<4)+T_int] = T_undefined ; + // table[(T_Object<<4)+T_null] = T_undefined ; + + // table[(T_double<<4)+T_undefined] = T_undefined ; + // table[(T_double<<4)+T_byte] = T_undefined ; + // table[(T_double<<4)+T_long] = T_undefined ; + // table[(T_double<<4)+T_short] = T_undefined ; + // table[(T_double<<4)+T_void] = T_undefined ; + // table[(T_double<<4)+T_String] = T_undefined ; + // table[(T_double<<4)+T_Object] = T_undefined ; + // table[(T_double<<4)+T_double] = T_undefined ; + // table[(T_double<<4)+T_float] = T_undefined ; + // table[(T_double<<4)+T_boolean] = T_undefined ; + // table[(T_double<<4)+T_char] = T_undefined ; + // table[(T_double<<4)+T_int] = T_undefined; + // table[(T_double<<4)+T_null] = T_undefined ; + + // table[(T_float<<4)+T_undefined] = T_undefined ; + // table[(T_float<<4)+T_byte] = T_undefined ; + // table[(T_float<<4)+T_long] = T_undefined ; + // table[(T_float<<4)+T_short] = T_undefined ; + // table[(T_float<<4)+T_void] = T_undefined ; + // table[(T_float<<4)+T_String] = T_undefined ; + // table[(T_float<<4)+T_Object] = T_undefined ; + // table[(T_float<<4)+T_double] = T_undefined ; + // table[(T_float<<4)+T_float] = T_undefined ; + // table[(T_float<<4)+T_boolean] = T_undefined ; + // table[(T_float<<4)+T_char] = T_undefined ; + // table[(T_float<<4)+T_int] = T_undefined ; + // table[(T_float<<4)+T_null] = T_undefined ; + + // table[(T_boolean<<4)+T_undefined] = T_undefined ; + // table[(T_boolean<<4)+T_byte] = T_undefined ; + // table[(T_boolean<<4)+T_long] = T_undefined ; + // table[(T_boolean<<4)+T_short] = T_undefined ; + // table[(T_boolean<<4)+T_void] = T_undefined ; + // table[(T_boolean<<4)+T_String] = T_undefined ; + // table[(T_boolean<<4)+T_Object] = T_undefined ; + // table[(T_boolean<<4)+T_double] = T_undefined ; + // table[(T_boolean<<4)+T_float] = T_undefined ; + table[(T_boolean<<4)+T_boolean] = (Boolean2Boolean<<12)+(Boolean2Boolean<<4)+T_boolean ; + // table[(T_boolean<<4)+T_char] = T_undefined ; + // table[(T_boolean<<4)+T_int] = T_undefined ; + // table[(T_boolean<<4)+T_null] = T_undefined ; + + // table[(T_char<<4)+T_undefined] = T_undefined ; + // table[(T_char<<4)+T_byte] = T_undefined ; + // table[(T_char<<4)+T_long] = T_undefined; + // table[(T_char<<4)+T_short] = T_undefined ; + // table[(T_char<<4)+T_void] = T_undefined ; + // table[(T_char<<4)+T_String] = T_undefined ; + // table[(T_char<<4)+T_Object] = T_undefined ; + // table[(T_char<<4)+T_double] = T_undefined ; + // table[(T_char<<4)+T_float] = T_undefined ; + // table[(T_char<<4)+T_boolean] = T_undefined ; + // table[(T_char<<4)+T_char] = T_undefined ; + // table[(T_char<<4)+T_int] = T_undefined ; + // table[(T_char<<4)+T_null] = T_undefined ; + + // table[(T_int<<4)+T_undefined] = T_undefined ; + // table[(T_int<<4)+T_byte] = T_undefined ; + // table[(T_int<<4)+T_long] = T_undefined ; + // table[(T_int<<4)+T_short] = T_undefined ; + // table[(T_int<<4)+T_void] = T_undefined ; + // table[(T_int<<4)+T_String] = T_undefined ; + // table[(T_int<<4)+T_Object] = T_undefined ; + // table[(T_int<<4)+T_double] = T_undefined ; + // table[(T_int<<4)+T_float] = T_undefined ; + // table[(T_int<<4)+T_boolean] = T_undefined ; + // table[(T_int<<4)+T_char] = T_undefined ; + // table[(T_int<<4)+T_int] = T_undefined ; + // table[(T_int<<4)+T_null] = T_undefined ; + + // table[(T_null<<4)+T_undefined] = T_undefined ; + // table[(T_null<<4)+T_byte] = T_undefined ; + // table[(T_null<<4)+T_long] = T_undefined ; + // table[(T_null<<4)+T_short] = T_undefined ; + // table[(T_null<<4)+T_void] = T_undefined ; + // table[(T_null<<4)+T_String] = T_undefined ; + // table[(T_null<<4)+T_Object] = T_undefined ; + // table[(T_null<<4)+T_double] = T_undefined ; + // table[(T_null<<4)+T_float] = T_undefined ; + // table[(T_null<<4)+T_boolean] = T_undefined ; + // table[(T_null<<4)+T_char] = T_undefined ; + // table[(T_null<<4)+T_int] = T_undefined ; + // table[(T_null<<4)+T_null] = T_undefined ; + return table ; + } + + public static final int[] get_DIVIDE(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + + // int[] table = new int[16*16] ; + + return get_MINUS(); + } + + public static final int[] get_EQUAL_EQUAL(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + int[] table = new int[16*16] ; + + // table[(T_undefined<<4)+T_undefined] = T_undefined ; + // table[(T_undefined<<4)+T_byte] = T_undefined ; + // table[(T_undefined<<4)+T_long] = T_undefined ; + // table[(T_undefined<<4)+T_short] = T_undefined ; + // table[(T_undefined<<4)+T_void] = T_undefined ; + // table[(T_undefined<<4)+T_String] = T_undefined ; + // table[(T_undefined<<4)+T_Object] = T_undefined ; + // table[(T_undefined<<4)+T_double] = T_undefined ; + // table[(T_undefined<<4)+T_float] = T_undefined ; + // table[(T_undefined<<4)+T_boolean] = T_undefined ; + // table[(T_undefined<<4)+T_char] = T_undefined ; + // table[(T_undefined<<4)+T_int] = T_undefined ; + // table[(T_undefined<<4)+T_null] = T_undefined ; + + // table[(T_byte<<4)+T_undefined] = T_undefined ; + table[(T_byte<<4)+T_byte] = (Byte2Int<<12)+(Byte2Int<<4)+T_boolean ; + table[(T_byte<<4)+T_long] = (Byte2Long<<12)+(Long2Long<<4)+T_boolean ; + table[(T_byte<<4)+T_short] = (Byte2Int<<12)+(Short2Int<<4)+T_boolean ; + // table[(T_byte<<4)+T_void] = T_undefined ; + // table[(T_byte<<4)+T_String] = T_undefined ; + // table[(T_byte<<4)+T_Object] = T_undefined ; + table[(T_byte<<4)+T_double] = (Byte2Double<<12)+(Double2Double<<4)+T_boolean ; + table[(T_byte<<4)+T_float] = (Byte2Float<<12)+(Float2Float<<4)+T_boolean; + // table[(T_byte<<4)+T_boolean] = T_undefined ; + table[(T_byte<<4)+T_char] = (Byte2Int<<12)+(Char2Int<<4)+T_boolean ; + table[(T_byte<<4)+T_int] = (Byte2Int<<12)+(Int2Int<<4)+T_boolean; + // table[(T_byte<<4)+T_null] = T_undefined ; + + // table[(T_long<<4)+T_undefined] = T_undefined ; + table[(T_long<<4)+T_byte] = (Long2Long<<12)+(Byte2Long<<4)+T_boolean; + table[(T_long<<4)+T_long] = (Long2Long<<12)+(Long2Long<<4)+T_boolean ; + table[(T_long<<4)+T_short] = (Long2Long<<12)+(Short2Long<<4)+T_boolean ; + // table[(T_long<<4)+T_void] = T_undefined ; + // table[(T_long<<4)+T_String] = T_undefined ; + // table[(T_long<<4)+T_Object] = T_undefined ; + table[(T_long<<4)+T_double] = (Long2Double<<12)+(Double2Double<<4)+T_boolean ; + table[(T_long<<4)+T_float] = (Long2Float<<12)+(Float2Float<<4)+T_boolean ; + // table[(T_long<<4)+T_boolean] = T_undefined ; + table[(T_long<<4)+T_char] = (Long2Long<<12)+(Char2Long<<4)+T_boolean ; + table[(T_long<<4)+T_int] = (Long2Long<<12)+(Int2Long<<4)+T_boolean ; + // table[(T_long<<4)+T_null] = T_undefined ; + + // table[(T_short<<4)+T_undefined] = T_undefined ; + table[(T_short<<4)+T_byte] = (Short2Int<<12)+(Byte2Int<<4)+T_boolean ; + table[(T_short<<4)+T_long] = (Short2Long<<12)+(Long2Long<<4)+T_boolean ; + table[(T_short<<4)+T_short] = (Short2Int<<12)+(Short2Int<<4)+T_boolean ; + // table[(T_short<<4)+T_void] = T_undefined ; + // table[(T_short<<4)+T_String] = T_undefined ; + // table[(T_short<<4)+T_Object] = T_undefined ; + table[(T_short<<4)+T_double] = (Short2Double<<12)+(Double2Double<<4)+T_boolean ; + table[(T_short<<4)+T_float] = (Short2Float<<12)+(Float2Float<<4)+T_boolean ; + // table[(T_short<<4)+T_boolean] = T_undefined ; + table[(T_short<<4)+T_char] = (Short2Int<<12)+(Char2Int<<4)+T_boolean ; + table[(T_short<<4)+T_int] = (Short2Int<<12)+(Int2Int<<4)+T_boolean ; + // table[(T_short<<4)+T_null] = T_undefined ; + + // table[(T_void<<4)+T_undefined] = T_undefined ; + // table[(T_void<<4)+T_byte] = T_undefined ; + // table[(T_void<<4)+T_long] = T_undefined ; + // table[(T_void<<4)+T_short] = T_undefined ; + // table[(T_void<<4)+T_void] = T_undefined ; + // table[(T_void<<4)+T_String] = T_undefined ; + // table[(T_void<<4)+T_Object] = T_undefined ; + // table[(T_void<<4)+T_double] = T_undefined ; + // table[(T_void<<4)+T_float] = T_undefined ; + // table[(T_void<<4)+T_boolean] = T_undefined ; + // table[(T_void<<4)+T_char] = T_undefined ; + // table[(T_void<<4)+T_int] = T_undefined ; + // table[(T_void<<4)+T_null] = T_undefined ; + + // table[(T_String<<4)+T_undefined] = T_undefined ; + // table[(T_String<<4)+T_byte] = T_undefined ; + // table[(T_String<<4)+T_long] = T_undefined ; + // table[(T_String<<4)+T_short] = T_undefined ; + // table[(T_String<<4)+T_void] = T_undefined ; + table[(T_String<<4)+T_String] = /*String2Object String2Object*/ + (T_Object<<16)+(T_String<<12)+(T_Object<<8)+(T_String<<4)+T_boolean ; + table[(T_String<<4)+T_Object] = /*String2Object Object2Object*/ + (T_Object<<16)+(T_String<<12)+(T_Object<<8)+(T_Object<<4)+T_boolean ; + // table[(T_String<<4)+T_double] = T_undefined ; + // table[(T_String<<4)+T_float] = T_undefined ; + // table[(T_String<<4)+T_boolean] = T_undefined ; + // table[(T_String<<4)+T_char] = T_undefined ; + // table[(T_String<<4)+T_int] = T_undefined ; + table[(T_String<<4)+T_null] = /*Object2String null2Object */ + (T_Object<<16)+(T_String<<12)+(T_Object<<8)+(T_null<<4)+T_boolean ; + + // table[(T_Object<<4)+T_undefined] = T_undefined ; + // table[(T_Object<<4)+T_byte] = T_undefined ; + // table[(T_Object<<4)+T_long] = T_undefined ; + // table[(T_Object<<4)+T_short] = T_undefined ; + // table[(T_Object<<4)+T_void] = T_undefined ; + table[(T_Object<<4)+T_String] = /*Object2Object String2Object*/ + (T_Object<<16)+(T_Object<<12)+(T_Object<<8)+(T_String<<4)+T_boolean ; + table[(T_Object<<4)+T_Object] = /*Object2Object Object2Object*/ + (T_Object<<16)+(T_Object<<12)+(T_Object<<8)+(T_Object<<4)+T_boolean ; + // table[(T_Object<<4)+T_double] = T_undefined ; + // table[(T_Object<<4)+T_float] = T_undefined ; + // table[(T_Object<<4)+T_boolean] = T_undefined ; + // table[(T_Object<<4)+T_char] = T_undefined ; + // table[(T_Object<<4)+T_int] = T_undefined ; + table[(T_Object<<4)+T_null] = /*Object2Object null2Object*/ + (T_Object<<16)+(T_Object<<12)+(T_Object<<8)+(T_null<<4)+T_boolean ; + + // table[(T_double<<4)+T_undefined] = T_undefined ; + table[(T_double<<4)+T_byte] = (Double2Double<<12)+(Byte2Double<<4)+T_boolean ; + table[(T_double<<4)+T_long] = (Double2Double<<12)+(Long2Double<<4)+T_boolean ; + table[(T_double<<4)+T_short] = (Double2Double<<12)+(Short2Double<<4)+T_boolean ; + // table[(T_double<<4)+T_void] = T_undefined ; + // table[(T_double<<4)+T_String] = T_undefined ; + // table[(T_double<<4)+T_Object] = T_undefined ; + table[(T_double<<4)+T_double] = (Double2Double<<12)+(Double2Double<<4)+T_boolean ; + table[(T_double<<4)+T_float] = (Double2Double<<12)+(Float2Double<<4)+T_boolean; + // table[(T_double<<4)+T_boolean] = T_undefined ; + table[(T_double<<4)+T_char] = (Double2Double<<12)+(Char2Double<<4)+T_boolean ; + table[(T_double<<4)+T_int] = (Double2Double<<12)+(Int2Double<<4)+T_boolean ; + // table[(T_double<<4)+T_null] = T_undefined ; + + // table[(T_float<<4)+T_undefined] = T_undefined ; + table[(T_float<<4)+T_byte] = (Float2Float<<12)+(Byte2Float<<4)+T_boolean ; + table[(T_float<<4)+T_long] = (Float2Float<<12)+(Long2Float<<4)+T_boolean ; + table[(T_float<<4)+T_short] = (Float2Float<<12)+(Short2Float<<4)+T_boolean ; + // table[(T_float<<4)+T_void] = T_undefined ; + // table[(T_float<<4)+T_String] = T_undefined ; + // table[(T_float<<4)+T_Object] = T_undefined ; + table[(T_float<<4)+T_double] = (Float2Double<<12)+(Double2Double<<4)+T_boolean ; + table[(T_float<<4)+T_float] = (Float2Float<<12)+(Float2Float<<4)+T_boolean ; + // table[(T_float<<4)+T_boolean] = T_undefined ; + table[(T_float<<4)+T_char] = (Float2Float<<12)+(Char2Float<<4)+T_boolean ; + table[(T_float<<4)+T_int] = (Float2Float<<12)+(Int2Float<<4)+T_boolean ; + // table[(T_float<<4)+T_null] = T_undefined ; + + // table[(T_boolean<<4)+T_undefined] = T_undefined ; + // table[(T_boolean<<4)+T_byte] = T_undefined ; + // table[(T_boolean<<4)+T_long] = T_undefined ; + // table[(T_boolean<<4)+T_short] = T_undefined ; + // table[(T_boolean<<4)+T_void] = T_undefined ; + // table[(T_boolean<<4)+T_String] = T_undefined ; + // table[(T_boolean<<4)+T_Object] = T_undefined ; + // table[(T_boolean<<4)+T_double] = T_undefined ; + // table[(T_boolean<<4)+T_float] = T_undefined ; + table[(T_boolean<<4)+T_boolean] = (Boolean2Boolean<<12)+(Boolean2Boolean<<4)+T_boolean ; + // table[(T_boolean<<4)+T_char] = T_undefined ; + // table[(T_boolean<<4)+T_int] = T_undefined ; + // table[(T_boolean<<4)+T_null] = T_undefined ; + + // table[(T_char<<4)+T_undefined] = T_undefined ; + table[(T_char<<4)+T_byte] = (Char2Int<<12)+(Byte2Int<<4)+T_boolean ; + table[(T_char<<4)+T_long] = (Char2Long<<12)+(Long2Long<<4)+T_boolean ; + table[(T_char<<4)+T_short] = (Char2Int<<12)+(Short2Int<<4)+T_boolean ; + // table[(T_char<<4)+T_void] = T_undefined ; + // table[(T_char<<4)+T_String] = T_undefined ; + // table[(T_char<<4)+T_Object] = T_undefined ; + table[(T_char<<4)+T_double] = (Char2Double<<12)+(Double2Double<<4)+T_boolean ; + table[(T_char<<4)+T_float] = (Char2Float<<12)+(Float2Float<<4)+T_boolean ; + // table[(T_char<<4)+T_boolean] = T_undefined ; + table[(T_char<<4)+T_char] = (Char2Int<<12)+(Char2Int<<4)+T_boolean ; + table[(T_char<<4)+T_int] = (Char2Int<<12)+(Int2Int<<4)+T_boolean ; + // table[(T_char<<4)+T_null] = T_undefined ; + + // table[(T_int<<4)+T_undefined] = T_undefined ; + table[(T_int<<4)+T_byte] = (Int2Int<<12)+(Byte2Int<<4)+T_boolean ; + table[(T_int<<4)+T_long] = (Int2Long<<12)+(Long2Long<<4)+T_boolean ; + table[(T_int<<4)+T_short] = (Int2Int<<12)+(Short2Int<<4)+T_boolean ; + // table[(T_int<<4)+T_void] = T_undefined ; + // table[(T_int<<4)+T_String] = T_undefined ; + // table[(T_int<<4)+T_Object] = T_undefined ; + table[(T_int<<4)+T_double] = (Int2Double<<12)+(Double2Double<<4)+T_boolean ; + table[(T_int<<4)+T_float] = (Int2Float<<12)+(Float2Float<<4)+T_boolean; + // table[(T_int<<4)+T_boolean] = T_undefined ; + table[(T_int<<4)+T_char] = (Int2Int<<12)+(Char2Int<<4)+T_boolean ; + table[(T_int<<4)+T_int] = (Int2Int<<12)+(Int2Int<<4)+T_boolean ; + // table[(T_int<<4)+T_null] = T_undefined ; + + // table[(T_null<<4)+T_undefined] = T_undefined ; + // table[(T_null<<4)+T_byte] = T_undefined ; + // table[(T_null<<4)+T_long] = T_undefined ; + // table[(T_null<<4)+T_short] = T_undefined ; + // table[(T_null<<4)+T_void] = T_undefined ; + table[(T_null<<4)+T_String] = /*null2Object String2Object*/ + (T_Object<<16)+(T_null<<12)+(T_Object<<8)+(T_String<<4)+T_boolean ; + table[(T_null<<4)+T_Object] = /*null2Object Object2Object*/ + (T_Object<<16)+(T_null<<12)+(T_Object<<8)+(T_Object<<4)+T_boolean ; ; + // table[(T_null<<4)+T_double] = T_undefined ; + // table[(T_null<<4)+T_float] = T_undefined ; + // table[(T_null<<4)+T_boolean] = T_undefined ; + // table[(T_null<<4)+T_char] = T_undefined ; + // table[(T_null<<4)+T_int] = T_undefined ; + table[(T_null<<4)+T_null] = /*null2Object null2Object*/ + (T_Object<<16)+(T_null<<12)+(T_Object<<8)+(T_null<<4)+T_boolean ; + return table ; + } + + public static final int[] get_GREATER(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + // int[] table = new int[16*16] ; + return get_LESS(); + } + + public static final int[] get_GREATER_EQUAL(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + // int[] table = new int[16*16] ; + return get_LESS(); + } + + public static final int[] get_LEFT_SHIFT(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + int[] table = new int[16*16] ; + + // table[(T_undefined<<4)+T_undefined] = T_undefined ; + // table[(T_undefined<<4)+T_byte] = T_undefined ; + // table[(T_undefined<<4)+T_long] = T_undefined ; + // table[(T_undefined<<4)+T_short] = T_undefined ; + // table[(T_undefined<<4)+T_void] = T_undefined ; + // table[(T_undefined<<4)+T_String] = T_undefined ; + // table[(T_undefined<<4)+T_Object] = T_undefined ; + // table[(T_undefined<<4)+T_double] = T_undefined ; + // table[(T_undefined<<4)+T_float] = T_undefined ; + // table[(T_undefined<<4)+T_boolean] = T_undefined ; + // table[(T_undefined<<4)+T_char] = T_undefined ; + // table[(T_undefined<<4)+T_int] = T_undefined ; + // table[(T_undefined<<4)+T_null] = T_undefined ; + + // table[(T_byte<<4)+T_undefined] = T_undefined ; + table[(T_byte<<4)+T_byte] = (Byte2Int<<12)+(Byte2Int<<4)+T_int ; + table[(T_byte<<4)+T_long] = (Byte2Int<<12)+(Long2Int<<4)+T_int ; + table[(T_byte<<4)+T_short] = (Byte2Int<<12)+(Short2Int<<4)+T_int ; + // table[(T_byte<<4)+T_void] = T_undefined ; + // table[(T_byte<<4)+T_String] = T_undefined ; + // table[(T_byte<<4)+T_Object] = T_undefined ; + // table[(T_byte<<4)+T_double] = T_undefined ; + // table[(T_byte<<4)+T_float] = T_undefined ; + // table[(T_byte<<4)+T_boolean] = T_undefined ; + table[(T_byte<<4)+T_char] = (Byte2Int<<12)+(Char2Int<<4)+T_int ; + table[(T_byte<<4)+T_int] = (Byte2Int<<12)+(Int2Int<<4)+T_int ; + // table[(T_byte<<4)+T_null] = T_undefined ; + + // table[(T_long<<4)+T_undefined] = T_undefined ; + table[(T_long<<4)+T_byte] = (Long2Long<<12)+(Byte2Int<<4)+T_long; + table[(T_long<<4)+T_long] = (Long2Long<<12)+(Long2Int<<4)+T_long ; + table[(T_long<<4)+T_short] = (Long2Long<<12)+(Short2Int<<4)+T_long ; + // table[(T_long<<4)+T_void] = T_undefined ; + // table[(T_long<<4)+T_String] = T_undefined ; + // table[(T_long<<4)+T_Object] = T_undefined ; + // table[(T_long<<4)+T_double] = T_undefined ; + // table[(T_long<<4)+T_float] = T_undefined ; + // table[(T_long<<4)+T_boolean] = T_undefined ; + table[(T_long<<4)+T_char] = (Long2Long<<12)+(Char2Int<<4)+T_long ; + table[(T_long<<4)+T_int] = (Long2Long<<12)+(Int2Int<<4)+T_long ; + // table[(T_long<<4)+T_null] = T_undefined ; + + // table[(T_short<<4)+T_undefined] = T_undefined ; + table[(T_short<<4)+T_byte] = (Short2Int<<12)+(Byte2Int<<4)+T_int ; + table[(T_short<<4)+T_long] = (Short2Int<<12)+(Long2Int<<4)+T_int ; + table[(T_short<<4)+T_short] = (Short2Int<<12)+(Short2Int<<4)+T_int ; + // table[(T_short<<4)+T_void] = T_undefined ; + // table[(T_short<<4)+T_String] = T_undefined ; + // table[(T_short<<4)+T_Object] = T_undefined ; + // table[(T_short<<4)+T_double] = T_undefined ; + // table[(T_short<<4)+T_float] = T_undefined ; + // table[(T_short<<4)+T_boolean] = T_undefined ; + table[(T_short<<4)+T_char] = (Short2Int<<12)+(Char2Int<<4)+T_int ; + table[(T_short<<4)+T_int] = (Short2Int<<12)+(Int2Int<<4)+T_int ; + // table[(T_short<<4)+T_null] = T_undefined ; + + // table[(T_void<<4)+T_undefined] = T_undefined ; + // table[(T_void<<4)+T_byte] = T_undefined ; + // table[(T_void<<4)+T_long] = T_undefined ; + // table[(T_void<<4)+T_short] = T_undefined ; + // table[(T_void<<4)+T_void] = T_undefined ; + // table[(T_void<<4)+T_String] = T_undefined ; + // table[(T_void<<4)+T_Object] = T_undefined ; + // table[(T_void<<4)+T_double] = T_undefined ; + // table[(T_void<<4)+T_float] = T_undefined ; + // table[(T_void<<4)+T_boolean] = T_undefined ; + // table[(T_void<<4)+T_char] = T_undefined ; + // table[(T_void<<4)+T_int] = T_undefined ; + // table[(T_void<<4)+T_null] = T_undefined ; + + // table[(T_String<<4)+T_undefined] = T_undefined ; + // table[(T_String<<4)+T_byte] = T_undefined ; + // table[(T_String<<4)+T_long] = T_undefined ; + // table[(T_String<<4)+T_short] = T_undefined ; + // table[(T_String<<4)+T_void] = T_undefined ; + // table[(T_String<<4)+T_String] = T_undefined ; + // table[(T_String<<4)+T_Object] = T_undefined ; + // table[(T_String<<4)+T_double] = T_undefined ; + // table[(T_String<<4)+T_float] = T_undefined ; + // table[(T_String<<4)+T_boolean] = T_undefined ; + // table[(T_String<<4)+T_char] = T_undefined ; + // table[(T_String<<4)+T_int] = T_undefined ; + // table[(T_String<<4)+T_null] = T_undefined ; + + // table[(T_Object<<4)+T_undefined] = T_undefined ; + // table[(T_Object<<4)+T_byte] = T_undefined ; + // table[(T_Object<<4)+T_long] = T_undefined ; + // table[(T_Object<<4)+T_short] = T_undefined ; + // table[(T_Object<<4)+T_void] = T_undefined ; + // table[(T_Object<<4)+T_String] = T_undefined ; + // table[(T_Object<<4)+T_Object] = T_undefined ; + // table[(T_Object<<4)+T_double] = T_undefined ; + // table[(T_Object<<4)+T_float] = T_undefined ; + // table[(T_Object<<4)+T_boolean] = T_undefined ; + // table[(T_Object<<4)+T_char] = T_undefined ; + // table[(T_Object<<4)+T_int] = T_undefined ; + // table[(T_Object<<4)+T_null] = T_undefined ; + + // table[(T_double<<4)+T_undefined] = T_undefined ; + // table[(T_double<<4)+T_byte] = T_undefined ; + // table[(T_double<<4)+T_long] = T_undefined ; + // table[(T_double<<4)+T_short] = T_undefined ; + // table[(T_double<<4)+T_void] = T_undefined ; + // table[(T_double<<4)+T_String] = T_undefined ; + // table[(T_double<<4)+T_Object] = T_undefined ; + // table[(T_double<<4)+T_double] = T_undefined ; + // table[(T_double<<4)+T_float] = T_undefined ; + // table[(T_double<<4)+T_boolean] = T_undefined ; + // table[(T_double<<4)+T_char] = T_undefined ; + // table[(T_double<<4)+T_int] = T_undefined; + // table[(T_double<<4)+T_null] = T_undefined ; + + // table[(T_float<<4)+T_undefined] = T_undefined ; + // table[(T_float<<4)+T_byte] = T_undefined ; + // table[(T_float<<4)+T_long] = T_undefined ; + // table[(T_float<<4)+T_short] = T_undefined ; + // table[(T_float<<4)+T_void] = T_undefined ; + // table[(T_float<<4)+T_String] = T_undefined ; + // table[(T_float<<4)+T_Object] = T_undefined ; + // table[(T_float<<4)+T_double] = T_undefined ; + // table[(T_float<<4)+T_float] = T_undefined ; + // table[(T_float<<4)+T_boolean] = T_undefined ; + // table[(T_float<<4)+T_char] = T_undefined ; + // table[(T_float<<4)+T_int] = T_undefined ; + // table[(T_float<<4)+T_null] = T_undefined ; + + // table[(T_boolean<<4)+T_undefined] = T_undefined ; + // table[(T_boolean<<4)+T_byte] = T_undefined ; + // table[(T_boolean<<4)+T_long] = T_undefined ; + // table[(T_boolean<<4)+T_short] = T_undefined ; + // table[(T_boolean<<4)+T_void] = T_undefined ; + // table[(T_boolean<<4)+T_String] = T_undefined ; + // table[(T_boolean<<4)+T_Object] = T_undefined ; + // table[(T_boolean<<4)+T_double] = T_undefined ; + // table[(T_boolean<<4)+T_float] = T_undefined ; + // table[(T_boolean<<4)+T_boolean] = T_undefined ; + // table[(T_boolean<<4)+T_char] = T_undefined ; + // table[(T_boolean<<4)+T_int] = T_undefined ; + // table[(T_boolean<<4)+T_null] = T_undefined ; + + // table[(T_char<<4)+T_undefined] = T_undefined ; + table[(T_char<<4)+T_byte] = (Char2Int<<12)+(Byte2Int<<4)+T_int ; + table[(T_char<<4)+T_long] = (Char2Int<<12)+(Long2Int<<4)+T_int ; + table[(T_char<<4)+T_short] = (Char2Int<<12)+(Short2Int<<4)+T_int ; + // table[(T_char<<4)+T_void] = T_undefined ; + // table[(T_char<<4)+T_String] = T_undefined ; + // table[(T_char<<4)+T_Object] = T_undefined ; + // table[(T_char<<4)+T_double] = T_undefined ; + // table[(T_char<<4)+T_float] = T_undefined ; + // table[(T_char<<4)+T_boolean] = T_undefined ; + table[(T_char<<4)+T_char] = (Char2Int<<12)+(Char2Int<<4)+T_int ; + table[(T_char<<4)+T_int] = (Char2Int<<12)+(Int2Int<<4)+T_int ; + // table[(T_char<<4)+T_null] = T_undefined ; + + // table[(T_int<<4)+T_undefined] = T_undefined ; + table[(T_int<<4)+T_byte] = (Int2Int<<12)+(Byte2Int<<4)+T_int ; + table[(T_int<<4)+T_long] = (Int2Int<<12)+(Long2Int<<4)+T_int ; + table[(T_int<<4)+T_short] = (Int2Int<<12)+(Short2Int<<4)+T_int ; + // table[(T_int<<4)+T_void] = T_undefined ; + // table[(T_int<<4)+T_String] = T_undefined ; + // table[(T_int<<4)+T_Object] = T_undefined ; + // table[(T_int<<4)+T_double] = T_undefined ; + // table[(T_int<<4)+T_float] = T_undefined ; + // table[(T_int<<4)+T_boolean] = T_undefined ; + table[(T_int<<4)+T_char] = (Int2Int<<12)+(Char2Int<<4)+T_int ; + table[(T_int<<4)+T_int] = (Int2Int<<12)+(Int2Int<<4)+T_int ; + // table[(T_int<<4)+T_null] = T_undefined ; + + // table[(T_null<<4)+T_undefined] = T_undefined ; + // table[(T_null<<4)+T_byte] = T_undefined ; + // table[(T_null<<4)+T_long] = T_undefined ; + // table[(T_null<<4)+T_short] = T_undefined ; + // table[(T_null<<4)+T_void] = T_undefined ; + // table[(T_null<<4)+T_String] = T_undefined ; + // table[(T_null<<4)+T_Object] = T_undefined ; + // table[(T_null<<4)+T_double] = T_undefined ; + // table[(T_null<<4)+T_float] = T_undefined ; + // table[(T_null<<4)+T_boolean] = T_undefined ; + // table[(T_null<<4)+T_char] = T_undefined ; + // table[(T_null<<4)+T_int] = T_undefined ; + // table[(T_null<<4)+T_null] = T_undefined ; + + return table ; + } + + public static final int[] get_LESS(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + int[] table = new int[16*16] ; + + // table[(T_undefined<<4)+T_undefined] = T_undefined ; + // table[(T_undefined<<4)+T_byte] = T_undefined ; + // table[(T_undefined<<4)+T_long] = T_undefined ; + // table[(T_undefined<<4)+T_short] = T_undefined ; + // table[(T_undefined<<4)+T_void] = T_undefined ; + // table[(T_undefined<<4)+T_String] = T_undefined ; + // table[(T_undefined<<4)+T_Object] = T_undefined ; + // table[(T_undefined<<4)+T_double] = T_undefined ; + // table[(T_undefined<<4)+T_float] = T_undefined ; + // table[(T_undefined<<4)+T_boolean] = T_undefined ; + // table[(T_undefined<<4)+T_char] = T_undefined ; + // table[(T_undefined<<4)+T_int] = T_undefined ; + // table[(T_undefined<<4)+T_null] = T_undefined ; + + // table[(T_byte<<4)+T_undefined] = T_undefined ; + table[(T_byte<<4)+T_byte] = (Byte2Int<<12)+(Byte2Int<<4)+T_boolean ; + table[(T_byte<<4)+T_long] = (Byte2Long<<12)+(Long2Long<<4)+T_boolean ; + table[(T_byte<<4)+T_short] = (Byte2Int<<12)+(Short2Int<<4)+T_boolean ; + // table[(T_byte<<4)+T_void] = T_undefined ; + // table[(T_byte<<4)+T_String] = T_undefined ; + // table[(T_byte<<4)+T_Object] = T_undefined ; + table[(T_byte<<4)+T_double] = (Byte2Double<<12)+(Double2Double<<4)+T_boolean ; + table[(T_byte<<4)+T_float] = (Byte2Float<<12)+(Float2Float<<4)+T_boolean; + // table[(T_byte<<4)+T_boolean] = T_undefined ; + table[(T_byte<<4)+T_char] = (Byte2Int<<12)+(Char2Int<<4)+T_boolean ; + table[(T_byte<<4)+T_int] = (Byte2Int<<12)+(Int2Int<<4)+T_boolean ; + // table[(T_byte<<4)+T_null] = T_undefined ; + + // table[(T_long<<4)+T_undefined] = T_undefined ; + table[(T_long<<4)+T_byte] = (Long2Long<<12)+(Byte2Long<<4)+T_boolean; + table[(T_long<<4)+T_long] = (Long2Long<<12)+(Long2Long<<4)+T_boolean ; + table[(T_long<<4)+T_short] = (Long2Long<<12)+(Short2Long<<4)+T_boolean ; + // table[(T_long<<4)+T_void] = T_undefined ; + // table[(T_long<<4)+T_String] = T_undefined ; + // table[(T_long<<4)+T_Object] = T_undefined ; + table[(T_long<<4)+T_double] = (Long2Double<<12)+(Double2Double<<4)+T_boolean ; + table[(T_long<<4)+T_float] = (Long2Float<<12)+(Float2Float<<4)+T_boolean ; + // table[(T_long<<4)+T_boolean] = T_undefined ; + table[(T_long<<4)+T_char] = (Long2Long<<12)+(Char2Long<<4)+T_boolean ; + table[(T_long<<4)+T_int] = (Long2Long<<12)+(Int2Long<<4)+T_boolean ; + // table[(T_long<<4)+T_null] = T_undefined ; + + // table[(T_short<<4)+T_undefined] = T_undefined ; + table[(T_short<<4)+T_byte] = (Short2Int<<12)+(Byte2Int<<4)+T_boolean ; + table[(T_short<<4)+T_long] = (Short2Long<<12)+(Long2Long<<4)+T_boolean ; + table[(T_short<<4)+T_short] = (Short2Int<<12)+(Short2Int<<4)+T_boolean ; + // table[(T_short<<4)+T_void] = T_undefined ; + // table[(T_short<<4)+T_String] = T_undefined ; + // table[(T_short<<4)+T_Object] = T_undefined ; + table[(T_short<<4)+T_double] = (Short2Double<<12)+(Double2Double<<4)+T_boolean ; + table[(T_short<<4)+T_float] = (Short2Float<<12)+(Float2Float<<4)+T_boolean ; + // table[(T_short<<4)+T_boolean] = T_undefined ; + table[(T_short<<4)+T_char] = (Short2Int<<12)+(Char2Int<<4)+T_boolean ; + table[(T_short<<4)+T_int] = (Short2Int<<12)+(Int2Int<<4)+T_boolean ; + // table[(T_short<<4)+T_null] = T_undefined ; + + // table[(T_void<<4)+T_undefined] = T_undefined ; + // table[(T_void<<4)+T_byte] = T_undefined ; + // table[(T_void<<4)+T_long] = T_undefined ; + // table[(T_void<<4)+T_short] = T_undefined ; + // table[(T_void<<4)+T_void] = T_undefined ; + // table[(T_void<<4)+T_String] = T_undefined ; + // table[(T_void<<4)+T_Object] = T_undefined ; + // table[(T_void<<4)+T_double] = T_undefined ; + // table[(T_void<<4)+T_float] = T_undefined ; + // table[(T_void<<4)+T_boolean] = T_undefined ; + // table[(T_void<<4)+T_char] = T_undefined ; + // table[(T_void<<4)+T_int] = T_undefined ; + // table[(T_void<<4)+T_null] = T_undefined ; + + // table[(T_String<<4)+T_undefined] = T_undefined ; + // table[(T_String<<4)+T_byte] = T_undefined ; + // table[(T_String<<4)+T_long] = T_undefined ; + // table[(T_String<<4)+T_short] = T_undefined ; + // table[(T_String<<4)+T_void] = T_undefined ; + // table[(T_String<<4)+T_String] = T_undefined ; + // table[(T_String<<4)+T_Object] = T_undefined ; + // table[(T_String<<4)+T_double] = T_undefined ; + // table[(T_String<<4)+T_float] = T_undefined ; + // table[(T_String<<4)+T_boolean] = T_undefined ; + // table[(T_String<<4)+T_char] = T_undefined ; + // table[(T_String<<4)+T_int] = T_undefined ; + // table[(T_String<<4)+T_null] = T_undefined ; + + // table[(T_Object<<4)+T_undefined] = T_undefined ; + // table[(T_Object<<4)+T_byte] = T_undefined ; + // table[(T_Object<<4)+T_long] = T_undefined ; + // table[(T_Object<<4)+T_short] = T_undefined ; + // table[(T_Object<<4)+T_void] = T_undefined ; + // table[(T_Object<<4)+T_String] = T_undefined ; + // table[(T_Object<<4)+T_Object] = T_undefined ; + // table[(T_Object<<4)+T_double] = T_undefined ; + // table[(T_Object<<4)+T_float] = T_undefined ; + // table[(T_Object<<4)+T_boolean] = T_undefined ; + // table[(T_Object<<4)+T_char] = T_undefined ; + // table[(T_Object<<4)+T_int] = T_undefined ; + // table[(T_Object<<4)+T_null] = T_undefined ; + + // table[(T_double<<4)+T_undefined] = T_undefined ; + table[(T_double<<4)+T_byte] = (Double2Double<<12)+(Byte2Double<<4)+T_boolean ; + table[(T_double<<4)+T_long] = (Double2Double<<12)+(Long2Double<<4)+T_boolean; + table[(T_double<<4)+T_short] = (Double2Double<<12)+(Short2Double<<4)+T_boolean ; + // table[(T_double<<4)+T_void] = T_undefined ; + // table[(T_double<<4)+T_String] = T_undefined ; + // table[(T_double<<4)+T_Object] = T_undefined ; + table[(T_double<<4)+T_double] = (Double2Double<<12)+(Double2Double<<4)+T_boolean ; + table[(T_double<<4)+T_float] = (Double2Double<<12)+(Float2Double<<4)+T_boolean ; + // table[(T_double<<4)+T_boolean] = T_undefined ; + table[(T_double<<4)+T_char] = (Double2Double<<12)+(Char2Double<<4)+T_boolean ; + table[(T_double<<4)+T_int] = (Double2Double<<12)+(Int2Double<<4)+T_boolean; + // table[(T_double<<4)+T_null] = T_undefined ; + + // table[(T_float<<4)+T_undefined] = T_undefined ; + table[(T_float<<4)+T_byte] = (Float2Float<<12)+(Byte2Float<<4)+T_boolean ; + table[(T_float<<4)+T_long] = (Float2Float<<12)+(Long2Float<<4)+T_boolean ; + table[(T_float<<4)+T_short] = (Float2Float<<12)+(Short2Float<<4)+T_boolean ; + // table[(T_float<<4)+T_void] = T_undefined ; + // table[(T_float<<4)+T_String] = T_undefined ; + // table[(T_float<<4)+T_Object] = T_undefined ; + table[(T_float<<4)+T_double] = (Float2Double<<12)+(Double2Double<<4)+T_boolean ; + table[(T_float<<4)+T_float] = (Float2Float<<12)+(Float2Float<<4)+T_boolean ; + // table[(T_float<<4)+T_boolean] = T_undefined ; + table[(T_float<<4)+T_char] = (Float2Float<<12)+(Char2Float<<4)+T_boolean ; + table[(T_float<<4)+T_int] = (Float2Float<<12)+(Int2Float<<4)+T_boolean ; + // table[(T_float<<4)+T_null] = T_undefined ; + + // table[(T_boolean<<4)+T_undefined] = T_undefined ; + // table[(T_boolean<<4)+T_byte] = T_undefined ; + // table[(T_boolean<<4)+T_long] = T_undefined ; + // table[(T_boolean<<4)+T_short] = T_undefined ; + // table[(T_boolean<<4)+T_void] = T_undefined ; + // table[(T_boolean<<4)+T_String] = T_undefined ; + // table[(T_boolean<<4)+T_Object] = T_undefined ; + // table[(T_boolean<<4)+T_double] = T_undefined ; + // table[(T_boolean<<4)+T_float] = T_undefined ; + // table[(T_boolean<<4)+T_boolean] = T_undefined ; + // table[(T_boolean<<4)+T_char] = T_undefined ; + // table[(T_boolean<<4)+T_int] = T_undefined ; + // table[(T_boolean<<4)+T_null] = T_undefined ; + + // table[(T_char<<4)+T_undefined] = T_undefined ; + table[(T_char<<4)+T_byte] = (Char2Int<<12)+(Byte2Int<<4)+T_boolean ; + table[(T_char<<4)+T_long] = (Char2Long<<12)+(Long2Long<<4)+T_boolean ; + table[(T_char<<4)+T_short] = (Char2Int<<12)+(Short2Int<<4)+T_boolean ; + // table[(T_char<<4)+T_void] = T_undefined ; + // table[(T_char<<4)+T_String] = T_undefined ; + // table[(T_char<<4)+T_Object] = T_undefined ; + table[(T_char<<4)+T_double] = (Char2Double<<12)+(Double2Double<<4)+T_boolean ; + table[(T_char<<4)+T_float] = (Char2Float<<12)+(Float2Float<<4)+T_boolean ; + // table[(T_char<<4)+T_boolean] = T_undefined ; + table[(T_char<<4)+T_char] = (Char2Int<<12)+(Char2Int<<4)+T_boolean ; + table[(T_char<<4)+T_int] = (Char2Int<<12)+(Int2Int<<4)+T_boolean ; + // table[(T_char<<4)+T_null] = T_undefined ; + + // table[(T_int<<4)+T_undefined] = T_undefined ; + table[(T_int<<4)+T_byte] = (Int2Int<<12)+(Byte2Int<<4)+T_boolean ; + table[(T_int<<4)+T_long] = (Int2Long<<12)+(Long2Long<<4)+T_boolean; + table[(T_int<<4)+T_short] = (Int2Int<<12)+(Short2Int<<4)+T_boolean ; + // table[(T_int<<4)+T_void] = T_undefined ; + // table[(T_int<<4)+T_String] = T_undefined ; + // table[(T_int<<4)+T_Object] = T_undefined ; + table[(T_int<<4)+T_double] = (Int2Double<<12)+(Double2Double<<4)+T_boolean ; + table[(T_int<<4)+T_float] = (Int2Float<<12)+(Float2Float<<4)+T_boolean ; + // table[(T_int<<4)+T_boolean] = T_undefined ; + table[(T_int<<4)+T_char] = (Int2Int<<12)+(Char2Int<<4)+T_boolean ; + table[(T_int<<4)+T_int] = (Int2Int<<12)+(Int2Int<<4)+T_boolean; + // table[(T_int<<4)+T_null] = T_undefined ; + + // table[(T_null<<4)+T_undefined] = T_undefined ; + // table[(T_null<<4)+T_byte] = T_undefined ; + // table[(T_null<<4)+T_long] = T_undefined ; + // table[(T_null<<4)+T_short] = T_undefined ; + // table[(T_null<<4)+T_void] = T_undefined ; + // table[(T_null<<4)+T_String] = T_undefined ; + // table[(T_null<<4)+T_Object] = T_undefined ; + // table[(T_null<<4)+T_double] = T_undefined ; + // table[(T_null<<4)+T_float] = T_undefined ; + // table[(T_null<<4)+T_boolean] = T_undefined ; + // table[(T_null<<4)+T_char] = T_undefined ; + // table[(T_null<<4)+T_int] = T_undefined ; + // table[(T_null<<4)+T_null] = T_undefined ; + + return table ; + } + + public static final int[] get_LESS_EQUAL(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + // int[] table = new int[16*16] ; + return get_LESS(); + } + + public static final int[] get_MINUS(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + int[] table = new int[16*16] ; + + table = (int[]) get_PLUS().clone(); + + // customization + table[(T_String<<4)+T_byte] = T_undefined ; + table[(T_String<<4)+T_long] = T_undefined ; + table[(T_String<<4)+T_short] = T_undefined ; + table[(T_String<<4)+T_void] = T_undefined ; + table[(T_String<<4)+T_String] = T_undefined ; + table[(T_String<<4)+T_Object] = T_undefined ; + table[(T_String<<4)+T_double] = T_undefined ; + table[(T_String<<4)+T_float] = T_undefined ; + table[(T_String<<4)+T_boolean] = T_undefined ; + table[(T_String<<4)+T_char] = T_undefined ; + table[(T_String<<4)+T_int] = T_undefined ; + table[(T_String<<4)+T_null] = T_undefined ; + + table[(T_byte<<4) +T_String] = T_undefined ; + table[(T_long<<4) +T_String] = T_undefined ; + table[(T_short<<4) +T_String] = T_undefined ; + table[(T_void<<4) +T_String] = T_undefined ; + table[(T_Object<<4) +T_String] = T_undefined ; + table[(T_double<<4) +T_String] = T_undefined ; + table[(T_float<<4) +T_String] = T_undefined ; + table[(T_boolean<<4)+T_String] = T_undefined ; + table[(T_char<<4) +T_String] = T_undefined ; + table[(T_int<<4) +T_String] = T_undefined ; + table[(T_null<<4) +T_String] = T_undefined ; + + table[(T_null<<4) +T_null] = T_undefined ; + + return table ; + } + + public static final int[] get_MULTIPLY(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + // int[] table = new int[16*16] ; + return get_MINUS(); + } + + public static final int[] get_OR(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + + // int[] table = new int[16*16] ; + return get_AND() ; + } + + public static final int[] get_OR_OR(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + // int[] table = new int[16*16] ; + return get_AND_AND() ; + } + + public static final int[] get_PLUS(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + int[] table = new int[16*16] ; + + // table[(T_undefined<<4)+T_undefined] = T_undefined ; + // table[(T_undefined<<4)+T_byte] = T_undefined ; + // table[(T_undefined<<4)+T_long] = T_undefined ; + // table[(T_undefined<<4)+T_short] = T_undefined ; + // table[(T_undefined<<4)+T_void] = T_undefined ; + // table[(T_undefined<<4)+T_String] = T_undefined ; + // table[(T_undefined<<4)+T_Object] = T_undefined ; + // table[(T_undefined<<4)+T_double] = T_undefined ; + // table[(T_undefined<<4)+T_float] = T_undefined ; + // table[(T_undefined<<4)+T_boolean] = T_undefined ; + // table[(T_undefined<<4)+T_char] = T_undefined ; + // table[(T_undefined<<4)+T_int] = T_undefined ; + // table[(T_undefined<<4)+T_null] = T_undefined ; + + // table[(T_byte<<4)+T_undefined] = T_undefined ; + table[(T_byte<<4)+T_byte] = (Byte2Int<<12)+(Byte2Int<<4)+T_int ; + table[(T_byte<<4)+T_long] = (Byte2Long<<12)+(Long2Long<<4)+T_long ; + table[(T_byte<<4)+T_short] = (Byte2Int<<12)+(Short2Int<<4)+T_int ; + // table[(T_byte<<4)+T_void] = T_undefined ; + table[(T_byte<<4)+T_String] = (Byte2Byte<<12)+(String2String<<4)+T_String ; + // table[(T_byte<<4)+T_Object] = T_undefined ; + table[(T_byte<<4)+T_double] = (Byte2Double<<12)+(Double2Double<<4)+T_double ; + table[(T_byte<<4)+T_float] = (Byte2Float<<12)+(Float2Float<<4)+T_float; + // table[(T_byte<<4)+T_boolean] = T_undefined ; + table[(T_byte<<4)+T_char] = (Byte2Int<<12)+(Char2Int<<4)+T_int ; + table[(T_byte<<4)+T_int] = (Byte2Int<<12)+(Int2Int<<4)+T_int ; + // table[(T_byte<<4)+T_null] = T_undefined ; + + // table[(T_long<<4)+T_undefined] = T_undefined ; + table[(T_long<<4)+T_byte] = (Long2Long<<12)+(Byte2Long<<4)+T_long; + table[(T_long<<4)+T_long] = (Long2Long<<12)+(Long2Long<<4)+T_long ; + table[(T_long<<4)+T_short] = (Long2Long<<12)+(Short2Long<<4)+T_long ; + // table[(T_long<<4)+T_void] = T_undefined ; + table[(T_long<<4)+T_String] = (Long2Long<<12)+(String2String<<4)+T_String ; + // table[(T_long<<4)+T_Object] = T_undefined ; + table[(T_long<<4)+T_double] = (Long2Double<<12)+(Double2Double<<4)+T_double ; + table[(T_long<<4)+T_float] = (Long2Float<<12)+(Float2Float<<4)+T_float ; + // table[(T_long<<4)+T_boolean] = T_undefined ; + table[(T_long<<4)+T_char] = (Long2Long<<12)+(Char2Long<<4)+T_long ; + table[(T_long<<4)+T_int] = (Long2Long<<12)+(Int2Long<<4)+T_long ; ; + // table[(T_long<<4)+T_null] = T_undefined ; + + // table[(T_short<<4)+T_undefined] = T_undefined ; + table[(T_short<<4)+T_byte] = (Short2Int<<12)+(Byte2Int<<4)+T_int ; + table[(T_short<<4)+T_long] = (Short2Long<<12)+(Long2Long<<4)+T_long ; + table[(T_short<<4)+T_short] = (Short2Int<<12)+(Short2Int<<4)+T_int ; + // table[(T_short<<4)+T_void] = T_undefined ; + table[(T_short<<4)+T_String] = (Short2Short<<12)+(String2String<<4)+T_String ; + // table[(T_short<<4)+T_Object] = T_undefined ; + table[(T_short<<4)+T_double] = (Short2Double<<12)+(Double2Double<<4)+T_double ; + table[(T_short<<4)+T_float] = (Short2Float<<12)+(Float2Float<<4)+T_float ; + // table[(T_short<<4)+T_boolean] = T_undefined ; + table[(T_short<<4)+T_char] = (Short2Int<<12)+(Char2Int<<4)+T_int ; + table[(T_short<<4)+T_int] = (Short2Int<<12)+(Int2Int<<4)+T_int ; + // table[(T_short<<4)+T_null] = T_undefined ; + + // table[(T_void<<4)+T_undefined] = T_undefined ; + // table[(T_void<<4)+T_byte] = T_undefined ; + // table[(T_void<<4)+T_long] = T_undefined ; + // table[(T_void<<4)+T_short] = T_undefined ; + // table[(T_void<<4)+T_void] = T_undefined ; + // table[(T_void<<4)+T_String] = T_undefined ; + // table[(T_void<<4)+T_Object] = T_undefined ; + // table[(T_void<<4)+T_double] = T_undefined ; + // table[(T_void<<4)+T_float] = T_undefined ; + // table[(T_void<<4)+T_boolean] = T_undefined ; + // table[(T_void<<4)+T_char] = T_undefined ; + // table[(T_void<<4)+T_int] = T_undefined ; + // table[(T_void<<4)+T_null] = T_undefined ; + + // table[(T_String<<4)+T_undefined] = T_undefined ; + table[(T_String<<4)+T_byte] = (String2String<<12)+(Byte2Byte<<4)+T_String ; + table[(T_String<<4)+T_long] = (String2String<<12)+(Long2Long<<4)+T_String ; + table[(T_String<<4)+T_short] = (String2String<<12)+(Short2Short<<4)+T_String ; + // table[(T_String<<4)+T_void] = T_undefined ; + table[(T_String<<4)+T_String] = (String2String<<12)+(String2String<<4)+T_String ; + table[(T_String<<4)+T_Object] = (String2String<<12)+(Object2Object<<4)+T_String ; + table[(T_String<<4)+T_double] = (String2String<<12)+(Double2Double<<4)+T_String ; + table[(T_String<<4)+T_float] = (String2String<<12)+(Float2Float<<4)+T_String ; + table[(T_String<<4)+T_boolean] = (String2String<<12)+(Boolean2Boolean<<4)+T_String ; + table[(T_String<<4)+T_char] = (String2String<<12)+(Char2Char<<4)+T_String ; + table[(T_String<<4)+T_int] = (String2String<<12)+(Int2Int<<4)+T_String ; + table[(T_String<<4)+T_null] = (String2String<<12)+(T_null<<8)+(T_null<<4)+T_String ; + + // table[(T_Object<<4)+T_undefined] = T_undefined ; + // table[(T_Object<<4)+T_byte] = T_undefined ; + // table[(T_Object<<4)+T_long] = T_undefined ; + // table[(T_Object<<4)+T_short] = T_undefined ; + // table[(T_Object<<4)+T_void] = T_undefined ; + table[(T_Object<<4)+T_String] = (Object2Object<<12)+(String2String<<4)+T_String ; + // table[(T_Object<<4)+T_Object] = T_undefined ; + // table[(T_Object<<4)+T_double] = T_undefined ; + // table[(T_Object<<4)+T_float] = T_undefined ; + // table[(T_Object<<4)+T_boolean] = T_undefined ; + // table[(T_Object<<4)+T_char] = T_undefined ; + // table[(T_Object<<4)+T_int] = T_undefined ; + // table[(T_Object<<4)+T_null] = T_undefined ; + + // table[(T_double<<4)+T_undefined] = T_undefined ; + table[(T_double<<4)+T_byte] = (Double2Double<<12)+(Byte2Double<<4)+T_double ; + table[(T_double<<4)+T_long] = (Double2Double<<12)+(Long2Double<<4)+T_double ; + table[(T_double<<4)+T_short] = (Double2Double<<12)+(Short2Double<<4)+T_double ; ; + // table[(T_double<<4)+T_void] = T_undefined ; + table[(T_double<<4)+T_String] = (Double2Double<<12)+(String2String<<4)+T_String ; + // table[(T_double<<4)+T_Object] = T_undefined ; + table[(T_double<<4)+T_double] = (Double2Double<<12)+(Double2Double<<4)+T_double ; + table[(T_double<<4)+T_float] = (Double2Double<<12)+(Float2Double<<4)+T_double ; ; + // table[(T_double<<4)+T_boolean] = T_undefined ; + table[(T_double<<4)+T_char] = (Double2Double<<12)+(Char2Double<<4)+T_double ; ; + table[(T_double<<4)+T_int] = (Double2Double<<12)+(Int2Double<<4)+T_double ; ; + // table[(T_double<<4)+T_null] = T_undefined ; + + // table[(T_float<<4)+T_undefined] = T_undefined ; + table[(T_float<<4)+T_byte] = (Float2Float<<12)+(Byte2Float<<4)+T_float ; + table[(T_float<<4)+T_long] = (Float2Float<<12)+(Long2Float<<4)+T_float ; + table[(T_float<<4)+T_short] = (Float2Float<<12)+(Short2Float<<4)+T_float ; + // table[(T_float<<4)+T_void] = T_undefined ; + table[(T_float<<4)+T_String] = (Float2Float<<12)+(String2String<<4)+T_String ; + // table[(T_float<<4)+T_Object] = T_undefined ; + table[(T_float<<4)+T_double] = (Float2Double<<12)+(Double2Double<<4)+T_double ; + table[(T_float<<4)+T_float] = (Float2Float<<12)+(Float2Float<<4)+T_float ; + // table[(T_float<<4)+T_boolean] = T_undefined ; + table[(T_float<<4)+T_char] = (Float2Float<<12)+(Char2Float<<4)+T_float ; + table[(T_float<<4)+T_int] = (Float2Float<<12)+(Int2Float<<4)+T_float ; + // table[(T_float<<4)+T_null] = T_undefined ; + + // table[(T_boolean<<4)+T_undefined] = T_undefined ; + // table[(T_boolean<<4)+T_byte] = T_undefined ; + // table[(T_boolean<<4)+T_long] = T_undefined ; + // table[(T_boolean<<4)+T_short] = T_undefined ; + // table[(T_boolean<<4)+T_void] = T_undefined ; + table[(T_boolean<<4)+T_String] = (Boolean2Boolean<<12)+(String2String<<4)+T_String ; + // table[(T_boolean<<4)+T_Object] = T_undefined ; + // table[(T_boolean<<4)+T_double] = T_undefined ; + // table[(T_boolean<<4)+T_float] = T_undefined ; + // table[(T_boolean<<4)+T_boolean] = T_undefined ; + // table[(T_boolean<<4)+T_char] = T_undefined ; + // table[(T_boolean<<4)+T_int] = T_undefined ; + // table[(T_boolean<<4)+T_null] = T_undefined ; + + // table[(T_char<<4)+T_undefined] = T_undefined ; + table[(T_char<<4)+T_byte] = (Char2Int<<12)+(Byte2Int<<4)+T_int ; + table[(T_char<<4)+T_long] = (Char2Long<<12)+(Long2Long<<4)+T_long ; + table[(T_char<<4)+T_short] = (Char2Int<<12)+(Short2Int<<4)+T_int ; + // table[(T_char<<4)+T_void] = T_undefined ; + table[(T_char<<4)+T_String] = (Char2Char<<12)+(String2String<<4)+T_String ; + // table[(T_char<<4)+T_Object] = T_undefined ; + table[(T_char<<4)+T_double] = (Char2Double<<12)+(Double2Double<<4)+T_double ; + table[(T_char<<4)+T_float] = (Char2Float<<12)+(Float2Float<<4)+T_float ; + // table[(T_char<<4)+T_boolean] = T_undefined ; + table[(T_char<<4)+T_char] = (Char2Int<<12)+(Char2Int<<4)+T_int ; ; + table[(T_char<<4)+T_int] = (Char2Int<<12)+(Int2Int<<4)+T_int ; + // table[(T_char<<4)+T_null] = T_undefined ; + + // table[(T_int<<4)+T_undefined] = T_undefined ; + table[(T_int<<4)+T_byte] = (Int2Int<<12)+(Byte2Int<<4)+T_int ; + table[(T_int<<4)+T_long] = (Int2Long<<12)+(Long2Long<<4)+T_long ; + table[(T_int<<4)+T_short] = (Int2Int<<12)+(Short2Int<<4)+T_int ; + // table[(T_int<<4)+T_void] = T_undefined ; + table[(T_int<<4)+T_String] = (Int2Int<<12)+(String2String<<4)+T_String ; + // table[(T_int<<4)+T_Object] = T_undefined ; + table[(T_int<<4)+T_double] = (Int2Double<<12)+(Double2Double<<4)+T_double ; + table[(T_int<<4)+T_float] = (Int2Float<<12)+(Float2Float<<4)+T_float ; + // table[(T_int<<4)+T_boolean] = T_undefined ; + table[(T_int<<4)+T_char] = (Int2Int<<12)+(Char2Int<<4)+T_int ; + table[(T_int<<4)+T_int] = (Int2Int<<12)+(Int2Int<<4)+T_int ; + // table[(T_int<<4)+T_null] = T_undefined ; + + // table[(T_null<<4)+T_undefined] = T_undefined ; + // table[(T_null<<4)+T_byte] = T_undefined ; + // table[(T_null<<4)+T_long] = T_undefined ; + // table[(T_null<<4)+T_short] = T_undefined ; + // table[(T_null<<4)+T_void] = T_undefined ; + table[(T_null<<4)+T_String] = (T_null<<16)+(T_null<<12)+(String2String<<4)+T_String ; + // table[(T_null<<4)+T_Object] = T_undefined ; + // table[(T_null<<4)+T_double] = T_undefined ; + // table[(T_null<<4)+T_float] = T_undefined ; + // table[(T_null<<4)+T_boolean] = T_undefined ; + // table[(T_null<<4)+T_char] = T_undefined ; + // table[(T_null<<4)+T_int] = T_undefined ; + // table[(T_null<<4)+T_null] = (Null2String<<12)+(Null2String<<4)+T_String ;; + + return table ; + } + + public static final int[] get_REMAINDER(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + // int[] table = new int[16*16] ; + return get_MINUS(); + } + + public static final int[] get_RIGHT_SHIFT(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + // int[] table = new int[16*16] ; + return get_LEFT_SHIFT(); + } + + public static final int[] get_UNSIGNED_RIGHT_SHIFT(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + // int[] table = new int[16*16] ; + return get_LEFT_SHIFT(); + } + + public static final int[] get_XOR(){ + + //the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 + + // int[] table = new int[16*16] ; + return get_AND() ; + } + + public String operatorToString() { + switch ((bits & OperatorMASK) >> OperatorSHIFT) { + case EQUAL_EQUAL : + return "=="; //$NON-NLS-1$ + case LESS_EQUAL : + return "<="; //$NON-NLS-1$ + case GREATER_EQUAL : + return ">="; //$NON-NLS-1$ + case NOT_EQUAL : + return "!="; //$NON-NLS-1$ + case LEFT_SHIFT : + return "<<"; //$NON-NLS-1$ + case RIGHT_SHIFT : + return ">>"; //$NON-NLS-1$ + case UNSIGNED_RIGHT_SHIFT : + return ">>>"; //$NON-NLS-1$ + case OR_OR : + return "||"; //$NON-NLS-1$ + case AND_AND : + return "&&"; //$NON-NLS-1$ + case PLUS : + return "+"; //$NON-NLS-1$ + case MINUS : + return "-"; //$NON-NLS-1$ + case NOT : + return "!"; //$NON-NLS-1$ + case REMAINDER : + return "%"; //$NON-NLS-1$ + case XOR : + return "^"; //$NON-NLS-1$ + case AND : + return "&"; //$NON-NLS-1$ + case MULTIPLY : + return "*"; //$NON-NLS-1$ + case OR : + return "|"; //$NON-NLS-1$ + case TWIDDLE : + return "~"; //$NON-NLS-1$ + case DIVIDE : + return "/"; //$NON-NLS-1$ + case GREATER : + return ">"; //$NON-NLS-1$ + case LESS : + return "<"; //$NON-NLS-1$ + case QUESTIONCOLON : + return "?:"; //$NON-NLS-1$ + case EQUAL : + return "="; //$NON-NLS-1$ + }; + return "unknown operator"; //$NON-NLS-1$ + } + + public String toStringExpression(){ + + //subclass redefine toStringExpressionNoParenthesis() + return "(" + toStringExpressionNoParenthesis() + ")"; //$NON-NLS-2$ //$NON-NLS-1$ + } + + public abstract String toStringExpressionNoParenthesis(); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/OperatorIds.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/OperatorIds.java new file mode 100644 index 0000000..c62835a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/OperatorIds.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +public interface OperatorIds { + public static final int AND_AND = 0; + public static final int OR_OR = 1; + public static final int AND = 2; + public static final int OR = 3; + public static final int LESS = 4; + public static final int LESS_EQUAL = 5; + public static final int GREATER = 6; + public static final int GREATER_EQUAL = 7; + public static final int XOR = 8; + public static final int DIVIDE = 9; + public static final int LEFT_SHIFT = 10; + public static final int NOT = 11; + public static final int TWIDDLE = 12; + public static final int MINUS = 13; + public static final int PLUS = 14; + public static final int MULTIPLY = 15; + public static final int REMAINDER = 16; + public static final int RIGHT_SHIFT = 17; + public static final int EQUAL_EQUAL = 18; + public static final int UNSIGNED_RIGHT_SHIFT= 19; + public static final int NumberOfTables = 20; + + public static final int QUESTIONCOLON = 23; + + public static final int NOT_EQUAL = 29; + public static final int EQUAL = 30; + public static final int INSTANCEOF = 31; + public static final int PLUS_PLUS = 32; + public static final int MINUS_MINUS = 33; +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/PostfixExpression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/PostfixExpression.java new file mode 100644 index 0000000..cd8df9a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/PostfixExpression.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; + +public class PostfixExpression extends CompoundAssignment { + + public PostfixExpression(Expression l, Expression e, int op, int pos) { + + super(l, e, op, pos); + this.sourceStart = l.sourceStart; + this.sourceEnd = pos; + } + + /** + * Code generation for PostfixExpression + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// // various scenarii are possible, setting an array reference, +// // a field reference, a blank final field reference, a field of an enclosing instance or +// // just a local variable. +// +// int pc = codeStream.position; +// ((Reference) lhs).generatePostIncrement(currentScope, codeStream, this, valueRequired); +// if (valueRequired) { +// codeStream.generateImplicitConversion(implicitConversion); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public String operatorToString() { + switch (operator) { + case PLUS : + return "++"; //$NON-NLS-1$ + case MINUS : + return "--"; //$NON-NLS-1$ + } + return "unknown operator"; //$NON-NLS-1$ + } + + public boolean restrainUsageToNumericTypes() { + + return true; + } + + public String toStringExpressionNoParenthesis() { + + return lhs.toStringExpression() + " " + operatorToString(); //$NON-NLS-1$ + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + lhs.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/PrefixExpression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/PrefixExpression.java new file mode 100644 index 0000000..f956d58 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/PrefixExpression.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; + +public class PrefixExpression extends CompoundAssignment { + + /** + * PrefixExpression constructor comment. + * @param l org.eclipse.jdt.internal.compiler.ast.Expression + * @param r org.eclipse.jdt.internal.compiler.ast.Expression + * @param op int + */ + public PrefixExpression(Expression l, Expression e, int op, int pos) { + + super(l, e, op, l.sourceEnd); + this.sourceStart = pos; + this.sourceEnd = l.sourceEnd; + } + + public String operatorToString() { + + switch (operator) { + case PLUS : + return "++"; //$NON-NLS-1$ + case MINUS : + return "--"; //$NON-NLS-1$ + } + return "unknown operator"; //$NON-NLS-1$ + } + + public boolean restrainUsageToNumericTypes() { + + return true; + } + + public String toStringExpressionNoParenthesis() { + + return operatorToString() + " " + lhs.toStringExpression(); //$NON-NLS-1$ + + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + lhs.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedAllocationExpression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedAllocationExpression.java new file mode 100644 index 0000000..dc5dc2a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedAllocationExpression.java @@ -0,0 +1,350 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +/** + * Variation on allocation, where can be specified an enclosing instance and an anonymous type + */ +public class QualifiedAllocationExpression extends AllocationExpression { + + //qualification may be on both side + public Expression enclosingInstance; + public AnonymousLocalTypeDeclaration anonymousType; + public ReferenceBinding superTypeBinding; + + public QualifiedAllocationExpression() { + } + + public QualifiedAllocationExpression(AnonymousLocalTypeDeclaration anonymousType) { + this.anonymousType = anonymousType; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + // analyse the enclosing instance + if (enclosingInstance != null) { + flowInfo = enclosingInstance.analyseCode(currentScope, flowContext, flowInfo); + } + + // check captured variables are initialized in current context (26134) + checkCapturedLocalInitializationIfNecessary( + this.superTypeBinding == null ? this.binding.declaringClass : this.superTypeBinding, + currentScope, + flowInfo); + + // process arguments + if (arguments != null) { + for (int i = 0, count = arguments.length; i < count; i++) { + flowInfo = arguments[i].analyseCode(currentScope, flowContext, flowInfo); + } + } + + // analyse the anonymous nested type + if (anonymousType != null) { + flowInfo = anonymousType.analyseCode(currentScope, flowContext, flowInfo); + } + + // record some dependency information for exception types + ReferenceBinding[] thrownExceptions; + if (((thrownExceptions = binding.thrownExceptions).length) != 0) { + // check exception handling + flowContext.checkExceptionHandlers( + thrownExceptions, + this, + flowInfo, + currentScope); + } + manageEnclosingInstanceAccessIfNecessary(currentScope); + manageSyntheticAccessIfNecessary(currentScope); + return flowInfo; + } + + public Expression enclosingInstance() { + + return enclosingInstance; + } + +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// int pc = codeStream.position; +// ReferenceBinding allocatedType = binding.declaringClass; +// codeStream.new_(allocatedType); +// if (valueRequired) { +// codeStream.dup(); +// } +// // better highlight for allocation: display the type individually +// codeStream.recordPositionsFrom(pc, type.sourceStart); +// +// // handling innerclass instance allocation - enclosing instance arguments +// if (allocatedType.isNestedType()) { +// codeStream.generateSyntheticEnclosingInstanceValues( +// currentScope, +// allocatedType, +// enclosingInstance(), +// this); +// } +// // generate the arguments for constructor +// if (arguments != null) { +// for (int i = 0, count = arguments.length; i < count; i++) { +// arguments[i].generateCode(currentScope, codeStream, true); +// } +// } +// // handling innerclass instance allocation - outer local arguments +// if (allocatedType.isNestedType()) { +// codeStream.generateSyntheticOuterArgumentValues( +// currentScope, +// allocatedType, +// this); +// } +// +// // invoke constructor +// if (syntheticAccessor == null) { +// codeStream.invokespecial(binding); +// } else { +// // synthetic accessor got some extra arguments appended to its signature, which need values +// for (int i = 0, +// max = syntheticAccessor.parameters.length - binding.parameters.length; +// i < max; +// i++) { +// codeStream.aconst_null(); +// } +// codeStream.invokespecial(syntheticAccessor); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// +// if (anonymousType != null) { +// anonymousType.generateCode(currentScope, codeStream); +// } +// } + + public boolean isSuperAccess() { + + // necessary to lookup super constructor of anonymous type + return anonymousType != null; + } + + /* Inner emulation consists in either recording a dependency + * link only, or performing one level of propagation. + * + * Dependency mechanism is used whenever dealing with source target + * types, since by the time we reach them, we might not yet know their + * exact need. + */ + public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) { + + ReferenceBinding allocatedType; + + // perform some emulation work in case there is some and we are inside a local type only + if ((allocatedType = binding.declaringClass).isNestedType() + && currentScope.enclosingSourceType().isLocalType()) { + + if (allocatedType.isLocalType()) { + ((LocalTypeBinding) allocatedType).addInnerEmulationDependent(currentScope, enclosingInstance != null); + } else { + // locally propagate, since we already now the desired shape for sure + currentScope.propagateInnerEmulation(allocatedType, enclosingInstance != null); + } + } + } + + public TypeBinding resolveType(BlockScope scope) { + + // added for code assist...cannot occur with 'normal' code + if (anonymousType == null && enclosingInstance == null) { + return super.resolveType(scope); + } + + // Propagate the type checking to the arguments, and checks if the constructor is defined. + // ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt + // ClassInstanceCreationExpression ::= Name '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt + // ==> by construction, when there is an enclosing instance the typename may NOT be qualified + // ==> therefore by construction the type is always a SingleTypeReferenceType instead of being either + // sometime a SingleTypeReference and sometime a QualifedTypeReference + + constant = NotAConstant; + TypeBinding enclosingInstanceType = null; + TypeBinding receiverType = null; + boolean hasError = false; + if (anonymousType == null) { //----------------no anonymous class------------------------ + if ((enclosingInstanceType = enclosingInstance.resolveType(scope)) == null){ + hasError = true; + } else if (enclosingInstanceType.isBaseType() || enclosingInstanceType.isArrayType()) { + scope.problemReporter().illegalPrimitiveOrArrayTypeForEnclosingInstance( + enclosingInstanceType, + enclosingInstance); + hasError = true; + } else if ((this.resolvedType = receiverType = ((SingleTypeReference) type).resolveTypeEnclosing( + scope, + (ReferenceBinding) enclosingInstanceType)) == null) { + hasError = true; + } + // will check for null after args are resolved + TypeBinding[] argumentTypes = NoParameters; + if (arguments != null) { + int length = arguments.length; + argumentTypes = new TypeBinding[length]; + for (int i = 0; i < length; i++) + if ((argumentTypes[i] = arguments[i].resolveType(scope)) == null){ + hasError = true; + } + } + // limit of fault-tolerance + if (hasError) return receiverType; + + if (!receiverType.canBeInstantiated()) { + scope.problemReporter().cannotInstantiate(type, receiverType); + return receiverType; + } + if ((this.binding = scope.getConstructor((ReferenceBinding) receiverType, argumentTypes, this)) + .isValidBinding()) { + if (isMethodUseDeprecated(binding, scope)) + scope.problemReporter().deprecatedMethod(this.binding, this); + + if (arguments != null) + for (int i = 0; i < arguments.length; i++) + arguments[i].implicitWidening(this.binding.parameters[i], argumentTypes[i]); + } else { + if (this.binding.declaringClass == null) + this.binding.declaringClass = (ReferenceBinding) receiverType; + scope.problemReporter().invalidConstructor(this, this.binding); + return receiverType; + } + + // The enclosing instance must be compatible with the innermost enclosing type + ReferenceBinding expectedType = this.binding.declaringClass.enclosingType(); + if (enclosingInstanceType.isCompatibleWith(expectedType)) + return receiverType; + scope.problemReporter().typeMismatchErrorActualTypeExpectedType( + this.enclosingInstance, + enclosingInstanceType, + expectedType); + return receiverType; + } + + //--------------there is an anonymous type declaration----------------- + if (this.enclosingInstance != null) { + if ((enclosingInstanceType = this.enclosingInstance.resolveType(scope)) == null) { + hasError = true; + } else if (enclosingInstanceType.isBaseType() || enclosingInstanceType.isArrayType()) { + scope.problemReporter().illegalPrimitiveOrArrayTypeForEnclosingInstance( + enclosingInstanceType, + this.enclosingInstance); + hasError = true; + } else { + receiverType = ((SingleTypeReference) type).resolveTypeEnclosing( + scope, + (ReferenceBinding) enclosingInstanceType); + } + } else { + receiverType = type.resolveType(scope); + } + if (receiverType == null) { + hasError = true; + } else if (((ReferenceBinding) receiverType).isFinal()) { + scope.problemReporter().anonymousClassCannotExtendFinalClass(type, receiverType); + hasError = true; + } + TypeBinding[] argumentTypes = NoParameters; + if (arguments != null) { + int length = arguments.length; + argumentTypes = new TypeBinding[length]; + for (int i = 0; i < length; i++) + if ((argumentTypes[i] = arguments[i].resolveType(scope)) == null) { + hasError = true; + } + } + // limit of fault-tolerance + if (hasError) { + return receiverType; + } + + // an anonymous class inherits from java.lang.Object when declared "after" an interface + this.superTypeBinding = + receiverType.isInterface() ? scope.getJavaLangObject() : (ReferenceBinding) receiverType; + MethodBinding inheritedBinding = + scope.getConstructor(this.superTypeBinding, argumentTypes, this); + if (!inheritedBinding.isValidBinding()) { + if (inheritedBinding.declaringClass == null) + inheritedBinding.declaringClass = this.superTypeBinding; + scope.problemReporter().invalidConstructor(this, inheritedBinding); + return null; + } + if (enclosingInstance != null) { + if (!enclosingInstanceType.isCompatibleWith(inheritedBinding.declaringClass.enclosingType())) { + scope.problemReporter().typeMismatchErrorActualTypeExpectedType( + enclosingInstance, + enclosingInstanceType, + inheritedBinding.declaringClass.enclosingType()); + return null; + } + } + + // this promotion has to be done somewhere: here or inside the constructor of the + // anonymous class. We do it here while the constructor of the inner is then easier. + if (arguments != null) + for (int i = 0; i < arguments.length; i++) + arguments[i].implicitWidening(inheritedBinding.parameters[i], argumentTypes[i]); + + // Update the anonymous inner class : superclass, interface + scope.addAnonymousType(anonymousType, (ReferenceBinding) receiverType); + anonymousType.resolve(scope); + binding = anonymousType.createsInternalConstructorWithBinding(inheritedBinding); + return anonymousType.binding; // 1.2 change + } + + public String toStringExpression() { + return this.toStringExpression(0); + } + + public String toStringExpression(int tab) { + + String s = ""; //$NON-NLS-1$ + if (enclosingInstance != null) + s += enclosingInstance.toString() + "."; //$NON-NLS-1$ + s += super.toStringExpression(); + if (anonymousType != null) { + s += anonymousType.toString(tab); + } //allows to restart just after the } one line under .... + return s; + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + if (visitor.visit(this, scope)) { + if (enclosingInstance != null) + enclosingInstance.traverse(visitor, scope); + type.traverse(visitor, scope); + if (arguments != null) { + int argumentsLength = arguments.length; + for (int i = 0; i < argumentsLength; i++) + arguments[i].traverse(visitor, scope); + } + if (anonymousType != null) + anonymousType.traverse(visitor, scope); + } + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedNameReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedNameReference.java new file mode 100644 index 0000000..449a39c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedNameReference.java @@ -0,0 +1,800 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ProblemFieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ProblemReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SyntheticAccessMethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding; + + +public class QualifiedNameReference extends NameReference { + + public char[][] tokens; + public FieldBinding[] otherBindings, otherCodegenBindings; + int[] otherDepths; + public int indexOfFirstFieldBinding;//points (into tokens) for the first token that corresponds to first FieldBinding + SyntheticAccessMethodBinding syntheticWriteAccessor; + SyntheticAccessMethodBinding[] syntheticReadAccessors; + protected FieldBinding lastFieldBinding; + public QualifiedNameReference( + char[][] sources, + int sourceStart, + int sourceEnd) { + super(); + tokens = sources; + this.sourceStart = sourceStart; + this.sourceEnd = sourceEnd; + } + public FlowInfo analyseAssignment( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo, + Assignment assignment, + boolean isCompound) { + + // determine the rank until which we now we do not need any actual value for the field access + int otherBindingsCount = otherBindings == null ? 0 : otherBindings.length; + boolean needValue = otherBindingsCount == 0 || !this.otherBindings[0].isStatic(); + switch (bits & RestrictiveFlagMASK) { + case FIELD : // reading a field + lastFieldBinding = (FieldBinding) binding; + if (needValue) { + manageSyntheticReadAccessIfNecessary(currentScope, lastFieldBinding, this.actualReceiverType, 0); + } // check if final blank field + if (lastFieldBinding.isBlankFinal() + && this.otherBindings != null // the last field binding is only assigned + && currentScope.allowBlankFinalFieldAssignment(lastFieldBinding)) { + if (!flowInfo.isDefinitelyAssigned(lastFieldBinding)) { + currentScope.problemReporter().uninitializedBlankFinalField( + lastFieldBinding, + this); + } + } + break; + case LOCAL : + // first binding is a local variable + LocalVariableBinding localBinding; + if (!flowInfo + .isDefinitelyAssigned(localBinding = (LocalVariableBinding) binding)) { + currentScope.problemReporter().uninitializedLocalVariable(localBinding, this); + } + if (flowInfo.isReachable()) { + localBinding.useFlag = LocalVariableBinding.USED; + } else if (localBinding.useFlag == LocalVariableBinding.UNUSED) { + localBinding.useFlag = LocalVariableBinding.FAKE_USED; + } + } + + if (needValue) { + manageEnclosingInstanceAccessIfNecessary(currentScope); + // only for first binding + } + // all intermediate field accesses are read accesses + if (otherBindings != null) { + for (int i = 0; i < otherBindingsCount-1; i++) { + lastFieldBinding = otherBindings[i]; + needValue = !otherBindings[i+1].isStatic(); + if (needValue) { + manageSyntheticReadAccessIfNecessary( + currentScope, + lastFieldBinding, + i == 0 + ? ((VariableBinding)binding).type + : otherBindings[i-1].type, + i + 1); + } + } + lastFieldBinding = otherBindings[otherBindingsCount-1]; + } + + if (isCompound) { + if (binding == lastFieldBinding + && lastFieldBinding.isBlankFinal() + && currentScope.allowBlankFinalFieldAssignment(lastFieldBinding) + && (!flowInfo.isDefinitelyAssigned(lastFieldBinding))) { + currentScope.problemReporter().uninitializedBlankFinalField( + lastFieldBinding, + this); + } + TypeBinding lastReceiverType; + if (lastFieldBinding == binding){ + lastReceiverType = this.actualReceiverType; + } else if (otherBindingsCount == 1){ + lastReceiverType = ((VariableBinding)this.binding).type; + } else { + lastReceiverType = this.otherBindings[otherBindingsCount-2].type; + } + manageSyntheticReadAccessIfNecessary( + currentScope, + lastFieldBinding, + lastReceiverType, + lastFieldBinding == binding + ? 0 + : otherBindingsCount); + } + + if (assignment.expression != null) { + flowInfo = + assignment + .expression + .analyseCode(currentScope, flowContext, flowInfo) + .unconditionalInits(); + } + + // the last field access is a write access + if (lastFieldBinding.isFinal()) { + // in a context where it can be assigned? + if (lastFieldBinding.isBlankFinal() + && !isCompound + && currentScope.allowBlankFinalFieldAssignment(lastFieldBinding) + && indexOfFirstFieldBinding == 1) { + if (flowInfo.isPotentiallyAssigned(lastFieldBinding)) { + currentScope.problemReporter().duplicateInitializationOfBlankFinalField(lastFieldBinding, this); + } else { + flowContext.recordSettingFinal(lastFieldBinding, this); + } + flowInfo.markAsDefinitelyAssigned(lastFieldBinding); + } else { + currentScope.problemReporter().cannotAssignToFinalField(lastFieldBinding, this); + if (currentScope.allowBlankFinalFieldAssignment(lastFieldBinding)) { // pretend it got assigned + flowInfo.markAsDefinitelyAssigned(lastFieldBinding); + } + } + } + // equivalent to valuesRequired[maxOtherBindings] + TypeBinding lastReceiverType; + if (lastFieldBinding == binding){ + lastReceiverType = this.actualReceiverType; + } else if (otherBindingsCount == 1){ + lastReceiverType = ((VariableBinding)this.binding).type; + } else { + lastReceiverType = this.otherBindings[otherBindingsCount-2].type; + } + manageSyntheticWriteAccessIfNecessary(currentScope, lastFieldBinding, lastReceiverType); + + return flowInfo; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + return analyseCode(currentScope, flowContext, flowInfo, true); + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo, + boolean valueRequired) { + + // determine the rank until which we now we do not need any actual value for the field access + int otherBindingsCount = otherBindings == null ? 0 : otherBindings.length; + + boolean needValue = otherBindingsCount == 0 ? valueRequired : !this.otherBindings[0].isStatic(); + switch (bits & RestrictiveFlagMASK) { + case FIELD : // reading a field + if (needValue) { + manageSyntheticReadAccessIfNecessary(currentScope, (FieldBinding) binding, this.actualReceiverType, 0); + } + // check if reading a final blank field + FieldBinding fieldBinding; + if ((fieldBinding = (FieldBinding) binding).isBlankFinal() + && (indexOfFirstFieldBinding == 1) + // was an implicit reference to the first field binding + && currentScope.allowBlankFinalFieldAssignment(fieldBinding) + && (!flowInfo.isDefinitelyAssigned(fieldBinding))) { + currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this); + } + break; + case LOCAL : // reading a local variable + LocalVariableBinding localBinding; + if (!flowInfo + .isDefinitelyAssigned(localBinding = (LocalVariableBinding) binding)) { + currentScope.problemReporter().uninitializedLocalVariable(localBinding, this); + } + if (flowInfo.isReachable()) { + localBinding.useFlag = LocalVariableBinding.USED; + } else if (localBinding.useFlag == LocalVariableBinding.UNUSED) { + localBinding.useFlag = LocalVariableBinding.FAKE_USED; + } + } + if (needValue) { + manageEnclosingInstanceAccessIfNecessary(currentScope); + // only for first binding + } + if (otherBindings != null) { + for (int i = 0; i < otherBindingsCount; i++) { + needValue = i < otherBindingsCount-1 ? !otherBindings[i+1].isStatic() : valueRequired; + if (needValue) { + manageSyntheticReadAccessIfNecessary( + currentScope, + otherBindings[i], + i == 0 + ? ((VariableBinding)binding).type + : otherBindings[i-1].type, + i + 1); + } + } + } + return flowInfo; + } + /** + * Check and/or redirect the field access to the delegate receiver if any + */ + public TypeBinding checkFieldAccess(BlockScope scope) { + // check for forward references + FieldBinding fieldBinding = (FieldBinding) binding; + MethodScope methodScope = scope.methodScope(); + if (methodScope.enclosingSourceType() == fieldBinding.declaringClass + && methodScope.fieldDeclarationIndex != MethodScope.NotInFieldDecl + && fieldBinding.id >= methodScope.fieldDeclarationIndex) { + if ((!fieldBinding.isStatic() || methodScope.isStatic) + && this.indexOfFirstFieldBinding == 1) + scope.problemReporter().forwardReference(this, 0, scope.enclosingSourceType()); + } + bits &= ~RestrictiveFlagMASK; // clear bits + bits |= FIELD; + return getOtherFieldBindings(scope); + } +// public void generateAssignment( +// BlockScope currentScope, +// CodeStream codeStream, +// Assignment assignment, +// boolean valueRequired) { +// +// generateReadSequence(currentScope, codeStream); +// assignment.expression.generateCode(currentScope, codeStream, true); +// fieldStore(codeStream, lastFieldBinding, syntheticWriteAccessor, valueRequired); +// // equivalent to valuesRequired[maxOtherBindings] +// if (valueRequired) { +// codeStream.generateImplicitConversion(assignment.implicitConversion); +// } +// } +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// int pc = codeStream.position; +// if (constant != NotAConstant) { +// if (valueRequired) { +// codeStream.generateConstant(constant, implicitConversion); +// } +// } else { +// generateReadSequence(currentScope, codeStream); +// if (valueRequired) { +// if (lastFieldBinding.declaringClass == null) { // array length +// codeStream.arraylength(); +// codeStream.generateImplicitConversion(implicitConversion); +// } else { +// if (lastFieldBinding.constant != NotAConstant) { +// if (!lastFieldBinding.isStatic()){ +// codeStream.invokeObjectGetClass(); +// codeStream.pop(); +// } +// // inline the last field constant +// codeStream.generateConstant(lastFieldBinding.constant, implicitConversion); +// } else { +// SyntheticAccessMethodBinding accessor = +// syntheticReadAccessors == null +// ? null +// : syntheticReadAccessors[syntheticReadAccessors.length - 1]; +// if (accessor == null) { +// if (lastFieldBinding.isStatic()) { +// codeStream.getstatic(lastFieldBinding); +// } else { +// codeStream.getfield(lastFieldBinding); +// } +// } else { +// codeStream.invokestatic(accessor); +// } +// codeStream.generateImplicitConversion(implicitConversion); +// } +// } +// } else { +// if (lastFieldBinding != null && !lastFieldBinding.isStatic()){ +// codeStream.invokeObjectGetClass(); // perform null check +// codeStream.pop(); +// } +// +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } +// public void generateCompoundAssignment( +// BlockScope currentScope, +// CodeStream codeStream, +// Expression expression, +// int operator, +// int assignmentImplicitConversion, +// boolean valueRequired) { +// +// generateReadSequence(currentScope, codeStream); +// SyntheticAccessMethodBinding accessor = +// syntheticReadAccessors == null +// ? null +// : syntheticReadAccessors[syntheticReadAccessors.length - 1]; +// if (lastFieldBinding.isStatic()) { +// if (accessor == null) { +// codeStream.getstatic(lastFieldBinding); +// } else { +// codeStream.invokestatic(accessor); +// } +// } else { +// codeStream.dup(); +// if (accessor == null) { +// codeStream.getfield(lastFieldBinding); +// } else { +// codeStream.invokestatic(accessor); +// } +// } +// // the last field access is a write access +// // perform the actual compound operation +// int operationTypeID; +// if ((operationTypeID = implicitConversion >> 4) == T_String) { +// codeStream.generateStringAppend(currentScope, null, expression); +// } else { +// // promote the array reference to the suitable operation type +// codeStream.generateImplicitConversion(implicitConversion); +// // generate the increment value (will by itself be promoted to the operation value) +// if (expression == IntLiteral.One) { // prefix operation +// codeStream.generateConstant(expression.constant, implicitConversion); +// } else { +// expression.generateCode(currentScope, codeStream, true); +// } +// // perform the operation +// codeStream.sendOperator(operator, operationTypeID); +// // cast the value back to the array reference type +// codeStream.generateImplicitConversion(assignmentImplicitConversion); +// } +// // actual assignment +// fieldStore(codeStream, lastFieldBinding, syntheticWriteAccessor, valueRequired); +// // equivalent to valuesRequired[maxOtherBindings] +// } +// public void generatePostIncrement( +// BlockScope currentScope, +// CodeStream codeStream, +// CompoundAssignment postIncrement, +// boolean valueRequired) { +// generateReadSequence(currentScope, codeStream); +// SyntheticAccessMethodBinding accessor = +// syntheticReadAccessors == null +// ? null +// : syntheticReadAccessors[syntheticReadAccessors.length - 1]; +// if (lastFieldBinding.isStatic()) { +// if (accessor == null) { +// codeStream.getstatic(lastFieldBinding); +// } else { +// codeStream.invokestatic(accessor); +// } +// } else { +// codeStream.dup(); +// if (accessor == null) { +// codeStream.getfield(lastFieldBinding); +// } else { +// codeStream.invokestatic(accessor); +// } +// } +// // duplicate the old field value +// if (valueRequired) { +// if (lastFieldBinding.isStatic()) { +// if ((lastFieldBinding.type == LongBinding) +// || (lastFieldBinding.type == DoubleBinding)) { +// codeStream.dup2(); +// } else { +// codeStream.dup(); +// } +// } else { // Stack: [owner][old field value] ---> [old field value][owner][old field value] +// if ((lastFieldBinding.type == LongBinding) +// || (lastFieldBinding.type == DoubleBinding)) { +// codeStream.dup2_x1(); +// } else { +// codeStream.dup_x1(); +// } +// } +// } +// codeStream.generateConstant( +// postIncrement.expression.constant, +// implicitConversion); +// codeStream.sendOperator(postIncrement.operator, lastFieldBinding.type.id); +// codeStream.generateImplicitConversion( +// postIncrement.assignmentImplicitConversion); +// fieldStore(codeStream, lastFieldBinding, syntheticWriteAccessor, false); +// } +// /* +// * Generate code for all bindings (local and fields) excluding the last one, which may then be generated code +// * for a read or write access. +// */ +// public void generateReadSequence( +// BlockScope currentScope, +// CodeStream codeStream) { +// +// // determine the rank until which we now we do not need any actual value for the field access +// int otherBindingsCount = this.otherCodegenBindings == null ? 0 : otherCodegenBindings.length; +// +// boolean needValue = otherBindingsCount == 0 || !this.otherBindings[0].isStatic(); +// switch (bits & RestrictiveFlagMASK) { +// case FIELD : +// lastFieldBinding = (FieldBinding) this.codegenBinding; +// // if first field is actually constant, we can inline it +// if (lastFieldBinding.constant != NotAConstant) { +// break; +// } +// if (needValue && !lastFieldBinding.isStatic()) { +// if ((bits & DepthMASK) != 0) { +// ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT); +// Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/); +// codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope); +// } else { +// generateReceiver(codeStream); +// } +// } +// break; +// case LOCAL : // reading the first local variable +// if (!needValue) break; // no value needed +// lastFieldBinding = null; +// LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; +// // regular local variable read +// if (localBinding.constant != NotAConstant) { +// codeStream.generateConstant(localBinding.constant, 0); +// // no implicit conversion +// } else { +// // outer local? +// if ((bits & DepthMASK) != 0) { +// // outer local can be reached either through a synthetic arg or a synthetic field +// VariableBinding[] path = currentScope.getEmulationPath(localBinding); +// codeStream.generateOuterAccess(path, this, localBinding, currentScope); +// } else { +// codeStream.load(localBinding); +// } +// } +// } +// +// // all intermediate field accesses are read accesses +// // only the last field binding is a write access +// if (this.otherCodegenBindings != null) { +// for (int i = 0; i < otherBindingsCount; i++) { +// FieldBinding nextField = this.otherCodegenBindings[i]; +// if (lastFieldBinding != null) { +// needValue = !nextField.isStatic(); +// if (needValue) { +// MethodBinding accessor = +// syntheticReadAccessors == null ? null : syntheticReadAccessors[i]; +// if (accessor == null) { +// if (lastFieldBinding.constant != NotAConstant) { +// if (this.lastFieldBinding != this.codegenBinding && !this.lastFieldBinding.isStatic()) { +// codeStream.invokeObjectGetClass(); // perform null check +// codeStream.pop(); +// } +// codeStream.generateConstant(lastFieldBinding.constant, 0); +// } else if (lastFieldBinding.isStatic()) { +// codeStream.getstatic(lastFieldBinding); +// } else { +// codeStream.getfield(lastFieldBinding); +// } +// } else { +// codeStream.invokestatic(accessor); +// } +// } else { +// if (this.codegenBinding != this.lastFieldBinding && !this.lastFieldBinding.isStatic()){ +// codeStream.invokeObjectGetClass(); // perform null check +// codeStream.pop(); +// } +// } +// } +// this.lastFieldBinding = nextField; +// } +// } +// } +// public void generateReceiver(CodeStream codeStream) { +// codeStream.aload_0(); +// } + public TypeBinding getOtherFieldBindings(BlockScope scope) { + // At this point restrictiveFlag may ONLY have two potential value : FIELD LOCAL (i.e cast <<(VariableBinding) binding>> is valid) + if ((bits & FIELD) != 0) { + if (!((FieldBinding) binding).isStatic()) { + //must check for the static status.... + if (indexOfFirstFieldBinding == 1) { + //the field is the first token of the qualified reference.... + if (scope.methodScope().isStatic) { + scope.problemReporter().staticFieldAccessToNonStaticVariable( + this, + (FieldBinding) binding); + return null; + } + } else { //accessing to a field using a type as "receiver" is allowed only with static field + scope.problemReporter().staticFieldAccessToNonStaticVariable( + this, + (FieldBinding) binding); + return null; + } + } + if (isFieldUseDeprecated((FieldBinding) binding, scope)) + scope.problemReporter().deprecatedField((FieldBinding) binding, this); + } + TypeBinding type = ((VariableBinding) binding).type; + int index = indexOfFirstFieldBinding; + int length = tokens.length; + if (index == length) { // restrictiveFlag == FIELD + this.constant = FieldReference.getConstantFor((FieldBinding) binding, this, false, scope); + return type; + } + // allocation of the fieldBindings array and its respective constants + int otherBindingsLength = length - index; + otherCodegenBindings = otherBindings = new FieldBinding[otherBindingsLength]; + otherDepths = new int[otherBindingsLength]; + + // fill the first constant (the one of the binding) + this.constant = + ((bits & FIELD) != 0) + ? FieldReference.getConstantFor((FieldBinding) binding, this, false, scope) + : ((VariableBinding) binding).constant; + // save first depth, since will be updated by visibility checks of other bindings + int firstDepth = (bits & DepthMASK) >> DepthSHIFT; + // iteration on each field + while (index < length) { + char[] token = tokens[index]; + if (type == null) + return null; // could not resolve type prior to this point + + bits &= ~DepthMASK; // flush previous depth if any + FieldBinding field = scope.getField(type, token, this); + int place = index - indexOfFirstFieldBinding; + otherBindings[place] = field; + otherDepths[place] = (bits & DepthMASK) >> DepthSHIFT; + if (field.isValidBinding()) { + if (isFieldUseDeprecated(field, scope)) + scope.problemReporter().deprecatedField(field, this); + Constant someConstant = FieldReference.getConstantFor(field, this, false, scope); + // constant propagation can only be performed as long as the previous one is a constant too. + if (this.constant != NotAConstant) { + this.constant = someConstant; + } + + type = field.type; + index++; + + if (field.isStatic()) { + // static field accessed through receiver? legal but unoptimal (optional warning) + scope.problemReporter().unnecessaryReceiverForStaticField(this, field); + } + + } else { + constant = NotAConstant; //don't fill other constants slots... + scope.problemReporter().invalidField(this, field, index, type); + setDepth(firstDepth); + return null; + } + } + setDepth(firstDepth); + return (otherBindings[otherBindingsLength - 1]).type; + } + public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) { + //If inlinable field, forget the access emulation, the code gen will directly target it + if (((bits & DepthMASK) == 0) || (constant != NotAConstant)) { + return; + } + if ((bits & RestrictiveFlagMASK) == LOCAL) { + currentScope.emulateOuterAccess((LocalVariableBinding) binding); + } + } + public void manageSyntheticReadAccessIfNecessary( + BlockScope currentScope, + FieldBinding fieldBinding, + TypeBinding lastReceiverType, + int index) { + // index == 0 denotes the first fieldBinding, index > 0 denotes one of the 'otherBindings' + if (fieldBinding.constant != NotAConstant) + return; + if (fieldBinding.isPrivate()) { // private access + if (fieldBinding.declaringClass != currentScope.enclosingSourceType()) { + if (syntheticReadAccessors == null) { + if (otherBindings == null) + syntheticReadAccessors = new SyntheticAccessMethodBinding[1]; + else + syntheticReadAccessors = + new SyntheticAccessMethodBinding[otherBindings.length + 1]; + } + syntheticReadAccessors[index] = ((SourceTypeBinding) fieldBinding.declaringClass).addSyntheticMethod(fieldBinding, true); + currentScope.problemReporter().needToEmulateFieldReadAccess(fieldBinding, this); + return; + } + } else if (fieldBinding.isProtected()){ + int depth = index == 0 ? (bits & DepthMASK) >> DepthSHIFT : otherDepths[index-1]; + // implicit protected access (only for first one) + if (depth > 0 && (fieldBinding.declaringClass.getPackage() + != currentScope.enclosingSourceType().getPackage())) { + if (syntheticReadAccessors == null) { + if (otherBindings == null) + syntheticReadAccessors = new SyntheticAccessMethodBinding[1]; + else + syntheticReadAccessors = + new SyntheticAccessMethodBinding[otherBindings.length + 1]; + } + syntheticReadAccessors[index] = + ((SourceTypeBinding) currentScope.enclosingSourceType().enclosingTypeAt(depth)) + .addSyntheticMethod(fieldBinding, true); + currentScope.problemReporter().needToEmulateFieldReadAccess(fieldBinding, this); + return; + } + } + // if the binding declaring class is not visible, need special action + // for runtime compatibility on 1.2 VMs : change the declaring class of the binding + // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type +// if (fieldBinding.declaringClass != lastReceiverType +// && !lastReceiverType.isArrayType() +// && fieldBinding.declaringClass != null +// && fieldBinding.constant == NotAConstant +// && ((currentScope.environment().options.targetJDK >= CompilerOptions.JDK1_2 +// && (index > 0 || indexOfFirstFieldBinding > 1 || !fieldBinding.isStatic()) +// && fieldBinding.declaringClass.id != T_Object) +// || !fieldBinding.declaringClass.canBeSeenBy(currentScope))){ +// if (index == 0){ +// this.codegenBinding = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType); +// } else { +// if (this.otherCodegenBindings == this.otherBindings){ +// int l = this.otherBindings.length; +// System.arraycopy(this.otherBindings, 0, this.otherCodegenBindings = new FieldBinding[l], 0, l); +// } +// this.otherCodegenBindings[index-1] = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType); +// } +// } + } + /* + * No need to emulate access to protected fields since not implicitly accessed + */ + public void manageSyntheticWriteAccessIfNecessary( + BlockScope currentScope, + FieldBinding fieldBinding, + TypeBinding lastReceiverType) { + if (fieldBinding.isPrivate()) { + if (fieldBinding.declaringClass != currentScope.enclosingSourceType()) { + syntheticWriteAccessor = ((SourceTypeBinding) fieldBinding.declaringClass) + .addSyntheticMethod(fieldBinding, false); + currentScope.problemReporter().needToEmulateFieldWriteAccess(fieldBinding, this); + return; + } + } else if (fieldBinding.isProtected()){ + int depth = fieldBinding == binding ? (bits & DepthMASK) >> DepthSHIFT : otherDepths[otherDepths.length-1]; + if (depth > 0 && (fieldBinding.declaringClass.getPackage() + != currentScope.enclosingSourceType().getPackage())) { + syntheticWriteAccessor = ((SourceTypeBinding) currentScope.enclosingSourceType().enclosingTypeAt(depth)) + .addSyntheticMethod(fieldBinding, false); + currentScope.problemReporter().needToEmulateFieldWriteAccess(fieldBinding, this); + return; + } + } + // if the binding declaring class is not visible, need special action + // for runtime compatibility on 1.2 VMs : change the declaring class of the binding + // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type +// if (fieldBinding.declaringClass != lastReceiverType +// && !lastReceiverType.isArrayType() +// && fieldBinding.declaringClass != null +// && fieldBinding.constant == NotAConstant +// && ((currentScope.environment().options.targetJDK >= CompilerOptions.JDK1_2 +// && (fieldBinding != binding || indexOfFirstFieldBinding > 1 || !fieldBinding.isStatic()) +// && fieldBinding.declaringClass.id != T_Object) +// || !fieldBinding.declaringClass.canBeSeenBy(currentScope))){ +// if (fieldBinding == binding){ +// this.codegenBinding = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType); +// } else { +// if (this.otherCodegenBindings == this.otherBindings){ +// int l = this.otherBindings.length; +// System.arraycopy(this.otherBindings, 0, this.otherCodegenBindings = new FieldBinding[l], 0, l); +// } +// this.otherCodegenBindings[this.otherCodegenBindings.length-1] = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType); +// } +// } + + } + /** + * Normal field binding did not work, try to bind to a field of the delegate receiver. + */ + public TypeBinding reportError(BlockScope scope) { + if (binding instanceof ProblemFieldBinding) { + scope.problemReporter().invalidField(this, (FieldBinding) binding); + } else if (binding instanceof ProblemReferenceBinding) { + scope.problemReporter().invalidType(this, (TypeBinding) binding); + } else { + scope.problemReporter().unresolvableReference(this, binding); + } + return null; + } + public TypeBinding resolveType(BlockScope scope) { + // field and/or local are done before type lookups + // the only available value for the restrictiveFlag BEFORE + // the TC is Flag_Type Flag_LocalField and Flag_TypeLocalField + this.actualReceiverType = this.receiverType = scope.enclosingSourceType(); + constant = Constant.NotAConstant; + if ((this.codegenBinding = this.binding = scope.getBinding(tokens, bits & RestrictiveFlagMASK, this)) + .isValidBinding()) { + switch (bits & RestrictiveFlagMASK) { + case VARIABLE : //============only variable=========== + case TYPE | VARIABLE : + if (binding instanceof LocalVariableBinding) { + if (!((LocalVariableBinding) binding).isFinal() && ((bits & DepthMASK) != 0)) + scope.problemReporter().cannotReferToNonFinalOuterLocal( + (LocalVariableBinding) binding, + this); + bits &= ~RestrictiveFlagMASK; // clear bits + bits |= LOCAL; + return this.resolvedType = getOtherFieldBindings(scope); + } + if (binding instanceof FieldBinding) { + // check for forward references + FieldBinding fieldBinding = (FieldBinding) binding; + MethodScope methodScope = scope.methodScope(); + if (methodScope.enclosingSourceType() == fieldBinding.declaringClass + && methodScope.fieldDeclarationIndex != MethodScope.NotInFieldDecl + && fieldBinding.id >= methodScope.fieldDeclarationIndex) { + if ((!fieldBinding.isStatic() || methodScope.isStatic) + && this.indexOfFirstFieldBinding == 1) + scope.problemReporter().forwardReference(this, 0, scope.enclosingSourceType()); + } + bits &= ~RestrictiveFlagMASK; // clear bits + bits |= FIELD; + + // check for deprecated receiver type + // deprecation check for receiver type if not first token + if (indexOfFirstFieldBinding > 1) { + if (isTypeUseDeprecated(this.actualReceiverType, scope)) + scope.problemReporter().deprecatedType(this.actualReceiverType, this); + } + + return this.resolvedType = getOtherFieldBindings(scope); + } + // thus it was a type + bits &= ~RestrictiveFlagMASK; // clear bits + bits |= TYPE; + case TYPE : //=============only type ============== + if (isTypeUseDeprecated((TypeBinding) binding, scope)) + scope.problemReporter().deprecatedType((TypeBinding) binding, this); + return this.resolvedType = (TypeBinding) binding; + } + } + //========error cases=============== + return this.resolvedType = this.reportError(scope); + } + public void setFieldIndex(int index) { + this.indexOfFirstFieldBinding = index; + } + public String toStringExpression() { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < tokens.length; i++) { + buffer.append(tokens[i]); + if (i < (tokens.length - 1)) { + buffer.append("."); //$NON-NLS-1$ + } + } + return buffer.toString(); + } + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); + } + public String unboundReferenceErrorName() { + return new String(tokens[0]); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedSuperReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedSuperReference.java new file mode 100644 index 0000000..2d70b69 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedSuperReference.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class QualifiedSuperReference extends QualifiedThisReference { + + public QualifiedSuperReference(TypeReference name, int pos, int sourceEnd) { + super(name, pos, sourceEnd); + } + + public boolean isSuper() { + + return true; + } + + public boolean isThis() { + + return false; + } + + public TypeBinding resolveType(BlockScope scope) { + + if ((this.bits & ParenthesizedMASK) != 0) { + scope.problemReporter().invalidParenthesizedExpression(this); + return null; + } + super.resolveType(scope); + if (currentCompatibleType == null) + return null; // error case + + if (scope.isJavaLangObject(currentCompatibleType)) { + scope.problemReporter().cannotUseSuperInJavaLangObject(this); + return null; + } + return this.resolvedType = currentCompatibleType.superclass(); + } + + public String toStringExpression() { + + return qualification.toString(0) + ".super"; //$NON-NLS-1$ + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + qualification.traverse(visitor, blockScope); + } + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedThisReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedThisReference.java new file mode 100644 index 0000000..77cadf6 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedThisReference.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class QualifiedThisReference extends ThisReference { + + public TypeReference qualification; + ReferenceBinding currentCompatibleType; + + public QualifiedThisReference(TypeReference name, int sourceStart, int sourceEnd) { + super(sourceStart, sourceEnd); + qualification = name; + this.sourceStart = name.sourceStart; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + return flowInfo; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo, + boolean valueRequired) { + + return flowInfo; + } + + /** + * Code generation for QualifiedThisReference + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// int pc = codeStream.position; +// if (valueRequired) { +// if ((bits & DepthMASK) != 0) { +// Object[] emulationPath = +// currentScope.getEmulationPath(this.currentCompatibleType, true /*only exact match*/, false/*consider enclosing arg*/); +// codeStream.generateOuterAccess(emulationPath, this, this.currentCompatibleType, currentScope); +// } else { +// // nothing particular after all +// codeStream.aload_0(); +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public TypeBinding resolveType(BlockScope scope) { + + constant = NotAConstant; + this.resolvedType = qualification.resolveType(scope); + if (this.resolvedType == null) return null; + + // the qualification MUST exactly match some enclosing type name + // Its possible to qualify 'this' by the name of the current class + int depth = 0; + this.currentCompatibleType = scope.referenceType().binding; + while (this.currentCompatibleType != null + && this.currentCompatibleType != this.resolvedType) { + depth++; + this.currentCompatibleType = this.currentCompatibleType.isStatic() ? null : this.currentCompatibleType.enclosingType(); + } + bits &= ~DepthMASK; // flush previous depth if any + bits |= (depth & 0xFF) << DepthSHIFT; // encoded depth into 8 bits + + if (this.currentCompatibleType == null) { + scope.problemReporter().noSuchEnclosingInstance(this.resolvedType, this, false); + return this.resolvedType; + } + + // Ensure one cannot write code like: B() { super(B.this); } + if (depth == 0) { + checkAccess(scope.methodScope()); + } // if depth>0, path emulation will diagnose bad scenarii + return this.resolvedType; + } + + public String toStringExpression() { + + return qualification.toString(0) + ".this"; //$NON-NLS-1$ + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + qualification.traverse(visitor, blockScope); + } + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedTypeReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedTypeReference.java new file mode 100644 index 0000000..dc6e277 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/QualifiedTypeReference.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope; +import net.sourceforge.phpdt.internal.compiler.lookup.Scope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class QualifiedTypeReference extends TypeReference { + public char[][] tokens; + public long[] sourcePositions; +public QualifiedTypeReference(char[][] sources , long[] poss) { + tokens = sources ; + sourcePositions = poss ; + sourceStart = (int) (sourcePositions[0]>>>32) ; + sourceEnd = (int)(sourcePositions[sourcePositions.length-1] & 0x00000000FFFFFFFFL ) ; +} +public QualifiedTypeReference(char[][] sources , TypeBinding type , long[] poss) { + this(sources,poss); + this.resolvedType = type; +} +public TypeReference copyDims(int dim){ + //return a type reference copy of me with some dimensions + //warning : the new type ref has a null binding + + return new ArrayQualifiedTypeReference(tokens,null,dim,sourcePositions) ; +} +public TypeBinding getTypeBinding(Scope scope) { + if (this.resolvedType != null) + return this.resolvedType; + return scope.getType(tokens); +} +public char[][] getTypeName(){ + + return tokens; +} +public String toStringExpression(int tab) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < tokens.length; i++) { + buffer.append(tokens[i]); + if (i < (tokens.length - 1)) { + buffer.append("."); //$NON-NLS-1$ + } + } + return buffer.toString(); +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Reference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Reference.java new file mode 100644 index 0000000..c999c1d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Reference.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; + +public abstract class Reference extends Expression { +/** + * BaseLevelReference constructor comment. + */ +public Reference() { + super(); +} +public abstract FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound); + +public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { + return flowInfo; +} +public FieldBinding fieldBinding() { + //this method should be sent one FIELD-tagged references + // (ref.bits & BindingIds.FIELD != 0)() + return null ; +} +//public void fieldStore(CodeStream codeStream, FieldBinding fieldBinding, MethodBinding syntheticWriteAccessor, boolean valueRequired) { +// +// if (fieldBinding.isStatic()) { +// if (valueRequired) { +// if ((fieldBinding.type == LongBinding) || (fieldBinding.type == DoubleBinding)) { +// codeStream.dup2(); +// } else { +// codeStream.dup(); +// } +// } +// if (syntheticWriteAccessor == null) { +// codeStream.putstatic(fieldBinding); +// } else { +// codeStream.invokestatic(syntheticWriteAccessor); +// } +// } else { // Stack: [owner][new field value] ---> [new field value][owner][new field value] +// if (valueRequired) { +// if ((fieldBinding.type == LongBinding) || (fieldBinding.type == DoubleBinding)) { +// codeStream.dup2_x1(); +// } else { +// codeStream.dup_x1(); +// } +// } +// if (syntheticWriteAccessor == null) { +// codeStream.putfield(fieldBinding); +// } else { +// codeStream.invokestatic(syntheticWriteAccessor); +// } +// } +//} +//public abstract void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired); +// +//public abstract void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired); +// +//public abstract void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired); + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ReturnStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ReturnStatement.java new file mode 100644 index 0000000..8d65b96 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ReturnStatement.java @@ -0,0 +1,248 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.InitializationFlowContext; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class ReturnStatement extends Statement { + public Expression expression; + + public TypeBinding expressionType; + public boolean isSynchronized; + public AstNode[] subroutines; + public LocalVariableBinding saveValueVariable; + +public ReturnStatement(Expression expr, int s, int e ) { + sourceStart = s; + sourceEnd = e; + expression = expr ; +} +public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { // here requires to generate a sequence of finally blocks invocations depending corresponding + // to each of the traversed try statements, so that execution will terminate properly. + + // lookup the label, this should answer the returnContext + + if (expression != null) { + flowInfo = expression.analyseCode(currentScope, flowContext, flowInfo); + } + // compute the return sequence (running the finally blocks) + FlowContext traversedContext = flowContext; + int subIndex = 0, maxSub = 5; + boolean saveValueNeeded = false; + boolean hasValueToSave = expression != null && expression.constant == NotAConstant; + do { + AstNode sub; + if ((sub = traversedContext.subRoutine()) != null) { + if (this.subroutines == null){ + this.subroutines = new AstNode[maxSub]; + } + if (subIndex == maxSub) { + System.arraycopy(this.subroutines, 0, (this.subroutines = new AstNode[maxSub *= 2]), 0, subIndex); // grow + } + this.subroutines[subIndex++] = sub; + if (sub.cannotReturn()) { + saveValueNeeded = false; + break; + } + } + traversedContext.recordReturnFrom(flowInfo.unconditionalInits()); + + AstNode node; + if ((node = traversedContext.associatedNode) instanceof SynchronizedStatement) { + isSynchronized = true; + + } else if (node instanceof TryStatement) { + TryStatement tryStatement = (TryStatement) node; + flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits + if (hasValueToSave) { + if (this.saveValueVariable == null){ // closest subroutine secret variable is used + prepareSaveValueLocation(tryStatement); + } + saveValueNeeded = true; + } + + } else if (traversedContext instanceof InitializationFlowContext) { + currentScope.problemReporter().cannotReturnInInitializer(this); + return FlowInfo.DEAD_END; + } + } while ((traversedContext = traversedContext.parent) != null); + + // resize subroutines + if ((subroutines != null) && (subIndex != maxSub)) { + System.arraycopy(subroutines, 0, (subroutines = new AstNode[subIndex]), 0, subIndex); + } + + // secret local variable for return value (note that this can only occur in a real method) + if (saveValueNeeded) { + if (this.saveValueVariable != null) { + this.saveValueVariable.useFlag = LocalVariableBinding.USED; + } + } else { + this.saveValueVariable = null; + if ((!isSynchronized) && (expressionType == BooleanBinding)) { + this.expression.bits |= ValueForReturnMASK; + } + } + return FlowInfo.DEAD_END; +} + +/** + * Retrun statement code generation + * + * generate the finallyInvocationSequence. + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +//public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// // generate the expression +// if ((expression != null) && (expression.constant == NotAConstant)) { +// expression.generateCode(currentScope, codeStream, needValue()); // no value needed if non-returning subroutine +// generateStoreSaveValueIfNecessary(codeStream); +// } +// +// // generation of code responsible for invoking the finally blocks in sequence +// if (subroutines != null) { +// for (int i = 0, max = subroutines.length; i < max; i++) { +// AstNode sub; +// if ((sub = subroutines[i]) instanceof SynchronizedStatement) { +// codeStream.load(((SynchronizedStatement) sub).synchroVariable); +// codeStream.monitorexit(); +// } else { +// TryStatement trySub = (TryStatement) sub; +// if (trySub.subRoutineCannotReturn) { +// codeStream.goto_(trySub.subRoutineStartLabel); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// return; +// } else { +// codeStream.jsr(trySub.subRoutineStartLabel); +// } +// } +// } +// } +// if (saveValueVariable != null) codeStream.load(saveValueVariable); +// +// if ((expression != null) && (expression.constant != NotAConstant)) { +// codeStream.generateConstant(expression.constant, expression.implicitConversion); +// generateStoreSaveValueIfNecessary(codeStream); +// } +// // output the suitable return bytecode or wrap the value inside a descriptor for doits +// this.generateReturnBytecode(codeStream); +// +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +/** + * Dump the suitable return bytecode for a return statement + * + */ +//public void generateReturnBytecode(CodeStream codeStream) { +// +// if (expression == null) { +// codeStream.return_(); +// } else { +// switch (expression.implicitConversion >> 4) { +// case T_boolean : +// case T_int : +// codeStream.ireturn(); +// break; +// case T_float : +// codeStream.freturn(); +// break; +// case T_long : +// codeStream.lreturn(); +// break; +// case T_double : +// codeStream.dreturn(); +// break; +// default : +// codeStream.areturn(); +// } +// } +//} +//public void generateStoreSaveValueIfNecessary(CodeStream codeStream){ +// if (saveValueVariable != null) codeStream.store(saveValueVariable, false); +//} +public boolean needValue(){ + return (subroutines == null) || (saveValueVariable != null) || isSynchronized; +} +public void prepareSaveValueLocation(TryStatement targetTryStatement){ + + this.saveValueVariable = targetTryStatement.secretReturnValue; +} +public void resolve(BlockScope scope) { + MethodScope methodScope = scope.methodScope(); + MethodBinding methodBinding; + TypeBinding methodType = + (methodScope.referenceContext instanceof AbstractMethodDeclaration) + ? ((methodBinding = ((AbstractMethodDeclaration) methodScope.referenceContext).binding) == null + ? null + : methodBinding.returnType) + : VoidBinding; + if (methodType == VoidBinding) { + // the expression should be null + if (expression == null) + return; + if ((expressionType = expression.resolveType(scope)) != null) + scope.problemReporter().attemptToReturnNonVoidExpression(this, expressionType); + return; + } + if (expression == null) { + if (methodType != null) scope.problemReporter().shouldReturn(methodType, this); + return; + } + if ((expressionType = expression.resolveType(scope)) == null) + return; + + if (methodType != null && expression.isConstantValueOfTypeAssignableToType(expressionType, methodType)) { + // dealing with constant + expression.implicitWidening(methodType, expressionType); + return; + } + if (expressionType == VoidBinding) { + scope.problemReporter().attemptToReturnVoidValue(this); + return; + } + if (methodType != null && expressionType.isCompatibleWith(methodType)) { + expression.implicitWidening(methodType, expressionType); + return; + } + if (methodType != null){ + scope.problemReporter().typeMismatchErrorActualTypeExpectedType(expression, expressionType, methodType); + } +} +public String toString(int tab){ + + String s = tabString(tab) ; + s = s + "return "; //$NON-NLS-1$ + if (expression != null ) + s = s + expression.toStringExpression() ; + return s; +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + if (visitor.visit(this, scope)) { + if (expression != null) + expression.traverse(visitor, scope); + } + visitor.endVisit(this, scope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SingleNameReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SingleNameReference.java new file mode 100644 index 0000000..175cd27 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SingleNameReference.java @@ -0,0 +1,674 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ProblemFieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ProblemReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding; + +public class SingleNameReference extends NameReference implements OperatorIds { + public char[] token; + + public MethodBinding[] syntheticAccessors; // [0]=read accessor [1]=write accessor + public static final int READ = 0; + public static final int WRITE = 1; + +public SingleNameReference(char[] source, long pos) { + super(); + token = source; + sourceStart = (int) (pos >>> 32); + sourceEnd = (int) pos; +} +public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) { + + // compound assignment extra work + if (isCompound) { // check the variable part is initialized if blank final + switch (bits & RestrictiveFlagMASK) { + case FIELD : // reading a field + FieldBinding fieldBinding; + if ((fieldBinding = (FieldBinding) binding).isBlankFinal() + && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) { + if (!flowInfo.isDefinitelyAssigned(fieldBinding)) { + currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this); + } + } + manageSyntheticReadAccessIfNecessary(currentScope); + break; + case LOCAL : // reading a local variable + // check if assigning a final blank field + LocalVariableBinding localBinding; + if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) binding)) { + currentScope.problemReporter().uninitializedLocalVariable(localBinding, this); + // we could improve error msg here telling "cannot use compound assignment on final local variable" + } + if (flowInfo.isReachable()) { + localBinding.useFlag = LocalVariableBinding.USED; + } else if (localBinding.useFlag == LocalVariableBinding.UNUSED) { + localBinding.useFlag = LocalVariableBinding.FAKE_USED; + } + } + } + if (assignment.expression != null) { + flowInfo = assignment.expression.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits(); + } + switch (bits & RestrictiveFlagMASK) { + case FIELD : // assigning to a field + manageSyntheticWriteAccessIfNecessary(currentScope); + + // check if assigning a final field + FieldBinding fieldBinding; + if ((fieldBinding = (FieldBinding) binding).isFinal()) { + // inside a context where allowed + if (!isCompound && fieldBinding.isBlankFinal() && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) { + if (flowInfo.isPotentiallyAssigned(fieldBinding)) { + currentScope.problemReporter().duplicateInitializationOfBlankFinalField(fieldBinding, this); + } else { + flowContext.recordSettingFinal(fieldBinding, this); + } + flowInfo.markAsDefinitelyAssigned(fieldBinding); + } else { + currentScope.problemReporter().cannotAssignToFinalField(fieldBinding, this); + } + } + break; + case LOCAL : // assigning to a local variable + LocalVariableBinding localBinding = (LocalVariableBinding) binding; + if (!flowInfo.isDefinitelyAssigned(localBinding)){// for local variable debug attributes + bits |= FirstAssignmentToLocalMASK; + } else { + bits &= ~FirstAssignmentToLocalMASK; + } + if (localBinding.isFinal()) { + if ((bits & DepthMASK) == 0) { + if (isCompound || !localBinding.isBlankFinal()){ + currentScope.problemReporter().cannotAssignToFinalLocal(localBinding, this); + } else if (flowInfo.isPotentiallyAssigned(localBinding)) { + currentScope.problemReporter().duplicateInitializationOfFinalLocal(localBinding, this); + } else { + flowContext.recordSettingFinal(localBinding, this); + } + } else { + currentScope.problemReporter().cannotAssignToFinalOuterLocal(localBinding, this); + } + } + flowInfo.markAsDefinitelyAssigned(localBinding); + } + manageEnclosingInstanceAccessIfNecessary(currentScope); + return flowInfo; +} +public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { + return analyseCode(currentScope, flowContext, flowInfo, true); +} +public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) { + + switch (bits & RestrictiveFlagMASK) { + case FIELD : // reading a field + if (valueRequired) { + manageSyntheticReadAccessIfNecessary(currentScope); + } + // check if reading a final blank field + FieldBinding fieldBinding; + if ((fieldBinding = (FieldBinding) binding).isBlankFinal() + && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) { + if (!flowInfo.isDefinitelyAssigned(fieldBinding)) { + currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this); + } + } + break; + case LOCAL : // reading a local variable + LocalVariableBinding localBinding; + if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) binding)) { + currentScope.problemReporter().uninitializedLocalVariable(localBinding, this); + } + if (flowInfo.isReachable()) { + localBinding.useFlag = LocalVariableBinding.USED; + } else if (localBinding.useFlag == LocalVariableBinding.UNUSED) { + localBinding.useFlag = LocalVariableBinding.FAKE_USED; + } + } + if (valueRequired) { + manageEnclosingInstanceAccessIfNecessary(currentScope); + } + return flowInfo; +} +public TypeBinding checkFieldAccess(BlockScope scope) { + + FieldBinding fieldBinding = (FieldBinding) binding; + + bits &= ~RestrictiveFlagMASK; // clear bits + bits |= FIELD; + if (!((FieldBinding) binding).isStatic()) { + // must check for the static status.... + if (scope.methodScope().isStatic) { + scope.problemReporter().staticFieldAccessToNonStaticVariable(this, fieldBinding); + constant = NotAConstant; + return fieldBinding.type; + } + } + constant = FieldReference.getConstantFor(fieldBinding, this, true, scope); + + if (isFieldUseDeprecated(fieldBinding, scope)) + scope.problemReporter().deprecatedField(fieldBinding, this); + + MethodScope ms = scope.methodScope(); + if ((this.bits & IsStrictlyAssignedMASK) == 0 + && ms.enclosingSourceType() == fieldBinding.declaringClass + && ms.fieldDeclarationIndex != MethodScope.NotInFieldDecl + && fieldBinding.id >= ms.fieldDeclarationIndex) { + //if the field is static and ms is not .... then it is valid + if (!fieldBinding.isStatic() || ms.isStatic) + scope.problemReporter().forwardReference(this, 0, scope.enclosingSourceType()); + } + //==================================================== + + return fieldBinding.type; + +} +//public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) { +// +// // optimizing assignment like: i = i + 1 or i = 1 + i +// if (assignment.expression.isCompactableOperation()) { +// BinaryExpression operation = (BinaryExpression) assignment.expression; +// SingleNameReference variableReference; +// if ((operation.left instanceof SingleNameReference) && ((variableReference = (SingleNameReference) operation.left).binding == binding)) { +// // i = i + value, then use the variable on the right hand side, since it has the correct implicit conversion +// variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.right, (operation.bits & OperatorMASK) >> OperatorSHIFT, operation.left.implicitConversion /*should be equivalent to no conversion*/, valueRequired); +// return; +// } +// int operator = (operation.bits & OperatorMASK) >> OperatorSHIFT; +// if ((operation.right instanceof SingleNameReference) +// && ((operator == PLUS) || (operator == MULTIPLY)) // only commutative operations +// && ((variableReference = (SingleNameReference) operation.right).binding == binding) +// && (operation.left.constant != NotAConstant) // exclude non constant expressions, since could have side-effect +// && ((operation.left.implicitConversion >> 4) != T_String) // exclude string concatenation which would occur backwards +// && ((operation.right.implicitConversion >> 4) != T_String)) { // exclude string concatenation which would occur backwards +// // i = value + i, then use the variable on the right hand side, since it has the correct implicit conversion +// variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.left, operator, operation.right.implicitConversion /*should be equivalent to no conversion*/, valueRequired); +// return; +// } +// } +// switch (bits & RestrictiveFlagMASK) { +// case FIELD : // assigning to a field +// FieldBinding fieldBinding; +// if (!(fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) { // need a receiver? +// if ((bits & DepthMASK) != 0) { +// ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT); +// Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/); +// codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope); +// } else { +// this.generateReceiver(codeStream); +// } +// } +// assignment.expression.generateCode(currentScope, codeStream, true); +// fieldStore(codeStream, fieldBinding, syntheticAccessors == null ? null : syntheticAccessors[WRITE], valueRequired); +// if (valueRequired) { +// codeStream.generateImplicitConversion(assignment.implicitConversion); +// } +// return; +// case LOCAL : // assigning to a local variable +// LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; +// if (localBinding.resolvedPosition != -1) { +// assignment.expression.generateCode(currentScope, codeStream, true); +// } else { +// if (assignment.expression.constant != NotAConstant) { +// // assigning an unused local to a constant value = no actual assignment is necessary +// if (valueRequired) { +// codeStream.generateConstant(assignment.expression.constant, assignment.implicitConversion); +// } +// } else { +// assignment.expression.generateCode(currentScope, codeStream, true); +// /* Even though the value may not be required, we force it to be produced, and discard it later +// on if it was actually not necessary, so as to provide the same behavior as JDK1.2beta3. */ +// if (valueRequired) { +// codeStream.generateImplicitConversion(assignment.implicitConversion); // implicit conversion +// } else { +// if ((localBinding.type == LongBinding) || (localBinding.type == DoubleBinding)) { +// codeStream.pop2(); +// } else { +// codeStream.pop(); +// } +// } +// } +// return; +// } +// // 26903, need extra cast to store null in array local var +// if (localBinding.type.isArrayType() +// && (assignment.expression.resolvedType == NullBinding // arrayLoc = null +// || ((assignment.expression instanceof CastExpression) // arrayLoc = (type[])null +// && (((CastExpression)assignment.expression).innermostCastedExpression().resolvedType == NullBinding)))){ +// codeStream.checkcast(localBinding.type); +// } +// +// // normal local assignment (since cannot store in outer local which are final locations) +// codeStream.store(localBinding, valueRequired); +// if ((bits & FirstAssignmentToLocalMASK) != 0) { // for local variable debug attributes +// localBinding.recordInitializationStartPC(codeStream.position); +// } +// // implicit conversion +// if (valueRequired) { +// codeStream.generateImplicitConversion(assignment.implicitConversion); +// } +// } +//} +//public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { +// int pc = codeStream.position; +// if (constant != NotAConstant) { +// if (valueRequired) { +// codeStream.generateConstant(constant, implicitConversion); +// } +// } else { +// switch (bits & RestrictiveFlagMASK) { +// case FIELD : // reading a field +// FieldBinding fieldBinding; +// if (valueRequired) { +// if ((fieldBinding = (FieldBinding) this.codegenBinding).constant == NotAConstant) { // directly use inlined value for constant fields +// boolean isStatic; +// if (!(isStatic = fieldBinding.isStatic())) { +// if ((bits & DepthMASK) != 0) { +// ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT); +// Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/); +// codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope); +// } else { +// generateReceiver(codeStream); +// } +// } +// // managing private access +// if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) { +// if (isStatic) { +// codeStream.getstatic(fieldBinding); +// } else { +// codeStream.getfield(fieldBinding); +// } +// } else { +// codeStream.invokestatic(syntheticAccessors[READ]); +// } +// codeStream.generateImplicitConversion(implicitConversion); +// } else { // directly use the inlined value +// codeStream.generateConstant(fieldBinding.constant, implicitConversion); +// } +// } +// break; +// case LOCAL : // reading a local +// LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; +// if (valueRequired) { +// // outer local? +// if ((bits & DepthMASK) != 0) { +// // outer local can be reached either through a synthetic arg or a synthetic field +// VariableBinding[] path = currentScope.getEmulationPath(localBinding); +// codeStream.generateOuterAccess(path, this, localBinding, currentScope); +// } else { +// // regular local variable read +// codeStream.load(localBinding); +// } +// codeStream.generateImplicitConversion(implicitConversion); +// } +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +///* +// * Regular API for compound assignment, relies on the fact that there is only one reference to the +// * variable, which carries both synthetic read/write accessors. +// * The APIs with an extra argument is used whenever there are two references to the same variable which +// * are optimized in one access: e.g "a = a + 1" optimized into "a++". +// */ +//public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { +// +// this.generateCompoundAssignment( +// currentScope, +// codeStream, +// syntheticAccessors == null ? null : syntheticAccessors[WRITE], +// expression, +// operator, +// assignmentImplicitConversion, +// valueRequired); +//} +///* +// * The APIs with an extra argument is used whenever there are two references to the same variable which +// * are optimized in one access: e.g "a = a + 1" optimized into "a++". +// */ +//public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, MethodBinding writeAccessor, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { +// switch (bits & RestrictiveFlagMASK) { +// case FIELD : // assigning to a field +// FieldBinding fieldBinding; +// if ((fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) { +// if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) { +// codeStream.getstatic(fieldBinding); +// } else { +// codeStream.invokestatic(syntheticAccessors[READ]); +// } +// } else { +// if ((bits & DepthMASK) != 0) { +// ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT); +// Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/); +// codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope); +// } else { +// codeStream.aload_0(); +// } +// codeStream.dup(); +// if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) { +// codeStream.getfield(fieldBinding); +// } else { +// codeStream.invokestatic(syntheticAccessors[READ]); +// } +// } +// break; +// case LOCAL : // assigning to a local variable (cannot assign to outer local) +// LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; +// Constant assignConstant; +// int increment; +// // using incr bytecode if possible +// switch (localBinding.type.id) { +// case T_String : +// codeStream.generateStringAppend(currentScope, this, expression); +// if (valueRequired) { +// codeStream.dup(); +// } +// codeStream.store(localBinding, false); +// return; +// case T_int : +// if (((assignConstant = expression.constant) != NotAConstant) +// && (assignConstant.typeID() != T_float) // only for integral types +// && (assignConstant.typeID() != T_double) +// && ((increment = assignConstant.intValue()) == (short) increment)) { // 16 bits value +// switch (operator) { +// case PLUS : +// codeStream.iinc(localBinding.resolvedPosition, increment); +// if (valueRequired) { +// codeStream.load(localBinding); +// } +// return; +// case MINUS : +// codeStream.iinc(localBinding.resolvedPosition, -increment); +// if (valueRequired) { +// codeStream.load(localBinding); +// } +// return; +// } +// } +// default : +// codeStream.load(localBinding); +// } +// } +// // perform the actual compound operation +// int operationTypeID; +// if ((operationTypeID = implicitConversion >> 4) == T_String || operationTypeID == T_Object) { +// // we enter here if the single name reference is a field of type java.lang.String or if the type of the +// // operation is java.lang.Object +// // For example: o = o + ""; // where the compiled type of o is java.lang.Object. +// codeStream.generateStringAppend(currentScope, null, expression); +// } else { +// // promote the array reference to the suitable operation type +// codeStream.generateImplicitConversion(implicitConversion); +// // generate the increment value (will by itself be promoted to the operation value) +// if (expression == IntLiteral.One){ // prefix operation +// codeStream.generateConstant(expression.constant, implicitConversion); +// } else { +// expression.generateCode(currentScope, codeStream, true); +// } +// // perform the operation +// codeStream.sendOperator(operator, operationTypeID); +// // cast the value back to the array reference type +// codeStream.generateImplicitConversion(assignmentImplicitConversion); +// } +// // store the result back into the variable +// switch (bits & RestrictiveFlagMASK) { +// case FIELD : // assigning to a field +// fieldStore(codeStream, (FieldBinding) this.codegenBinding, writeAccessor, valueRequired); +// return; +// case LOCAL : // assigning to a local variable +// LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; +// if (valueRequired) { +// if ((localBinding.type == LongBinding) || (localBinding.type == DoubleBinding)) { +// codeStream.dup2(); +// } else { +// codeStream.dup(); +// } +// } +// codeStream.store(localBinding, false); +// } +//} +//public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) { +// switch (bits & RestrictiveFlagMASK) { +// case FIELD : // assigning to a field +// FieldBinding fieldBinding; +// if ((fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) { +// if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) { +// codeStream.getstatic(fieldBinding); +// } else { +// codeStream.invokestatic(syntheticAccessors[READ]); +// } +// } else { +// if ((bits & DepthMASK) != 0) { +// ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT); +// Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/); +// codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope); +// } else { +// codeStream.aload_0(); +// } +// codeStream.dup(); +// if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) { +// codeStream.getfield(fieldBinding); +// } else { +// codeStream.invokestatic(syntheticAccessors[READ]); +// } +// } +// if (valueRequired) { +// if (fieldBinding.isStatic()) { +// if ((fieldBinding.type == LongBinding) || (fieldBinding.type == DoubleBinding)) { +// codeStream.dup2(); +// } else { +// codeStream.dup(); +// } +// } else { // Stack: [owner][old field value] ---> [old field value][owner][old field value] +// if ((fieldBinding.type == LongBinding) || (fieldBinding.type == DoubleBinding)) { +// codeStream.dup2_x1(); +// } else { +// codeStream.dup_x1(); +// } +// } +// } +// codeStream.generateConstant(postIncrement.expression.constant, implicitConversion); +// codeStream.sendOperator(postIncrement.operator, fieldBinding.type.id); +// codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion); +// fieldStore(codeStream, fieldBinding, syntheticAccessors == null ? null : syntheticAccessors[WRITE], false); +// return; +// case LOCAL : // assigning to a local variable +// LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; +// // using incr bytecode if possible +// if (localBinding.type == IntBinding) { +// if (valueRequired) { +// codeStream.load(localBinding); +// } +// if (postIncrement.operator == PLUS) { +// codeStream.iinc(localBinding.resolvedPosition, 1); +// } else { +// codeStream.iinc(localBinding.resolvedPosition, -1); +// } +// } else { +// codeStream.load(localBinding); +// if (valueRequired){ +// if ((localBinding.type == LongBinding) || (localBinding.type == DoubleBinding)) { +// codeStream.dup2(); +// } else { +// codeStream.dup(); +// } +// } +// codeStream.generateConstant(postIncrement.expression.constant, implicitConversion); +// codeStream.sendOperator(postIncrement.operator, localBinding.type.id); +// codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion); +// +// codeStream.store(localBinding, false); +// } +// } +//} +//public void generateReceiver(CodeStream codeStream) { +// codeStream.aload_0(); +//} +public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) { + + //If inlinable field, forget the access emulation, the code gen will directly target it + if (((bits & DepthMASK) == 0) || (constant != NotAConstant)) return; + + if ((bits & RestrictiveFlagMASK) == LOCAL) { + currentScope.emulateOuterAccess((LocalVariableBinding) binding); + } +} +public void manageSyntheticReadAccessIfNecessary(BlockScope currentScope) { + + //If inlinable field, forget the access emulation, the code gen will directly target it + if (constant != NotAConstant) + return; + + if ((bits & FIELD) != 0) { + FieldBinding fieldBinding = (FieldBinding) binding; + if (((bits & DepthMASK) != 0) + && (fieldBinding.isPrivate() // private access + || (fieldBinding.isProtected() // implicit protected access + && fieldBinding.declaringClass.getPackage() + != currentScope.enclosingSourceType().getPackage()))) { + if (syntheticAccessors == null) + syntheticAccessors = new MethodBinding[2]; + syntheticAccessors[READ] = + ((SourceTypeBinding)currentScope.enclosingSourceType(). + enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT)). + addSyntheticMethod(fieldBinding, true); + currentScope.problemReporter().needToEmulateFieldReadAccess(fieldBinding, this); + return; + } + // if the binding declaring class is not visible, need special action + // for runtime compatibility on 1.2 VMs : change the declaring class of the binding + // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type + // and not from Object or implicit static field access. +// if (fieldBinding.declaringClass != this.actualReceiverType +// && !this.actualReceiverType.isArrayType() +// && fieldBinding.declaringClass != null +// && fieldBinding.constant == NotAConstant +// && ((currentScope.environment().options.targetJDK >= CompilerOptions.JDK1_2 +// && !fieldBinding.isStatic() +// && fieldBinding.declaringClass.id != T_Object) // no change for Object fields (if there was any) +// || !fieldBinding.declaringClass.canBeSeenBy(currentScope))){ +// this.codegenBinding = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)this.actualReceiverType); +// } + } +} +public void manageSyntheticWriteAccessIfNecessary(BlockScope currentScope) { + + if ((bits & FIELD) != 0) { + FieldBinding fieldBinding = (FieldBinding) binding; + if (((bits & DepthMASK) != 0) + && (fieldBinding.isPrivate() // private access + || (fieldBinding.isProtected() // implicit protected access + && fieldBinding.declaringClass.getPackage() + != currentScope.enclosingSourceType().getPackage()))) { + if (syntheticAccessors == null) + syntheticAccessors = new MethodBinding[2]; + syntheticAccessors[WRITE] = + ((SourceTypeBinding)currentScope.enclosingSourceType(). + enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT)). + addSyntheticMethod(fieldBinding, false); + currentScope.problemReporter().needToEmulateFieldWriteAccess(fieldBinding, this); + return; + } + // if the binding declaring class is not visible, need special action + // for runtime compatibility on 1.2 VMs : change the declaring class of the binding + // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type + // and not from Object or implicit static field access. +// if (fieldBinding.declaringClass != this.actualReceiverType +// && !this.actualReceiverType.isArrayType() +// && fieldBinding.declaringClass != null +// && fieldBinding.constant == NotAConstant +// && ((currentScope.environment().options.targetJDK >= CompilerOptions.JDK1_2 +// && !fieldBinding.isStatic() +// && fieldBinding.declaringClass.id != T_Object) // no change for Object fields (if there was any) +// || !fieldBinding.declaringClass.canBeSeenBy(currentScope))){ +// this.codegenBinding = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)this.actualReceiverType); +// } + } +} +public TypeBinding reportError(BlockScope scope) { + //=====error cases======= + constant = Constant.NotAConstant; + if (binding instanceof ProblemFieldBinding) { + scope.problemReporter().invalidField(this, (FieldBinding) binding); + } else if (binding instanceof ProblemReferenceBinding) { + scope.problemReporter().invalidType(this, (TypeBinding) binding); + } else { + scope.problemReporter().unresolvableReference(this, binding); + } + return null; +} +public TypeBinding resolveType(BlockScope scope) { + // for code gen, harm the restrictiveFlag + + this.actualReceiverType = this.receiverType = scope.enclosingSourceType(); + + if ((this.codegenBinding = this.binding = scope.getBinding(token, bits & RestrictiveFlagMASK, this)).isValidBinding()) { + switch (bits & RestrictiveFlagMASK) { + case VARIABLE : // =========only variable============ + case VARIABLE | TYPE : //====both variable and type============ + if (binding instanceof VariableBinding) { + VariableBinding variable = (VariableBinding) binding; + if (binding instanceof LocalVariableBinding) { + bits &= ~RestrictiveFlagMASK; // clear bits + bits |= LOCAL; + if ((this.bits & IsStrictlyAssignedMASK) == 0) { + constant = variable.constant; + } else { + constant = NotAConstant; + } + if ((!variable.isFinal()) && ((bits & DepthMASK) != 0)) { + scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding)variable, this); + } + return this.resolvedType = variable.type; + } + // a field + return this.resolvedType = checkFieldAccess(scope); + } + + // thus it was a type + bits &= ~RestrictiveFlagMASK; // clear bits + bits |= TYPE; + case TYPE : //========only type============== + constant = Constant.NotAConstant; + //deprecated test + if (isTypeUseDeprecated((TypeBinding) binding, scope)) + scope.problemReporter().deprecatedType((TypeBinding) binding, this); + return this.resolvedType = (TypeBinding) binding; + } + } + + // error scenarii + return this.resolvedType = this.reportError(scope); +} +public String toStringExpression(){ + + return new String(token);} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); +} +public String unboundReferenceErrorName(){ + + return new String(token);} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SingleTypeReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SingleTypeReference.java new file mode 100644 index 0000000..c50e83b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SingleTypeReference.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.Scope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class SingleTypeReference extends TypeReference { + public char[] token; + + +public SingleTypeReference(char[] source, long pos) { + token = source; + sourceStart = (int) (pos>>>32) ; + sourceEnd = (int) (pos & 0x00000000FFFFFFFFL) ; + +} +public SingleTypeReference(char[] source ,TypeBinding type, long pos) { + this(source, pos) ; + this.resolvedType = type ; +} +public TypeReference copyDims(int dim){ + //return a type reference copy of me with some dimensions + //warning : the new type ref has a null binding + + return new ArrayTypeReference(token,null,dim,(((long)sourceStart)<<32)+sourceEnd) ; +} +public TypeBinding getTypeBinding(Scope scope) { + if (this.resolvedType != null) + return this.resolvedType; + return scope.getType(token); +} +public char [][] getTypeName() { + return new char[][] { token }; +} +public TypeBinding resolveTypeEnclosing(BlockScope scope, ReferenceBinding enclosingType) { + ReferenceBinding memberTb = scope.getMemberType(token, enclosingType); + if (!memberTb.isValidBinding()) { + scope.problemReporter().invalidEnclosingType(this, memberTb, enclosingType); + return null; + } + if (isTypeUseDeprecated(memberTb, scope)) + scope.problemReporter().deprecatedType(memberTb, this); + return this.resolvedType = memberTb; +} +public String toStringExpression(int tab){ + return new String(token) ; +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Statement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Statement.java new file mode 100644 index 0000000..b767e9d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/Statement.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public abstract class Statement extends AstNode { + + /** + * Statement constructor comment. + */ + public Statement() { + super(); + } + + public abstract FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo); + +// public abstract void generateCode(BlockScope currentScope, CodeStream codeStream); + + public boolean isEmptyBlock() { + return false; + } + + public boolean isValidJavaStatement() { + //the use of this method should be avoid in most cases + //and is here mostly for documentation purpose..... + //while the parser is responsable for creating + //welled formed expression statement, which results + //in the fact that java-non-semantic-expression-used-as-statement + //should not be parsable...thus not being built. + //It sounds like the java grammar as help the compiler job in removing + //-by construction- some statement that would have no effect.... + //(for example all expression that may do side-effects are valid statement + // -this is an appromative idea.....-) + + return true; + } + + public abstract void resolve(BlockScope scope); + + public Constant resolveCase(BlockScope scope, TypeBinding testType, SwitchStatement switchStatement) { + // statement within a switch that are not case are treated as normal statement.... + + resolve(scope); + return null; + } + + public void resetStateForCodeGeneration() { + } + + /** + * INTERNAL USE ONLY. + * Do nothing by default. This is used to redirect inter-statements jumps. + */ + public void branchChainTo(Label label) { + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/StringLiteral.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/StringLiteral.java new file mode 100644 index 0000000..a77ef11 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/StringLiteral.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public class StringLiteral extends Literal { + + char[] source; + + public StringLiteral(char[] token, int s, int e) { + + this(s,e); + source = token; + } + + public StringLiteral(int s, int e) { + + super(s,e); + } + + public void computeConstant() { + + constant = Constant.fromValue(String.valueOf(source)); + } + + public ExtendedStringLiteral extendWith(CharLiteral lit){ + + //add the lit source to mine, just as if it was mine + return new ExtendedStringLiteral(this,lit); + } + + public ExtendedStringLiteral extendWith(StringLiteral lit){ + + //add the lit source to mine, just as if it was mine + return new ExtendedStringLiteral(this,lit); + } + + /** + * Code generation for string literal + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { +// +// int pc = codeStream.position; +// if (valueRequired) +// codeStream.ldc(constant.stringValue()); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public TypeBinding literalType(BlockScope scope) { + + return scope.getJavaLangString(); + } + + public char[] source() { + + return source; + } + + public String toStringExpression() { + + // handle some special char..... + StringBuffer result = new StringBuffer("\""); //$NON-NLS-1$ + for (int i = 0; i < source.length; i++) { + switch (source[i]) { + case '\b' : + result.append("\\b"); //$NON-NLS-1$ + break; + case '\t' : + result.append("\\t"); //$NON-NLS-1$ + break; + case '\n' : + result.append("\\n"); //$NON-NLS-1$ + break; + case '\f' : + result.append("\\f"); //$NON-NLS-1$ + break; + case '\r' : + result.append("\\r"); //$NON-NLS-1$ + break; + case '\"' : + result.append("\\\""); //$NON-NLS-1$ + break; + case '\'' : + result.append("\\'"); //$NON-NLS-1$ + break; + case '\\' : //take care not to display the escape as a potential real char + result.append("\\\\"); //$NON-NLS-1$ + break; + default : + result.append(source[i]); + } + } + result.append("\""); //$NON-NLS-1$ + return result.toString(); + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SuperReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SuperReference.java new file mode 100644 index 0000000..0eb6261 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SuperReference.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class SuperReference extends ThisReference { + +public SuperReference(int sourceStart, int sourceEnd) { + super(sourceStart, sourceEnd); +} +public static ExplicitConstructorCall implicitSuperConstructorCall() { + return new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper); +} +public boolean isImplicitThis() { + + return false; +} +public boolean isSuper() { + + return true; +} +public boolean isThis() { + + return false ; +} +public TypeBinding resolveType(BlockScope scope) { + constant = NotAConstant; + if (!checkAccess(scope.methodScope())) + return null; + SourceTypeBinding enclosingTb = scope.enclosingSourceType(); + if (scope.isJavaLangObject(enclosingTb)) { + scope.problemReporter().cannotUseSuperInJavaLangObject(this); + return null; + } + return this.resolvedType = enclosingTb.superclass; +} +public String toStringExpression(){ + + return "super"; //$NON-NLS-1$ + +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) { + visitor.visit(this, blockScope); + visitor.endVisit(this, blockScope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SwitchStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SwitchStatement.java new file mode 100644 index 0000000..ddc5514 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SwitchStatement.java @@ -0,0 +1,326 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.SwitchFlowContext; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class SwitchStatement extends Statement { + public Expression testExpression; + public Statement[] statements; + public BlockScope scope; + public int explicitDeclarations; + public Label breakLabel; + public Case[] cases; + public DefaultCase defaultCase; + public int caseCount = 0; + + // for local variables table attributes + int preSwitchInitStateIndex = -1; + int mergedInitStateIndex = -1; + /** + * SwitchStatement constructor comment. + */ + public SwitchStatement() { + super(); + } + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + flowInfo = testExpression.analyseCode(currentScope, flowContext, flowInfo); + SwitchFlowContext switchContext = + new SwitchFlowContext(flowContext, this, (breakLabel = new Label())); + + // analyse the block by considering specially the case/default statements (need to bind them + // to the entry point) + FlowInfo caseInits = FlowInfo.DEAD_END; + // in case of statements before the first case + preSwitchInitStateIndex = + currentScope.methodScope().recordInitializationStates(flowInfo); + int caseIndex = 0; + if (statements != null) { + boolean didAlreadyComplain = false; + for (int i = 0, max = statements.length; i < max; i++) { + Statement statement = statements[i]; + if ((caseIndex < caseCount) && (statement == cases[caseIndex])) { // statement is a case + caseIndex++; + caseInits = caseInits.mergedWith(flowInfo.copy().unconditionalInits()); + didAlreadyComplain = false; // reset complaint + } else if (statement == defaultCase) { // statement is the default case + caseInits = caseInits.mergedWith(flowInfo.copy().unconditionalInits()); + didAlreadyComplain = false; // reset complaint + } + if (!caseInits.complainIfUnreachable(statement, scope, didAlreadyComplain)) { + caseInits = statement.analyseCode(scope, switchContext, caseInits); + } else { + didAlreadyComplain = true; + } + } + } + + // if no default case, then record it may jump over the block directly to the end + if (defaultCase == null) { + // only retain the potential initializations + flowInfo.addPotentialInitializationsFrom( + caseInits.mergedWith(switchContext.initsOnBreak)); + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(flowInfo); + return flowInfo; + } + + // merge all branches inits + FlowInfo mergedInfo = caseInits.mergedWith(switchContext.initsOnBreak); + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(mergedInfo); + return mergedInfo; + } + /** + * Switch code generation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// int[] sortedIndexes = new int[caseCount]; +// int[] localKeysCopy; +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// +// // prepare the labels and constants +// breakLabel.codeStream = codeStream; +// CaseLabel[] caseLabels = new CaseLabel[caseCount]; +// int[] constants = new int[caseCount]; +// boolean needSwitch = caseCount != 0; +// for (int i = 0; i < caseCount; i++) { +// constants[i] = cases[i].constantExpression.constant.intValue(); +// cases[i].targetLabel = (caseLabels[i] = new CaseLabel(codeStream)); +// } +// +// // we sort the keys to be able to generate the code for tableswitch or lookupswitch +// for (int i = 0; i < caseCount; i++) { +// sortedIndexes[i] = i; +// } +// System.arraycopy( +// constants, +// 0, +// (localKeysCopy = new int[caseCount]), +// 0, +// caseCount); +// CodeStream.sort(localKeysCopy, 0, caseCount - 1, sortedIndexes); +// CaseLabel defaultLabel = new CaseLabel(codeStream); +// if (defaultCase != null) { +// defaultCase.targetLabel = defaultLabel; +// } +// // generate expression testes +// testExpression.generateCode(currentScope, codeStream, needSwitch); +// +// // generate the appropriate switch table/lookup bytecode +// if (needSwitch) { +// int max = localKeysCopy[caseCount - 1]; +// int min = localKeysCopy[0]; +// if ((long) (caseCount * 2.5) > ((long) max - (long) min)) { +// +// // work-around 1.3 VM bug, if max>0x7FFF0000, must use lookup bytecode +// // see http://dev.eclipse.org/bugs/show_bug.cgi?id=21557 +// if (max > 0x7FFF0000 && currentScope.environment().options.complianceLevel < CompilerOptions.JDK1_4) { +// codeStream.lookupswitch(defaultLabel, constants, sortedIndexes, caseLabels); +// +// } else { +// codeStream.tableswitch( +// defaultLabel, +// min, +// max, +// constants, +// sortedIndexes, +// caseLabels); +// } +// } else { +// codeStream.lookupswitch(defaultLabel, constants, sortedIndexes, caseLabels); +// } +// codeStream.updateLastRecordedEndPC(codeStream.position); +// } +// +// // generate the switch block statements +// int caseIndex = 0; +// if (statements != null) { +// for (int i = 0, maxCases = statements.length; i < maxCases; i++) { +// Statement statement = statements[i]; +// if ((caseIndex < caseCount) +// && (statement == cases[caseIndex])) { // statements[i] is a case +// if (preSwitchInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// preSwitchInitStateIndex); +// caseIndex++; +// } +// } else { +// if (statement == defaultCase) { // statements[i] is a case or a default case +// if (preSwitchInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// preSwitchInitStateIndex); +// } +// } +// } +// statement.generateCode(scope, codeStream); +// } +// } +// // place the trailing labels (for break and default case) +// breakLabel.place(); +// if (defaultCase == null) { +// defaultLabel.place(); +// } +// // May loose some local variable initializations : affecting the local variable attributes +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// codeStream.addDefinitelyAssignedVariables(currentScope, mergedInitStateIndex); +// } +// if (scope != currentScope) { +// codeStream.exitUserScope(scope); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + + public void resetStateForCodeGeneration() { + if (this.breakLabel != null) { + this.breakLabel.resetStateForCodeGeneration(); + } + } + + public void resolve(BlockScope upperScope) { + + TypeBinding testType = testExpression.resolveType(upperScope); + if (testType == null) + return; + testExpression.implicitWidening(testType, testType); + if (!(testExpression.isConstantValueOfTypeAssignableToType(testType, IntBinding))) { + if (!testType.isCompatibleWith(IntBinding)) { + upperScope.problemReporter().incorrectSwitchType(testExpression, testType); + return; + } + } + if (statements != null) { + scope = explicitDeclarations == 0 ? upperScope : new BlockScope(upperScope); + int length; + // collection of cases is too big but we will only iterate until caseCount + cases = new Case[length = statements.length]; + int[] casesValues = new int[length]; + int counter = 0; + for (int i = 0; i < length; i++) { + Constant cst; + if ((cst = statements[i].resolveCase(scope, testType, this)) != null) { + //----check for duplicate case statement------------ + if (cst != NotAConstant) { + int key = cst.intValue(); + for (int j = 0; j < counter; j++) { + if (casesValues[j] == key) { + scope.problemReporter().duplicateCase((Case) statements[i], cst); //TODO: (philippe) could improve diagnosis to indicate colliding case + } + } + casesValues[counter++] = key; + } + } + } + } + } + public String toString(int tab) { + + String inFront, s = tabString(tab); + inFront = s; + s = s + "switch (" + testExpression.toStringExpression() + ") "; //$NON-NLS-1$ //$NON-NLS-2$ + if (statements == null) { + s = s + "{}"; //$NON-NLS-1$ + return s; + } else + s = s + "{"; //$NON-NLS-1$ + s = s + + (explicitDeclarations != 0 + ? "// ---scope needed for " //$NON-NLS-1$ + + String.valueOf(explicitDeclarations) + + " locals------------ \n"//$NON-NLS-1$ + : "// ---NO scope needed------ \n"); //$NON-NLS-1$ + + int i = 0; + String tabulation = " "; //$NON-NLS-1$ + try { + while (true) { + //use instanceof in order not to polluate classes with behavior only needed for printing purpose. + if (statements[i] instanceof Expression) + s = s + "\n" + inFront + tabulation; //$NON-NLS-1$ + if (statements[i] instanceof Break) + s = s + statements[i].toString(0); + else + s = s + "\n" + statements[i].toString(tab + 2); //$NON-NLS-1$ + //============= + if ((statements[i] instanceof Case) + || (statements[i] instanceof DefaultCase)) { + i++; + while (!((statements[i] instanceof Case) + || (statements[i] instanceof DefaultCase))) { + if ((statements[i] instanceof Expression) || (statements[i] instanceof Break)) + s = s + statements[i].toString(0) + " ; "; //$NON-NLS-1$ + else + s = s + "\n" + statements[i].toString(tab + 6) + " ; "; //$NON-NLS-1$ //$NON-NLS-2$ + i++; + } + } else { + s = s + " ;"; //$NON-NLS-1$ + i++; + } + } + } catch (IndexOutOfBoundsException e) { + }; + s = s + "}"; //$NON-NLS-1$ + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + testExpression.traverse(visitor, scope); + if (statements != null) { + int statementsLength = statements.length; + for (int i = 0; i < statementsLength; i++) + statements[i].traverse(visitor, scope); + } + } + visitor.endVisit(this, blockScope); + } + + /** + * Dispatch the call on its last statement. + */ + public void branchChainTo(Label label) { + + // in order to improve debug attributes for stepping (11431) + // we want to inline the jumps to #breakLabel which already got + // generated (if any), and have them directly branch to a better + // location (the argument label). + // we know at this point that the breakLabel already got placed + if (this.breakLabel.hasForwardReferences()) { + label.appendForwardReferencesFrom(this.breakLabel); + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SynchronizedStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SynchronizedStatement.java new file mode 100644 index 0000000..cbe43d3 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/SynchronizedStatement.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.InsideSubRoutineFlowContext; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class SynchronizedStatement extends Statement { + + public Expression expression; + public Block block; + public BlockScope scope; + + boolean blockExit; + public LocalVariableBinding synchroVariable; + static final char[] SecretLocalDeclarationName = " syncValue".toCharArray(); //$NON-NLS-1$ + + public SynchronizedStatement( + Expression expression, + Block statement, + int s, + int e) { + + this.expression = expression; + this.block = statement; + sourceEnd = e; + sourceStart = s; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + // mark the synthetic variable as being used + synchroVariable.useFlag = LocalVariableBinding.USED; + + // simple propagation to subnodes + flowInfo = + block.analyseCode( + scope, + new InsideSubRoutineFlowContext(flowContext, this), + expression.analyseCode(scope, flowContext, flowInfo)); + + // optimizing code gen + this.blockExit = !flowInfo.isReachable(); + + return flowInfo; + } + + /** + * Synchronized statement code generation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// +// // generate the synchronization expression +// expression.generateCode(scope, codeStream, true); +// if (block.isEmptyBlock()) { +// if ((synchroVariable.type == LongBinding) +// || (synchroVariable.type == DoubleBinding)) { +// codeStream.dup2(); +// } else { +// codeStream.dup(); +// } +// // only take the lock +// codeStream.monitorenter(); +// codeStream.monitorexit(); +// } else { +// // enter the monitor +// codeStream.store(synchroVariable, true); +// codeStream.monitorenter(); +// +// // generate the body of the synchronized block +// ExceptionLabel anyExceptionHandler = new ExceptionLabel(codeStream, null); +// //'null' denotes any kind of exception +// block.generateCode(scope, codeStream); +// Label endLabel = new Label(codeStream); +// if (!blockExit) { +// codeStream.load(synchroVariable); +// codeStream.monitorexit(); +// codeStream.goto_(endLabel); +// } +// // generate the body of the exception handler +// anyExceptionHandler.placeEnd(); +// anyExceptionHandler.place(); +// codeStream.incrStackSize(1); +// codeStream.load(synchroVariable); +// codeStream.monitorexit(); +// codeStream.athrow(); +// if (!blockExit) { +// endLabel.place(); +// } +// } +// if (scope != currentScope) { +// codeStream.exitUserScope(scope); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public void resolve(BlockScope upperScope) { + + // special scope for secret locals optimization. + scope = new BlockScope(upperScope); + TypeBinding type = expression.resolveType(scope); + if (type == null) + return; + switch (type.id) { + case (T_boolean) : + case (T_char) : + case (T_float) : + case (T_double) : + case (T_byte) : + case (T_short) : + case (T_int) : + case (T_long) : + scope.problemReporter().invalidTypeToSynchronize(expression, type); + break; + case (T_void) : + scope.problemReporter().illegalVoidExpression(expression); + break; + case (T_null) : + scope.problemReporter().invalidNullToSynchronize(expression); + break; + } + //continue even on errors in order to have the TC done into the statements + synchroVariable = new LocalVariableBinding(SecretLocalDeclarationName, type, AccDefault, false); + scope.addLocalVariable(synchroVariable); + synchroVariable.constant = NotAConstant; // not inlinable + expression.implicitWidening(type, type); + block.resolveUsing(scope); + } + + public String toString(int tab) { + + String s = tabString(tab); + s = s + "synchronized (" + expression.toStringExpression() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + s = s + "\n" + block.toString(tab + 1); //$NON-NLS-1$ + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + expression.traverse(visitor, scope); + block.traverse(visitor, scope); + } + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ThisReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ThisReference.java new file mode 100644 index 0000000..d13353d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ThisReference.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class ThisReference extends Reference { + + public static ThisReference implicitThis(){ + + ThisReference implicitThis = new ThisReference(0, 0); + implicitThis.bits |= IsImplicitThisMask; + return implicitThis; + } + + public ThisReference(int sourceStart, int sourceEnd) { + + this.sourceStart = sourceStart; + this.sourceEnd = sourceEnd; + } + + /* + * @see Reference#analyseAssignment(...) + */ + public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) { + + return flowInfo; // this cannot be assigned + } + + public boolean checkAccess(MethodScope methodScope) { + + // this/super cannot be used in constructor call + if (methodScope.isConstructorCall) { + methodScope.problemReporter().fieldsOrThisBeforeConstructorInvocation(this); + return false; + } + + // static may not refer to this/super + if (methodScope.isStatic) { + methodScope.problemReporter().errorThisSuperInStatic(this); + return false; + } + return true; + } + + /* + * @see Reference#generateAssignment(...) + */ +// public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) { +// +// // this cannot be assigned +// } +// +// public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { +// +// int pc = codeStream.position; +// if (valueRequired) +// codeStream.aload_0(); +// if ((this.bits & IsImplicitThisMask) == 0) codeStream.recordPositionsFrom(pc, this.sourceStart); +// } +// +// /* +// * @see Reference#generateCompoundAssignment(...) +// */ +// public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { +// +// // this cannot be assigned +// } +// +// /* +// * @see org.eclipse.jdt.internal.compiler.ast.Reference#generatePostIncrement() +// */ +// public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) { +// +// // this cannot be assigned +// } + + public boolean isImplicitThis() { + + return (this.bits & IsImplicitThisMask) != 0; + } + + public boolean isThis() { + + return true ; + } + + public TypeBinding resolveType(BlockScope scope) { + + constant = NotAConstant; + if (!this.isImplicitThis() && !checkAccess(scope.methodScope())) + return null; + return this.resolvedType = scope.enclosingSourceType(); + } + + public String toStringExpression(){ + + if (this.isImplicitThis()) return "" ; //$NON-NLS-1$ + return "this"; //$NON-NLS-1$ + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) { + + visitor.visit(this, blockScope); + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ThrowStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ThrowStatement.java new file mode 100644 index 0000000..25aaa89 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/ThrowStatement.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class ThrowStatement extends Statement { + public Expression exception; + public TypeBinding exceptionType; + + public ThrowStatement(Expression exception, int startPosition) { + this.exception = exception; + this.sourceStart = startPosition; + this.sourceEnd = exception.sourceEnd; + } + + public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { + + exception.analyseCode(currentScope, flowContext, flowInfo); + // need to check that exception thrown is actually caught somewhere + flowContext.checkExceptionHandlers(exceptionType, this, flowInfo, currentScope); + return FlowInfo.DEAD_END; + } + + /** + * Throw code generation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) +// return; +// int pc = codeStream.position; +// exception.generateCode(currentScope, codeStream, true); +// codeStream.athrow(); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public void resolve(BlockScope scope) { + + exceptionType = exception.resolveTypeExpecting(scope, scope.getJavaLangThrowable()); + +// if (exceptionType == NullBinding +// && scope.environment().options.complianceLevel <= CompilerOptions.JDK1_3){ +// // if compliant with 1.4, this problem will not be reported +// scope.problemReporter().cannotThrowNull(this); +// } + exception.implicitWidening(exceptionType, exceptionType); + } + + public String toString(int tab) { + String s = tabString(tab); + s = s + "throw "; //$NON-NLS-1$ + s = s + exception.toStringExpression(); + return s; + } + + public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) { + if (visitor.visit(this, blockScope)) + exception.traverse(visitor, blockScope); + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/TrueLiteral.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/TrueLiteral.java new file mode 100644 index 0000000..07f7385 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/TrueLiteral.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public class TrueLiteral extends MagicLiteral { + static final char[] source = {'t' , 'r' , 'u' , 'e'}; +public TrueLiteral(int s , int e) { + super(s,e); +} +public void computeConstant() { + + constant = Constant.fromValue(true);} +/** + * Code generation for the true literal + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +//public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { +// int pc = codeStream.position; +// if (valueRequired) +// codeStream.iconst_1(); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +//public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) { +// +// // trueLabel being not nil means that we will not fall through into the TRUE case +// +// int pc = codeStream.position; +// // constant == true +// if (valueRequired) { +// if (falseLabel == null) { +// // implicit falling through the FALSE case +// if (trueLabel != null) { +// codeStream.goto_(trueLabel); +// } +// } +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +//} +public TypeBinding literalType(BlockScope scope) { + return BooleanBinding; +} +/** + * + */ +public char[] source() { + return source; +} +public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + visitor.visit(this, scope); + visitor.endVisit(this, scope); +} +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/TryStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/TryStatement.java new file mode 100644 index 0000000..8eca475 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/TryStatement.java @@ -0,0 +1,546 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.ExceptionHandlingFlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FinallyFlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.InsideSubRoutineFlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.UnconditionalFlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +public class TryStatement extends Statement { + + public Block tryBlock; + public Block[] catchBlocks; + public Argument[] catchArguments; + public Block finallyBlock; + BlockScope scope; + + public boolean subRoutineCannotReturn = true; + public UnconditionalFlowInfo subRoutineInits; + + // should rename into subRoutineComplete to be set to false by default + + ReferenceBinding[] caughtExceptionTypes; + boolean tryBlockExit; + boolean[] catchExits; + public int[] preserveExceptionHandler; + + Label subRoutineStartLabel; + public LocalVariableBinding anyExceptionVariable, + returnAddressVariable, + secretReturnValue; + + public final static char[] SecretReturnName = " returnAddress".toCharArray(); //$NON-NLS-1$ + public final static char[] SecretAnyHandlerName = " anyExceptionHandler".toCharArray(); //$NON-NLS-1$ + public static final char[] SecretLocalDeclarationName = " returnValue".toCharArray(); //$NON-NLS-1$ + + // for local variables table attributes + int preTryInitStateIndex = -1; + int mergedInitStateIndex = -1; + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + // Consider the try block and catch block so as to compute the intersection of initializations and + // the minimum exit relative depth amongst all of them. Then consider the subroutine, and append its + // initialization to the try/catch ones, if the subroutine completes normally. If the subroutine does not + // complete, then only keep this result for the rest of the analysis + + // process the finally block (subroutine) - create a context for the subroutine + + preTryInitStateIndex = + currentScope.methodScope().recordInitializationStates(flowInfo); + + if (anyExceptionVariable != null) { + anyExceptionVariable.useFlag = LocalVariableBinding.USED; + } + if (returnAddressVariable != null) { + returnAddressVariable.useFlag = LocalVariableBinding.USED; + } + InsideSubRoutineFlowContext insideSubContext; + FinallyFlowContext finallyContext; + UnconditionalFlowInfo subInfo; + if (subRoutineStartLabel == null) { + // no finally block + insideSubContext = null; + finallyContext = null; + subInfo = null; + } else { + // analyse finally block first + insideSubContext = new InsideSubRoutineFlowContext(flowContext, this); + subInfo = + finallyBlock + .analyseCode( + currentScope, + finallyContext = new FinallyFlowContext(flowContext, finallyBlock), + flowInfo.copy()) + .unconditionalInits(); + if (subInfo.isReachable()) { + subRoutineCannotReturn = false; + } + this.subRoutineInits = subInfo; + } + // process the try block in a context handling the local exceptions. + ExceptionHandlingFlowContext handlingContext = + new ExceptionHandlingFlowContext( + insideSubContext == null ? flowContext : insideSubContext, + tryBlock, + caughtExceptionTypes, + scope, + flowInfo.unconditionalInits()); + + FlowInfo tryInfo; + if (tryBlock.statements == null) { + tryInfo = flowInfo; + tryBlockExit = false; + } else { + tryInfo = tryBlock.analyseCode(currentScope, handlingContext, flowInfo.copy()); + tryBlockExit = !tryInfo.isReachable(); + } + + // check unreachable catch blocks + handlingContext.complainIfUnusedExceptionHandlers(catchBlocks, scope, this); + + // process the catch blocks - computing the minimal exit depth amongst try/catch + if (catchArguments != null) { + int catchCount; + catchExits = new boolean[catchCount = catchBlocks.length]; + for (int i = 0; i < catchCount; i++) { + // keep track of the inits that could potentially have led to this exception handler (for final assignments diagnosis) + FlowInfo catchInfo = + flowInfo + .copy() + .unconditionalInits() + .addPotentialInitializationsFrom( + handlingContext.initsOnException(caughtExceptionTypes[i]).unconditionalInits()) + .addPotentialInitializationsFrom(tryInfo.unconditionalInits()) + .addPotentialInitializationsFrom(handlingContext.initsOnReturn); + + // catch var is always set + catchInfo.markAsDefinitelyAssigned(catchArguments[i].binding); + /* + "If we are about to consider an unchecked exception handler, potential inits may have occured inside + the try block that need to be detected , e.g. + try { x = 1; throwSomething();} catch(Exception e){ x = 2} " + "(uncheckedExceptionTypes notNil and: [uncheckedExceptionTypes at: index]) + ifTrue: [catchInits addPotentialInitializationsFrom: tryInits]." + */ + // TODO: should only tag as unreachable if the catchblock cannot be reached + //??? if (!handlingContext.initsOnException(caughtExceptionTypes[i]).isReachable()){ + if (tryBlock.statements == null) { + catchInfo.setReachMode(FlowInfo.UNREACHABLE); + } + catchInfo = + catchBlocks[i].analyseCode( + currentScope, + insideSubContext == null ? flowContext : insideSubContext, + catchInfo); + catchExits[i] = !catchInfo.isReachable(); + tryInfo = tryInfo.mergedWith(catchInfo.unconditionalInits()); + } + } + if (subRoutineStartLabel == null) { + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(tryInfo); + return tryInfo; + } + + + // we also need to check potential multiple assignments of final variables inside the finally block + // need to include potential inits from returns inside the try/catch parts - 1GK2AOF + finallyContext.complainOnRedundantFinalAssignments( + tryInfo.isReachable() + ? (tryInfo.addPotentialInitializationsFrom(insideSubContext.initsOnReturn)) + : insideSubContext.initsOnReturn, + currentScope); + if (subInfo == FlowInfo.DEAD_END) { + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(subInfo); + return subInfo; + } else { + FlowInfo mergedInfo = tryInfo.addInitializationsFrom(subInfo); + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(mergedInfo); + return mergedInfo; + } + } + + public boolean cannotReturn() { + + return subRoutineCannotReturn; + } + + /** + * Try statement code generation + * + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// if (tryBlock.isEmptyBlock()) { +// if (subRoutineStartLabel != null) { +// // since not passing the finallyScope, the block generation will exitUserScope(finallyScope) +// finallyBlock.generateCode(scope, codeStream); +// } +// // May loose some local variable initializations : affecting the local variable attributes +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// // no local bytecode produced so no need for position remembering +// return; +// } +// int pc = codeStream.position; +// Label endLabel = new Label(codeStream); +// boolean requiresNaturalJsr = false; +// +// // preparing exception labels +// int maxCatches; +// ExceptionLabel[] exceptionLabels = +// new ExceptionLabel[maxCatches = +// catchArguments == null ? 0 : catchArguments.length]; +// for (int i = 0; i < maxCatches; i++) { +// boolean preserveCurrentHandler = +// (preserveExceptionHandler[i +// / ExceptionHandlingFlowContext.BitCacheSize] +// & (1 << (i % ExceptionHandlingFlowContext.BitCacheSize))) +// != 0; +// if (preserveCurrentHandler) { +// exceptionLabels[i] = +// new ExceptionLabel( +// codeStream, +// (ReferenceBinding) catchArguments[i].binding.type); +// } +// } +// ExceptionLabel anyExceptionLabel = null; +// if (subRoutineStartLabel != null) { +// subRoutineStartLabel.codeStream = codeStream; +// anyExceptionLabel = new ExceptionLabel(codeStream, null); +// } +// // generate the try block +// tryBlock.generateCode(scope, codeStream); +// boolean tryBlockHasSomeCode = codeStream.position != pc; +// // flag telling if some bytecodes were issued inside the try block +// +// // natural exit: only if necessary +// boolean nonReturningSubRoutine = +// (subRoutineStartLabel != null) && subRoutineCannotReturn; +// if ((!tryBlockExit) && tryBlockHasSomeCode) { +// int position = codeStream.position; +// if (nonReturningSubRoutine) { +// codeStream.goto_(subRoutineStartLabel); +// } else { +// requiresNaturalJsr = true; +// codeStream.goto_(endLabel); +// } +// codeStream.updateLastRecordedEndPC(position); +// //goto is tagged as part of the try block +// } +// // place end positions of user-defined exception labels +// if (tryBlockHasSomeCode) { +// for (int i = 0; i < maxCatches; i++) { +// boolean preserveCurrentHandler = +// (preserveExceptionHandler[i / ExceptionHandlingFlowContext.BitCacheSize] +// & (1 << (i % ExceptionHandlingFlowContext.BitCacheSize))) +// != 0; +// if (preserveCurrentHandler) { +// exceptionLabels[i].placeEnd(); +// } +// } +// /* generate sequence of handler, all starting by storing the TOS (exception +// thrown) into their own catch variables, the one specified in the source +// that must denote the handled exception. +// */ +// if (catchArguments == null) { +// if (anyExceptionLabel != null) { +// anyExceptionLabel.placeEnd(); +// } +// } else { +// for (int i = 0; i < maxCatches; i++) { +// boolean preserveCurrentHandler = +// (preserveExceptionHandler[i / ExceptionHandlingFlowContext.BitCacheSize] +// & (1 << (i % ExceptionHandlingFlowContext.BitCacheSize))) +// != 0; +// if (preserveCurrentHandler) { +// // May loose some local variable initializations : affecting the local variable attributes +// if (preTryInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// preTryInitStateIndex); +// } +// exceptionLabels[i].place(); +// codeStream.incrStackSize(1); +// // optimizing the case where the exception variable is not actually used +// LocalVariableBinding catchVar; +// int varPC = codeStream.position; +// if ((catchVar = catchArguments[i].binding).resolvedPosition != -1) { +// codeStream.store(catchVar, false); +// catchVar.recordInitializationStartPC(codeStream.position); +// codeStream.addVisibleLocalVariable(catchVar); +// } else { +// codeStream.pop(); +// } +// codeStream.recordPositionsFrom(varPC, catchArguments[i].sourceStart); +// // Keep track of the pcs at diverging point for computing the local attribute +// // since not passing the catchScope, the block generation will exitUserScope(catchScope) +// catchBlocks[i].generateCode(scope, codeStream); +// } +// if (i == maxCatches - 1) { +// if (anyExceptionLabel != null) { +// anyExceptionLabel.placeEnd(); +// } +// if (subRoutineStartLabel != null) { +// if (!catchExits[i] && preserveCurrentHandler) { +// requiresNaturalJsr = true; +// codeStream.goto_(endLabel); +// } +// } +// } else { +// if (!catchExits[i] && preserveCurrentHandler) { +// if (nonReturningSubRoutine) { +// codeStream.goto_(subRoutineStartLabel); +// } else { +// requiresNaturalJsr = true; +// codeStream.goto_(endLabel); +// } +// } +// } +// } +// } +// // addition of a special handler so as to ensure that any uncaught exception (or exception thrown +// // inside catch blocks) will run the finally block +// int finallySequenceStartPC = codeStream.position; +// if (subRoutineStartLabel != null) { +// // the additional handler is doing: jsr finallyBlock and rethrow TOS-exception +// anyExceptionLabel.place(); +// +// if (preTryInitStateIndex != -1) { +// // reset initialization state, as for a normal catch block +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// preTryInitStateIndex); +// } +// +// codeStream.incrStackSize(1); +// if (nonReturningSubRoutine) { +// codeStream.pop(); +// // "if subroutine cannot return, no need to jsr/jump to subroutine since it will be entered in sequence +// } else { +// codeStream.store(anyExceptionVariable, false); +// codeStream.jsr(subRoutineStartLabel); +// codeStream.load(anyExceptionVariable); +// codeStream.athrow(); +// } +// } +// // end of catch sequence, place label that will correspond to the finally block beginning, or end of statement +// endLabel.place(); +// if (subRoutineStartLabel != null) { +// if (nonReturningSubRoutine) { +// requiresNaturalJsr = false; +// } +// Label veryEndLabel = new Label(codeStream); +// if (requiresNaturalJsr) { +// codeStream.jsr(subRoutineStartLabel); +// codeStream.goto_(veryEndLabel); +// } +// subRoutineStartLabel.place(); +// if (!nonReturningSubRoutine) { +// codeStream.incrStackSize(1); +// codeStream.store(returnAddressVariable, false); +// } +// codeStream.recordPositionsFrom( +// finallySequenceStartPC, +// finallyBlock.sourceStart); +// // entire sequence for finally is associated to finally block +// finallyBlock.generateCode(scope, codeStream); +// if (!nonReturningSubRoutine) { +// int position = codeStream.position; +// codeStream.ret(returnAddressVariable.resolvedPosition); +// codeStream.updateLastRecordedEndPC(position); +// // the ret bytecode is part of the subroutine +// } +// if (requiresNaturalJsr) { +// veryEndLabel.place(); +// } +// } +// } else { +// // try block had no effect, only generate the body of the finally block if any +// if (subRoutineStartLabel != null) { +// finallyBlock.generateCode(scope, codeStream); +// } +// } +// // May loose some local variable initializations : affecting the local variable attributes +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// codeStream.addDefinitelyAssignedVariables(currentScope, mergedInitStateIndex); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public void resetStateForCodeGeneration() { + if (this.subRoutineStartLabel != null) { + this.subRoutineStartLabel.resetStateForCodeGeneration(); + } + } + + public void resolve(BlockScope upperScope) { + + // special scope for secret locals optimization. + this.scope = new BlockScope(upperScope); + + BlockScope tryScope = new BlockScope(scope); + BlockScope finallyScope = null; + + if (finallyBlock != null + && finallyBlock.statements != null) { + + finallyScope = new BlockScope(scope, false); // don't add it yet to parent scope + + // provision for returning and forcing the finally block to run + MethodScope methodScope = scope.methodScope(); + + // the type does not matter as long as it is not a base type + this.returnAddressVariable = + new LocalVariableBinding(SecretReturnName, upperScope.getJavaLangObject(), AccDefault, false); + finallyScope.addLocalVariable(returnAddressVariable); + this.returnAddressVariable.constant = NotAConstant; // not inlinable + this.subRoutineStartLabel = new Label(); + + this.anyExceptionVariable = + new LocalVariableBinding(SecretAnyHandlerName, scope.getJavaLangThrowable(), AccDefault, false); + finallyScope.addLocalVariable(this.anyExceptionVariable); + this.anyExceptionVariable.constant = NotAConstant; // not inlinable + + if (!methodScope.isInsideInitializer()) { + MethodBinding methodBinding = + ((AbstractMethodDeclaration) methodScope.referenceContext).binding; + if (methodBinding != null) { + TypeBinding methodReturnType = methodBinding.returnType; + if (methodReturnType.id != T_void) { + this.secretReturnValue = + new LocalVariableBinding( + SecretLocalDeclarationName, + methodReturnType, + AccDefault, + false); + finallyScope.addLocalVariable(this.secretReturnValue); + this.secretReturnValue.constant = NotAConstant; // not inlinable + } + } + } + finallyBlock.resolveUsing(finallyScope); + // force the finally scope to have variable positions shifted after its try scope and catch ones + finallyScope.shiftScopes = new BlockScope[catchArguments == null ? 1 : catchArguments.length+1]; + finallyScope.shiftScopes[0] = tryScope; + } + this.tryBlock.resolveUsing(tryScope); + + // arguments type are checked against JavaLangThrowable in resolveForCatch(..) + if (this.catchBlocks != null) { + int length = this.catchArguments.length; + TypeBinding[] argumentTypes = new TypeBinding[length]; + for (int i = 0; i < length; i++) { + BlockScope catchScope = new BlockScope(scope); + if (finallyScope != null){ + finallyScope.shiftScopes[i+1] = catchScope; + } + // side effect on catchScope in resolveForCatch(..) + if ((argumentTypes[i] = catchArguments[i].resolveForCatch(catchScope)) == null) + return; + catchBlocks[i].resolveUsing(catchScope); + } + + // Verify that the catch clause are ordered in the right way: + // more specialized first. + this.caughtExceptionTypes = new ReferenceBinding[length]; + for (int i = 0; i < length; i++) { + caughtExceptionTypes[i] = (ReferenceBinding) argumentTypes[i]; + for (int j = 0; j < i; j++) { + if (caughtExceptionTypes[i].isCompatibleWith(argumentTypes[j])) { + scope.problemReporter().wrongSequenceOfExceptionTypesError(this, i, j); + // cannot return - since may still proceed if unreachable code is ignored (21203) + } + } + } + } else { + caughtExceptionTypes = new ReferenceBinding[0]; + } + + if (finallyScope != null){ + // add finallyScope as last subscope, so it can be shifted behind try/catch subscopes. + // the shifting is necessary to achieve no overlay in between the finally scope and its + // sibling in term of local variable positions. + this.scope.addSubscope(finallyScope); + } + } + + public String toString(int tab) { + String s = tabString(tab); + //try + s = s + "try "; //$NON-NLS-1$ + if (tryBlock == Block.None) + s = s + "{}"; //$NON-NLS-1$ + else + s = s + "\n" + tryBlock.toString(tab + 1); //$NON-NLS-1$ + + //catches + if (catchBlocks != null) + for (int i = 0; i < catchBlocks.length; i++) + s = s + "\n" + tabString(tab) + "catch (" //$NON-NLS-2$ //$NON-NLS-1$ + +catchArguments[i].toString(0) + ") " //$NON-NLS-1$ + +catchBlocks[i].toString(tab + 1); + //finally + if (finallyBlock != null) { + if (finallyBlock == Block.None) + s = s + "\n" + tabString(tab) + "finally {}"; //$NON-NLS-2$ //$NON-NLS-1$ + else + s = s + "\n" + tabString(tab) + "finally\n" + //$NON-NLS-2$ //$NON-NLS-1$ + finallyBlock.toString(tab + 1); + } + + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + tryBlock.traverse(visitor, scope); + if (catchArguments != null) { + for (int i = 0, max = catchBlocks.length; i < max; i++) { + catchArguments[i].traverse(visitor, scope); + catchBlocks[i].traverse(visitor, scope); + } + } + if (finallyBlock != null) + finallyBlock.traverse(visitor, scope); + } + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/TypeDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/TypeDeclaration.java new file mode 100644 index 0000000..308f852 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/TypeDeclaration.java @@ -0,0 +1,980 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.CompilationResult; +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.InitializationFlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.UnconditionalFlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope; +import net.sourceforge.phpdt.internal.compiler.lookup.CompilationUnitScope; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MemberTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; +import net.sourceforge.phpdt.internal.compiler.lookup.NestedTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; +import net.sourceforge.phpdt.internal.compiler.parser.Parser; +import net.sourceforge.phpdt.internal.compiler.parser.UnitParser; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; +import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilationUnit; +import net.sourceforge.phpdt.internal.compiler.problem.AbortMethod; +import net.sourceforge.phpdt.internal.compiler.problem.AbortType; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities; + +public class TypeDeclaration + extends Statement + implements ProblemSeverities, ReferenceContext { + + public int modifiers; + public int modifiersSourceStart; + public char[] name; + public TypeReference superclass; + public TypeReference[] superInterfaces; + public FieldDeclaration[] fields; + public AbstractMethodDeclaration[] methods; + public MemberTypeDeclaration[] memberTypes; + public SourceTypeBinding binding; + public ClassScope scope; + public MethodScope initializerScope; + public MethodScope staticInitializerScope; + public boolean ignoreFurtherInvestigation = false; + public int maxFieldCount; + public int declarationSourceStart; + public int declarationSourceEnd; + public int bodyStart; + public int bodyEnd; // doesn't include the trailing comment if any. + protected boolean hasBeenGenerated = false; + public CompilationResult compilationResult; + private MethodDeclaration[] missingAbstractMethods; + + public TypeDeclaration(CompilationResult compilationResult){ + this.compilationResult = compilationResult; + } + + /* + * We cause the compilation task to abort to a given extent. + */ + public void abort(int abortLevel) { + + if (scope == null) { + throw new AbortCompilation(); // cannot do better + } + + CompilationResult compilationResult = + scope.referenceCompilationUnit().compilationResult; + + switch (abortLevel) { + case AbortCompilation : + throw new AbortCompilation(compilationResult); + case AbortCompilationUnit : + throw new AbortCompilationUnit(compilationResult); + case AbortMethod : + throw new AbortMethod(compilationResult); + default : + throw new AbortType(compilationResult); + } + } + /** + * This method is responsible for adding a method declaration to the type method collections. + * Note that this implementation is inserting it in first place (as VAJ or javac), and that this + * impacts the behavior of the method ConstantPool.resetForClinit(int. int), in so far as + * the latter will have to reset the constant pool state accordingly (if it was added first, it does + * not need to preserve some of the method specific cached entries since this will be the first method). + * inserts the clinit method declaration in the first position. + * + * @see org.eclipse.jdt.internal.compiler.codegen.ConstantPool#resetForClinit(int, int) + */ + public final void addClinit() { + + //see comment on needClassInitMethod + if (needClassInitMethod()) { + int length; + AbstractMethodDeclaration[] methods; + if ((methods = this.methods) == null) { + length = 0; + methods = new AbstractMethodDeclaration[1]; + } else { + length = methods.length; + System.arraycopy( + methods, + 0, + (methods = new AbstractMethodDeclaration[length + 1]), + 1, + length); + } + Clinit clinit = new Clinit(this.compilationResult); + methods[0] = clinit; + // clinit is added in first location, so as to minimize the use of ldcw (big consumer of constant inits) + clinit.declarationSourceStart = clinit.sourceStart = sourceStart; + clinit.declarationSourceEnd = clinit.sourceEnd = sourceEnd; + clinit.bodyEnd = sourceEnd; + this.methods = methods; + } + } + + /** + * Flow analysis for a local innertype + * + */ + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + if (ignoreFurtherInvestigation) + return flowInfo; + try { + bits |= IsReachableMASK; + LocalTypeBinding localType = (LocalTypeBinding) binding; + + localType.setConstantPoolName(currentScope.compilationUnitScope().computeConstantPoolName(localType)); + manageEnclosingInstanceAccessIfNecessary(currentScope); + + updateMaxFieldCount(); // propagate down the max field count + internalAnalyseCode(flowContext, flowInfo); + } catch (AbortType e) { + this.ignoreFurtherInvestigation = true; + } + return flowInfo; + } + + /** + * Flow analysis for a member innertype + * + */ + public void analyseCode(ClassScope enclosingClassScope) { + + if (ignoreFurtherInvestigation) + return; + try { + // propagate down the max field count + updateMaxFieldCount(); + internalAnalyseCode(null, FlowInfo.initial(maxFieldCount)); + } catch (AbortType e) { + this.ignoreFurtherInvestigation = true; + } + } + + /** + * Flow analysis for a local member innertype + * + */ + public void analyseCode( + ClassScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + if (ignoreFurtherInvestigation) + return; + try { + bits |= IsReachableMASK; + LocalTypeBinding localType = (LocalTypeBinding) binding; + + localType.setConstantPoolName(currentScope.compilationUnitScope().computeConstantPoolName(localType)); + manageEnclosingInstanceAccessIfNecessary(currentScope); + + updateMaxFieldCount(); // propagate down the max field count + internalAnalyseCode(flowContext, flowInfo); + } catch (AbortType e) { + this.ignoreFurtherInvestigation = true; + } + } + + /** + * Flow analysis for a package member type + * + */ + public void analyseCode(CompilationUnitScope unitScope) { + + if (ignoreFurtherInvestigation) + return; + try { + internalAnalyseCode(null, FlowInfo.initial(maxFieldCount)); + } catch (AbortType e) { + this.ignoreFurtherInvestigation = true; + } + } + + /* + * Check for constructor vs. method with no return type. + * Answers true if at least one constructor is defined + */ + public boolean checkConstructors(Parser parser) { + + //if a constructor has not the name of the type, + //convert it into a method with 'null' as its return type + boolean hasConstructor = false; + if (methods != null) { + for (int i = methods.length; --i >= 0;) { + AbstractMethodDeclaration am; + if ((am = methods[i]).isConstructor()) { + if (!CharOperation.equals(am.selector, name)) { + // the constructor was in fact a method with no return type + // unless an explicit constructor call was supplied + ConstructorDeclaration c = (ConstructorDeclaration) am; + if ((c.constructorCall == null) + || (c.constructorCall.isImplicitSuper())) { //changed to a method + MethodDeclaration m = new MethodDeclaration(this.compilationResult); + m.sourceStart = c.sourceStart; + m.sourceEnd = c.sourceEnd; + m.bodyStart = c.bodyStart; + m.bodyEnd = c.bodyEnd; + m.declarationSourceEnd = c.declarationSourceEnd; + m.declarationSourceStart = c.declarationSourceStart; + m.selector = c.selector; + m.statements = c.statements; + m.modifiers = c.modifiers; + m.arguments = c.arguments; + m.thrownExceptions = c.thrownExceptions; + m.explicitDeclarations = c.explicitDeclarations; + m.returnType = null; + methods[i] = m; + } + } else { + if (this.isInterface()) { + // report the problem and continue the parsing + parser.problemReporter().interfaceCannotHaveConstructors( + (ConstructorDeclaration) am); + } + hasConstructor = true; + } + } + } + } + return hasConstructor; + } + + public CompilationResult compilationResult() { + + return this.compilationResult; + } + + public ConstructorDeclaration createsInternalConstructor( + boolean needExplicitConstructorCall, + boolean needToInsert) { + + //Add to method'set, the default constuctor that just recall the + //super constructor with no arguments + //The arguments' type will be positionned by the TC so just use + //the default int instead of just null (consistency purpose) + + //the constructor + ConstructorDeclaration constructor = new ConstructorDeclaration(this.compilationResult); + constructor.isDefaultConstructor = true; + constructor.selector = name; + if (modifiers != AccDefault) { + constructor.modifiers = + ((this instanceof MemberTypeDeclaration) && (modifiers & AccPrivate) != 0) + ? AccDefault + : modifiers & AccVisibilityMASK; + } + + //if you change this setting, please update the + //SourceIndexer2.buildTypeDeclaration(TypeDeclaration,char[]) method + constructor.declarationSourceStart = constructor.sourceStart = sourceStart; + constructor.declarationSourceEnd = + constructor.sourceEnd = constructor.bodyEnd = sourceEnd; + + //the super call inside the constructor + if (needExplicitConstructorCall) { + constructor.constructorCall = SuperReference.implicitSuperConstructorCall(); + constructor.constructorCall.sourceStart = sourceStart; + constructor.constructorCall.sourceEnd = sourceEnd; + } + + //adding the constructor in the methods list + if (needToInsert) { + if (methods == null) { + methods = new AbstractMethodDeclaration[] { constructor }; + } else { + AbstractMethodDeclaration[] newMethods; + System.arraycopy( + methods, + 0, + newMethods = new AbstractMethodDeclaration[methods.length + 1], + 1, + methods.length); + newMethods[0] = constructor; + methods = newMethods; + } + } + return constructor; + } + + /** + * INTERNAL USE ONLY - Creates a fake method declaration for the corresponding binding. + * It is used to report errors for missing abstract methods. + */ + public MethodDeclaration addMissingAbstractMethodFor(MethodBinding methodBinding) { + TypeBinding[] argumentTypes = methodBinding.parameters; + int argumentsLength = argumentTypes.length; + //the constructor + MethodDeclaration methodDeclaration = new MethodDeclaration(this.compilationResult); + methodDeclaration.selector = methodBinding.selector; + methodDeclaration.sourceStart = sourceStart; + methodDeclaration.sourceEnd = sourceEnd; + methodDeclaration.modifiers = methodBinding.getAccessFlags() & ~AccAbstract; + + if (argumentsLength > 0) { + String baseName = "arg";//$NON-NLS-1$ + Argument[] arguments = (methodDeclaration.arguments = new Argument[argumentsLength]); + for (int i = argumentsLength; --i >= 0;) { + arguments[i] = new Argument((baseName + i).toCharArray(), 0L, null /*type ref*/, AccDefault); + } + } + + //adding the constructor in the methods list + if (this.missingAbstractMethods == null) { + this.missingAbstractMethods = new MethodDeclaration[] { methodDeclaration }; + } else { + MethodDeclaration[] newMethods; + System.arraycopy( + this.missingAbstractMethods, + 0, + newMethods = new MethodDeclaration[this.missingAbstractMethods.length + 1], + 1, + this.missingAbstractMethods.length); + newMethods[0] = methodDeclaration; + this.missingAbstractMethods = newMethods; + } + + //============BINDING UPDATE========================== + methodDeclaration.binding = new MethodBinding( + methodDeclaration.modifiers, //methodDeclaration + methodBinding.selector, + methodBinding.returnType, + argumentsLength == 0 ? NoParameters : argumentTypes, //arguments bindings + methodBinding.thrownExceptions, //exceptions + binding); //declaringClass + + methodDeclaration.scope = new MethodScope(scope, methodDeclaration, true); + methodDeclaration.bindArguments(); + +/* if (binding.methods == null) { + binding.methods = new MethodBinding[] { methodDeclaration.binding }; + } else { + MethodBinding[] newMethods; + System.arraycopy( + binding.methods, + 0, + newMethods = new MethodBinding[binding.methods.length + 1], + 1, + binding.methods.length); + newMethods[0] = methodDeclaration.binding; + binding.methods = newMethods; + }*/ + //=================================================== + + return methodDeclaration; + } + + /* + * Find the matching parse node, answers null if nothing found + */ + public FieldDeclaration declarationOf(FieldBinding fieldBinding) { + + if (fieldBinding != null) { + for (int i = 0, max = this.fields.length; i < max; i++) { + FieldDeclaration fieldDecl; + if ((fieldDecl = this.fields[i]).binding == fieldBinding) + return fieldDecl; + } + } + return null; + } + + /* + * Find the matching parse node, answers null if nothing found + */ + public TypeDeclaration declarationOf(MemberTypeBinding memberTypeBinding) { + + if (memberTypeBinding != null) { + for (int i = 0, max = this.memberTypes.length; i < max; i++) { + TypeDeclaration memberTypeDecl; + if ((memberTypeDecl = this.memberTypes[i]).binding == memberTypeBinding) + return memberTypeDecl; + } + } + return null; + } + + /* + * Find the matching parse node, answers null if nothing found + */ + public AbstractMethodDeclaration declarationOf(MethodBinding methodBinding) { + + if (methodBinding != null) { + for (int i = 0, max = this.methods.length; i < max; i++) { + AbstractMethodDeclaration methodDecl; + + if ((methodDecl = this.methods[i]).binding == methodBinding) + return methodDecl; + } + } + return null; + } + + /* + * Finds the matching type amoung this type's member types. + * Returns null if no type with this name is found. + * The type name is a compound name relative to this type + * eg. if this type is X and we're looking for Y.X.A.B + * then a type name would be {X, A, B} + */ + public TypeDeclaration declarationOfType(char[][] typeName) { + + int typeNameLength = typeName.length; + if (typeNameLength < 1 || !CharOperation.equals(typeName[0], this.name)) { + return null; + } + if (typeNameLength == 1) { + return this; + } + char[][] subTypeName = new char[typeNameLength - 1][]; + System.arraycopy(typeName, 1, subTypeName, 0, typeNameLength - 1); + for (int i = 0; i < this.memberTypes.length; i++) { + TypeDeclaration typeDecl = this.memberTypes[i].declarationOfType(subTypeName); + if (typeDecl != null) { + return typeDecl; + } + } + return null; + } + + /** + * Generic bytecode generation for type + */ +// public void generateCode(ClassFile enclosingClassFile) { +// +// if (hasBeenGenerated) +// return; +// hasBeenGenerated = true; +// if (ignoreFurtherInvestigation) { +// if (binding == null) +// return; +// ClassFile.createProblemType( +// this, +// scope.referenceCompilationUnit().compilationResult); +// return; +// } +// try { +// // create the result for a compiled type +// ClassFile classFile = new ClassFile(binding, enclosingClassFile, false); +// // generate all fiels +// classFile.addFieldInfos(); +// +// // record the inner type inside its own .class file to be able +// // to generate inner classes attributes +// if (binding.isMemberType()) +// classFile.recordEnclosingTypeAttributes(binding); +// if (binding.isLocalType()) { +// enclosingClassFile.recordNestedLocalAttribute(binding); +// classFile.recordNestedLocalAttribute(binding); +// } +// if (memberTypes != null) { +// for (int i = 0, max = memberTypes.length; i < max; i++) { +// // record the inner type inside its own .class file to be able +// // to generate inner classes attributes +// classFile.recordNestedMemberAttribute(memberTypes[i].binding); +// memberTypes[i].generateCode(scope, classFile); +// } +// } +// // generate all methods +// classFile.setForMethodInfos(); +// if (methods != null) { +// for (int i = 0, max = methods.length; i < max; i++) { +// methods[i].generateCode(scope, classFile); +// } +// } +// +// classFile.generateMissingAbstractMethods(this.missingAbstractMethods, scope.referenceCompilationUnit().compilationResult); +// +// // generate all methods +// classFile.addSpecialMethods(); +// +// if (ignoreFurtherInvestigation) { // trigger problem type generation for code gen errors +// throw new AbortType(scope.referenceCompilationUnit().compilationResult); +// } +// +// // finalize the compiled type result +// classFile.addAttributes(); +// scope.referenceCompilationUnit().compilationResult.record( +// binding.constantPoolName(), +// classFile); +// } catch (AbortType e) { +// if (binding == null) +// return; +// ClassFile.createProblemType( +// this, +// scope.referenceCompilationUnit().compilationResult); +// } +// } + + /** + * Bytecode generation for a local inner type (API as a normal statement code gen) + */ +// public void generateCode(BlockScope blockScope, CodeStream codeStream) { +// +// if (hasBeenGenerated) return; +// int pc = codeStream.position; +// if (binding != null) ((NestedTypeBinding) binding).computeSyntheticArgumentSlotSizes(); +// generateCode(codeStream.classFile); +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + /** + * Bytecode generation for a member inner type + */ +// public void generateCode(ClassScope classScope, ClassFile enclosingClassFile) { +// +// if (hasBeenGenerated) return; +// if (binding != null) ((NestedTypeBinding) binding).computeSyntheticArgumentSlotSizes(); +// generateCode(enclosingClassFile); +// } + + /** + * Bytecode generation for a package member + */ +// public void generateCode(CompilationUnitScope unitScope) { +// +// generateCode((ClassFile) null); +// } + + public boolean hasErrors() { + return this.ignoreFurtherInvestigation; + } + + /** + * Common flow analysis for all types + * + */ + public void internalAnalyseCode(FlowContext flowContext, FlowInfo flowInfo) { + + if (this.binding.isPrivate() && !this.binding.isPrivateUsed()) { + if (!scope.referenceCompilationUnit().compilationResult.hasSyntaxError()) { + scope.problemReporter().unusedPrivateType(this); + } + } + + ReferenceBinding[] defaultHandledExceptions = new ReferenceBinding[] { scope.getJavaLangThrowable()}; // tolerate any kind of exception + InitializationFlowContext initializerContext = new InitializationFlowContext(null, this, initializerScope); + InitializationFlowContext staticInitializerContext = new InitializationFlowContext(null, this, staticInitializerScope); + FlowInfo nonStaticFieldInfo = flowInfo.copy().unconditionalInits().discardFieldInitializations(); + FlowInfo staticFieldInfo = flowInfo.copy().unconditionalInits().discardFieldInitializations(); + if (fields != null) { + for (int i = 0, count = fields.length; i < count; i++) { + FieldDeclaration field = fields[i]; + if (field.isStatic()) { + /*if (field.isField()){ + staticInitializerContext.handledExceptions = NoExceptions; // no exception is allowed jls8.3.2 + } else {*/ + staticInitializerContext.handledExceptions = defaultHandledExceptions; // tolerate them all, and record them + /*}*/ + staticFieldInfo = + field.analyseCode( + staticInitializerScope, + staticInitializerContext, + staticFieldInfo); + // in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable + // branch, since the previous initializer already got the blame. + if (staticFieldInfo == FlowInfo.DEAD_END) { + staticInitializerScope.problemReporter().initializerMustCompleteNormally(field); + staticFieldInfo = FlowInfo.initial(maxFieldCount).setReachMode(FlowInfo.UNREACHABLE); + } + } else { + /*if (field.isField()){ + initializerContext.handledExceptions = NoExceptions; // no exception is allowed jls8.3.2 + } else {*/ + initializerContext.handledExceptions = defaultHandledExceptions; // tolerate them all, and record them + /*}*/ + nonStaticFieldInfo = + field.analyseCode(initializerScope, initializerContext, nonStaticFieldInfo); + // in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable + // branch, since the previous initializer already got the blame. + if (nonStaticFieldInfo == FlowInfo.DEAD_END) { + initializerScope.problemReporter().initializerMustCompleteNormally(field); + nonStaticFieldInfo = FlowInfo.initial(maxFieldCount).setReachMode(FlowInfo.UNREACHABLE); + } + } + } + } + if (memberTypes != null) { + for (int i = 0, count = memberTypes.length; i < count; i++) { + if (flowContext != null){ // local type + memberTypes[i].analyseCode(scope, flowContext, nonStaticFieldInfo.copy()); + } else { + memberTypes[i].analyseCode(scope); + } + } + } + if (methods != null) { + UnconditionalFlowInfo outerInfo = flowInfo.copy().unconditionalInits().discardFieldInitializations(); + FlowInfo constructorInfo = nonStaticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo); + for (int i = 0, count = methods.length; i < count; i++) { + AbstractMethodDeclaration method = methods[i]; + if (method.ignoreFurtherInvestigation) + continue; + if (method.isInitializationMethod()) { + if (method.isStatic()) { // + method.analyseCode( + scope, + staticInitializerContext, + staticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo)); + } else { // constructor + method.analyseCode(scope, initializerContext, constructorInfo.copy()); + } + } else { // regular method + method.analyseCode(scope, null, flowInfo.copy()); + } + } + } + } + + public boolean isInterface() { + + return (modifiers & AccInterface) != 0; + } + + /* + * Access emulation for a local type + * force to emulation of access to direct enclosing instance. + * By using the initializer scope, we actually only request an argument emulation, the + * field is not added until actually used. However we will force allocations to be qualified + * with an enclosing instance. + * 15.9.2 + */ + public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) { + + NestedTypeBinding nestedType = (NestedTypeBinding) binding; + + MethodScope methodScope = currentScope.methodScope(); + if (!methodScope.isStatic && !methodScope.isConstructorCall){ + + nestedType.addSyntheticArgumentAndField(binding.enclosingType()); + } + // add superclass enclosing instance arg for anonymous types (if necessary) + if (binding.isAnonymousType()) { + ReferenceBinding superclass = binding.superclass; + if (superclass.enclosingType() != null && !superclass.isStatic()) { + if (!binding.superclass.isLocalType() + || ((NestedTypeBinding)binding.superclass).getSyntheticField(superclass.enclosingType(), true) != null){ + + nestedType.addSyntheticArgument(superclass.enclosingType()); + } + } + } + } + + /* + * Access emulation for a local member type + * force to emulation of access to direct enclosing instance. + * By using the initializer scope, we actually only request an argument emulation, the + * field is not added until actually used. However we will force allocations to be qualified + * with an enclosing instance. + * + * Local member cannot be static. + */ + public void manageEnclosingInstanceAccessIfNecessary(ClassScope currentScope) { + + NestedTypeBinding nestedType = (NestedTypeBinding) binding; + nestedType.addSyntheticArgumentAndField(binding.enclosingType()); + } + + /** + * A will be requested as soon as static fields or assertions are present. It will be eliminated during + * classfile creation if no bytecode was actually produced based on some optimizations/compiler settings. + */ + public final boolean needClassInitMethod() { + + // always need a when assertions are present + if ((this.bits & AddAssertionMASK) != 0) + return true; + if (fields == null) + return false; + if (isInterface()) + return true; // fields are implicitly statics + for (int i = fields.length; --i >= 0;) { + FieldDeclaration field = fields[i]; + //need to test the modifier directly while there is no binding yet + if ((field.modifiers & AccStatic) != 0) + return true; + } + return false; + } + + public void parseMethod(UnitParser parser, CompilationUnitDeclaration unit) { + + //connect method bodies + if (unit.ignoreMethodBodies) + return; + + // no scope were created, so cannot report further errors +// if (binding == null) +// return; + + //members + if (memberTypes != null) { + int length = memberTypes.length; + for (int i = 0; i < length; i++) + memberTypes[i].parseMethod(parser, unit); + } + + //methods + if (methods != null) { + int length = methods.length; + for (int i = 0; i < length; i++) + methods[i].parseStatements(parser, unit); + } + + //initializers + if (fields != null) { + int length = fields.length; + for (int i = 0; i < length; i++) { + if (fields[i] instanceof Initializer) { + ((Initializer) fields[i]).parseStatements(parser, this, unit); + } + } + } + } + + public void resolve() { + + if (binding == null) { + ignoreFurtherInvestigation = true; + return; + } + + try { + // check superclass & interfaces + if (binding.superclass != null) // watch out for Object ! (and other roots) + if (isTypeUseDeprecated(binding.superclass, scope)) + scope.problemReporter().deprecatedType(binding.superclass, superclass); + if (superInterfaces != null) + for (int i = superInterfaces.length; --i >= 0;) + if (superInterfaces[i].resolvedType != null) + if (isTypeUseDeprecated(superInterfaces[i].resolvedType, scope)) + scope.problemReporter().deprecatedType( + superInterfaces[i].resolvedType, + superInterfaces[i]); + maxFieldCount = 0; + int lastFieldID = -1; + if (fields != null) { + for (int i = 0, count = fields.length; i < count; i++) { + FieldDeclaration field = fields[i]; + if (field.isField()) { + if (field.binding == null) { + // still discover secondary errors + if (field.initialization != null) field.initialization.resolve(field.isStatic() ? staticInitializerScope : initializerScope); + ignoreFurtherInvestigation = true; + continue; + } + maxFieldCount++; + lastFieldID = field.binding.id; + } else { // initializer + ((Initializer) field).lastFieldID = lastFieldID + 1; + } + field.resolve(field.isStatic() ? staticInitializerScope : initializerScope); + } + } + if (memberTypes != null) { + for (int i = 0, count = memberTypes.length; i < count; i++) { + memberTypes[i].resolve(scope); + } + } + int missingAbstractMethodslength = this.missingAbstractMethods == null ? 0 : this.missingAbstractMethods.length; + int methodsLength = this.methods == null ? 0 : methods.length; + if ((methodsLength + missingAbstractMethodslength) > 0xFFFF) { + scope.problemReporter().tooManyMethods(this); + } + + if (methods != null) { + for (int i = 0, count = methods.length; i < count; i++) { + methods[i].resolve(scope); + } + } + } catch (AbortType e) { + this.ignoreFurtherInvestigation = true; + return; + }; + } + + public void resolve(BlockScope blockScope) { + // local type declaration + + // need to build its scope first and proceed with binding's creation + blockScope.addLocalType(this); + + // and TC.... + if (binding != null) { + // remember local types binding for innerclass emulation propagation + blockScope.referenceCompilationUnit().record((LocalTypeBinding)binding); + + // binding is not set if the receiver could not be created + resolve(); + updateMaxFieldCount(); + } + } + + public void resolve(ClassScope upperScope) { + // member scopes are already created + // request the construction of a binding if local member type + + if (binding != null && binding instanceof LocalTypeBinding) { + // remember local types binding for innerclass emulation propagation + upperScope.referenceCompilationUnit().record((LocalTypeBinding)binding); + } + resolve(); + updateMaxFieldCount(); + } + + public void resolve(CompilationUnitScope upperScope) { + // top level : scope are already created + + resolve(); + updateMaxFieldCount(); + } + + public void tagAsHavingErrors() { + ignoreFurtherInvestigation = true; + } + + public String toString(int tab) { + + return tabString(tab) + toStringHeader() + toStringBody(tab); + } + + public String toStringBody(int tab) { + + String s = " {"; //$NON-NLS-1$ + if (memberTypes != null) { + for (int i = 0; i < memberTypes.length; i++) { + if (memberTypes[i] != null) { + s += "\n" + memberTypes[i].toString(tab + 1); //$NON-NLS-1$ + } + } + } + if (fields != null) { + for (int fieldI = 0; fieldI < fields.length; fieldI++) { + if (fields[fieldI] != null) { + s += "\n" + fields[fieldI].toString(tab + 1); //$NON-NLS-1$ + if (fields[fieldI].isField()) + s += ";"; //$NON-NLS-1$ + } + } + } + if (methods != null) { + for (int i = 0; i < methods.length; i++) { + if (methods[i] != null) { + s += "\n" + methods[i].toString(tab + 1); //$NON-NLS-1$ + } + } + } + s += "\n" + tabString(tab) + "}"; //$NON-NLS-2$ //$NON-NLS-1$ + return s; + } + + public String toStringHeader() { + + String s = ""; //$NON-NLS-1$ + if (modifiers != AccDefault) { + s += modifiersString(modifiers); + } + s += (isInterface() ? "interface " : "class ") + new String(name);//$NON-NLS-1$ //$NON-NLS-2$ + if (superclass != null) + s += " extends " + superclass.toString(0); //$NON-NLS-1$ + if (superInterfaces != null && superInterfaces.length > 0) { + s += (isInterface() ? " extends " : " implements ");//$NON-NLS-2$ //$NON-NLS-1$ + for (int i = 0; i < superInterfaces.length; i++) { + s += superInterfaces[i].toString(0); + if (i != superInterfaces.length - 1) + s += ", "; //$NON-NLS-1$ + }; + }; + return s; + } + + /** + * Iteration for a package member type + * + */ + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + CompilationUnitScope unitScope) { + + if (ignoreFurtherInvestigation) + return; + try { + if (visitor.visit(this, unitScope)) { + if (superclass != null) + superclass.traverse(visitor, scope); + if (superInterfaces != null) { + int superInterfaceLength = superInterfaces.length; + for (int i = 0; i < superInterfaceLength; i++) + superInterfaces[i].traverse(visitor, scope); + } + if (memberTypes != null) { + int memberTypesLength = memberTypes.length; + for (int i = 0; i < memberTypesLength; i++) + memberTypes[i].traverse(visitor, scope); + } + if (fields != null) { + int fieldsLength = fields.length; + for (int i = 0; i < fieldsLength; i++) { + FieldDeclaration field; + if ((field = fields[i]).isStatic()) { + field.traverse(visitor, staticInitializerScope); + } else { + field.traverse(visitor, initializerScope); + } + } + } + if (methods != null) { + int methodsLength = methods.length; + for (int i = 0; i < methodsLength; i++) + methods[i].traverse(visitor, scope); + } + } + visitor.endVisit(this, unitScope); + } catch (AbortType e) { + } + } + + /** + * MaxFieldCount's computation is necessary so as to reserve space for + * the flow info field portions. It corresponds to the maximum amount of + * fields this class or one of its innertypes have. + * + * During name resolution, types are traversed, and the max field count is recorded + * on the outermost type. It is then propagated down during the flow analysis. + * + * This method is doing either up/down propagation. + */ + void updateMaxFieldCount() { + + if (binding == null) + return; // error scenario + TypeDeclaration outerMostType = scope.outerMostClassScope().referenceType(); + if (maxFieldCount > outerMostType.maxFieldCount) { + outerMostType.maxFieldCount = maxFieldCount; // up + } else { + maxFieldCount = outerMostType.maxFieldCount; // down + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/TypeReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/TypeReference.java new file mode 100644 index 0000000..94571a7 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/TypeReference.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope; +import net.sourceforge.phpdt.internal.compiler.lookup.Scope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; + +public abstract class TypeReference extends Expression { + +public TypeReference() { + super () ; + } + +public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { + return flowInfo; +} + +// allows us to trap completion & selection nodes +public void aboutToResolve(Scope scope) {} +/* + * Answer a base type reference (can be an array of base type). + */ +//public static final TypeReference baseTypeReference(int baseType, int dim) { +// +// if (dim == 0) { +// switch (baseType) { +// case (T_void) : +// return new SingleTypeReference(VoidBinding.simpleName, 0); +// case (T_boolean) : +// return new SingleTypeReference(BooleanBinding.simpleName, 0); +// case (T_char) : +// return new SingleTypeReference(CharBinding.simpleName, 0); +// case (T_float) : +// return new SingleTypeReference(FloatBinding.simpleName, 0); +// case (T_double) : +// return new SingleTypeReference(DoubleBinding.simpleName, 0); +// case (T_byte) : +// return new SingleTypeReference(ByteBinding.simpleName, 0); +// case (T_short) : +// return new SingleTypeReference(ShortBinding.simpleName, 0); +// case (T_int) : +// return new SingleTypeReference(IntBinding.simpleName, 0); +// default : //T_long +// return new SingleTypeReference(LongBinding.simpleName, 0); +// } +// } +// switch (baseType) { +// case (T_void) : +// return new ArrayTypeReference(VoidBinding.simpleName, dim, 0); +// case (T_boolean) : +// return new ArrayTypeReference(BooleanBinding.simpleName, dim, 0); +// case (T_char) : +// return new ArrayTypeReference(CharBinding.simpleName, dim, 0); +// case (T_float) : +// return new ArrayTypeReference(FloatBinding.simpleName, dim, 0); +// case (T_double) : +// return new ArrayTypeReference(DoubleBinding.simpleName, dim, 0); +// case (T_byte) : +// return new ArrayTypeReference(ByteBinding.simpleName, dim, 0); +// case (T_short) : +// return new ArrayTypeReference(ShortBinding.simpleName, dim, 0); +// case (T_int) : +// return new ArrayTypeReference(IntBinding.simpleName, dim, 0); +// default : //T_long +// return new ArrayTypeReference(LongBinding.simpleName, dim, 0); +// } +//} +public abstract TypeReference copyDims(int dim); +public int dimensions() { + return 0; +} +public abstract TypeBinding getTypeBinding(Scope scope); +/** + * @return char[][] + */ +public abstract char [][] getTypeName() ; +public boolean isTypeReference() { + return true; +} +public TypeBinding resolveType(BlockScope scope) { + // handle the error here + constant = NotAConstant; + if (this.resolvedType != null) { // is a shared type reference which was already resolved + if (!this.resolvedType.isValidBinding()) + return null; // already reported error + } else { + this.resolvedType = getTypeBinding(scope); + if (!this.resolvedType.isValidBinding()) { + scope.problemReporter().invalidType(this, this.resolvedType); + return null; + } + if (isTypeUseDeprecated(this.resolvedType, scope)) + scope.problemReporter().deprecatedType(this.resolvedType, this); + } + return this.resolvedType; +} +public abstract void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope classScope); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/UnaryExpression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/UnaryExpression.java new file mode 100644 index 0000000..ac2a75d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/UnaryExpression.java @@ -0,0 +1,297 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public class UnaryExpression extends OperatorExpression { + + public Expression expression; + public Constant optimizedBooleanConstant; + + public UnaryExpression(Expression expression, int operator) { + this.expression = expression; + this.bits |= operator << OperatorSHIFT; // encode operator + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + if (((bits & OperatorMASK) >> OperatorSHIFT) == NOT) { + return this.expression + .analyseCode(currentScope, flowContext, flowInfo) + .asNegatedCondition(); + } else { + return this.expression.analyseCode(currentScope, flowContext, flowInfo); + } + } + + public Constant optimizedBooleanConstant() { + + return this.optimizedBooleanConstant == null + ? this.constant + : this.optimizedBooleanConstant; + } + + /** + * Code generation for an unary operation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param valueRequired boolean + */ +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// int pc = codeStream.position; +// Label falseLabel, endifLabel; +// if (this.constant != Constant.NotAConstant) { +// // inlined value +// if (valueRequired) { +// codeStream.generateConstant(this.constant, this.implicitConversion); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// return; +// } +// switch ((bits & OperatorMASK) >> OperatorSHIFT) { +// case NOT : +// switch (this.expression.implicitConversion >> 4) /* runtime type */ { +// case T_boolean : +// // ! +// // Generate code for the condition +// this.expression.generateOptimizedBoolean( +// currentScope, +// codeStream, +// null, +// (falseLabel = new Label(codeStream)), +// valueRequired); +// if (valueRequired) { +// codeStream.iconst_0(); +// if (falseLabel.hasForwardReferences()) { +// codeStream.goto_(endifLabel = new Label(codeStream)); +// codeStream.decrStackSize(1); +// falseLabel.place(); +// codeStream.iconst_1(); +// endifLabel.place(); +// } +// } else { // 6596: if (!(a && b)){} - must still place falseLabel +// falseLabel.place(); +// } +// break; +// } +// break; +// case TWIDDLE : +// switch (this.expression.implicitConversion >> 4 /* runtime */ +// ) { +// case T_int : +// // ~int +// this.expression.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// codeStream.iconst_m1(); +// codeStream.ixor(); +// } +// break; +// case T_long : +// this.expression.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// codeStream.ldc2_w(-1L); +// codeStream.lxor(); +// } +// } +// break; +// case MINUS : +// // - +// if (this.constant != NotAConstant) { +// if (valueRequired) { +// switch (this.expression.implicitConversion >> 4){ /* runtime */ +// case T_int : +// codeStream.generateInlinedValue(this.constant.intValue() * -1); +// break; +// case T_float : +// codeStream.generateInlinedValue(this.constant.floatValue() * -1.0f); +// break; +// case T_long : +// codeStream.generateInlinedValue(this.constant.longValue() * -1L); +// break; +// case T_double : +// codeStream.generateInlinedValue(this.constant.doubleValue() * -1.0); +// } +// } +// } else { +// this.expression.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// switch (expression.implicitConversion >> 4){ /* runtime type */ +// case T_int : +// codeStream.ineg(); +// break; +// case T_float : +// codeStream.fneg(); +// break; +// case T_long : +// codeStream.lneg(); +// break; +// case T_double : +// codeStream.dneg(); +// } +// } +// } +// break; +// case PLUS : +// this.expression.generateCode(currentScope, codeStream, valueRequired); +// } +// if (valueRequired) { +// codeStream.generateImplicitConversion(this.implicitConversion); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } +// +// /** +// * Boolean operator code generation +// * Optimized operations are: &&, ||, <, <=, >, >=, &, |, ^ +// */ +// public void generateOptimizedBoolean( +// BlockScope currentScope, +// CodeStream codeStream, +// Label trueLabel, +// Label falseLabel, +// boolean valueRequired) { +// +// if ((this.constant != Constant.NotAConstant) && (this.constant.typeID() == T_boolean)) { +// super.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// return; +// } +// if (((this.bits & OperatorMASK) >> OperatorSHIFT) == NOT) { +// this.expression.generateOptimizedBoolean( +// currentScope, +// codeStream, +// falseLabel, +// trueLabel, +// valueRequired); +// } else { +// super.generateOptimizedBoolean( +// currentScope, +// codeStream, +// trueLabel, +// falseLabel, +// valueRequired); +// } +// } + + public TypeBinding resolveType(BlockScope scope) { + + TypeBinding expressionType = this.expression.resolveType(scope); + if (expressionType == null) { + this.constant = NotAConstant; + return null; + } + int expressionId = expressionType.id; + if (expressionId > 15) { + this.constant = NotAConstant; + scope.problemReporter().invalidOperator(this, expressionType); + return null; + } + + int tableId; + switch ((bits & OperatorMASK) >> OperatorSHIFT) { + case NOT : + tableId = AND_AND; + break; + case TWIDDLE : + tableId = LEFT_SHIFT; + break; + default : + tableId = MINUS; + } //+ and - cases + + // the code is an int + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 <<0 + int result = ResolveTypeTables[tableId][(expressionId << 4) + expressionId]; + this.expression.implicitConversion = result >>> 12; + this.bits |= result & 0xF; + switch (result & 0xF) { // only switch on possible result type..... + case T_boolean : + this.resolvedType = BooleanBinding; + break; + case T_byte : + this.resolvedType = ByteBinding; + break; + case T_char : + this.resolvedType = CharBinding; + break; + case T_double : + this.resolvedType = DoubleBinding; + break; + case T_float : + this.resolvedType = FloatBinding; + break; + case T_int : + this.resolvedType = IntBinding; + break; + case T_long : + this.resolvedType = LongBinding; + break; + default : //error........ + this.constant = Constant.NotAConstant; + if (expressionId != T_undefined) + scope.problemReporter().invalidOperator(this, expressionType); + return null; + } + // compute the constant when valid + if (this.expression.constant != Constant.NotAConstant) { + this.constant = + Constant.computeConstantOperation( + this.expression.constant, + expressionId, + (bits & OperatorMASK) >> OperatorSHIFT); + } else { + this.constant = Constant.NotAConstant; + if (((bits & OperatorMASK) >> OperatorSHIFT) == NOT) { + Constant cst = expression.optimizedBooleanConstant(); + if (cst != Constant.NotAConstant) + this.optimizedBooleanConstant = Constant.fromValue(!cst.booleanValue()); + } + } + return this.resolvedType; + } + + public String toStringExpressionNoParenthesis() { + + return operatorToString() + " " + this.expression.toStringExpression(); //$NON-NLS-1$ + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + this.expression.traverse(visitor, blockScope); + } + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/WhileStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/WhileStatement.java new file mode 100644 index 0000000..2fd8e96 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/WhileStatement.java @@ -0,0 +1,259 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.internal.compiler.ast; + +import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.LoopingFlowContext; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + + +public class WhileStatement extends Statement { + + public Expression condition; + public Statement action; + private Label breakLabel, continueLabel; + int preCondInitStateIndex = -1; + int condIfTrueInitStateIndex = -1; + int mergedInitStateIndex = -1; + + public WhileStatement(Expression condition, Statement action, int s, int e) { + + this.condition = condition; + this.action = action; + sourceStart = s; + sourceEnd = e; + } + + public FlowInfo analyseCode( + BlockScope currentScope, + FlowContext flowContext, + FlowInfo flowInfo) { + + breakLabel = new Label(); + continueLabel = new Label(); + + Constant cst = this.condition.constant; + boolean isConditionTrue = cst != NotAConstant && cst.booleanValue() == true; + boolean isConditionFalse = cst != NotAConstant && cst.booleanValue() == false; + + cst = this.condition.optimizedBooleanConstant(); + boolean isConditionOptimizedTrue = cst != NotAConstant && cst.booleanValue() == true; + boolean isConditionOptimizedFalse = cst != NotAConstant && cst.booleanValue() == false; + + preCondInitStateIndex = + currentScope.methodScope().recordInitializationStates(flowInfo); + LoopingFlowContext condLoopContext; + FlowInfo postCondInfo = + this.condition.analyseCode( + currentScope, + (condLoopContext = + new LoopingFlowContext(flowContext, this, null, null, currentScope)), + flowInfo); + + LoopingFlowContext loopingContext; + FlowInfo actionInfo; +// if (action == null +// || (action.isEmptyBlock() && currentScope.environment().options.complianceLevel <= CompilerOptions.JDK1_3)) { +// condLoopContext.complainOnFinalAssignmentsInLoop(currentScope, postCondInfo); +// if (isConditionTrue) { +// return FlowInfo.DEAD_END; +// } else { +// FlowInfo mergedInfo = postCondInfo.initsWhenFalse().unconditionalInits(); +// if (isConditionOptimizedTrue){ +// mergedInfo.setReachMode(FlowInfo.UNREACHABLE); +// } +// mergedInitStateIndex = +// currentScope.methodScope().recordInitializationStates(mergedInfo); +// return mergedInfo; +// } +// } else { + // in case the condition was inlined to false, record the fact that there is no way to reach any + // statement inside the looping action + loopingContext = + new LoopingFlowContext( + flowContext, + this, + breakLabel, + continueLabel, + currentScope); + if (isConditionFalse) { + actionInfo = FlowInfo.DEAD_END; + } else { + actionInfo = postCondInfo.initsWhenTrue().copy(); + if (isConditionOptimizedFalse){ + actionInfo.setReachMode(FlowInfo.UNREACHABLE); + } + } + + // for computing local var attributes + condIfTrueInitStateIndex = + currentScope.methodScope().recordInitializationStates( + postCondInfo.initsWhenTrue()); + + if (!actionInfo.complainIfUnreachable(action, currentScope, false)) { + actionInfo = action.analyseCode(currentScope, loopingContext, actionInfo); + } + + // code generation can be optimized when no need to continue in the loop + if (!actionInfo.isReachable() && !loopingContext.initsOnContinue.isReachable()) { + continueLabel = null; + } else { + // TODO: (philippe) should simplify in one Loop context + condLoopContext.complainOnFinalAssignmentsInLoop(currentScope, postCondInfo); + loopingContext.complainOnFinalAssignmentsInLoop(currentScope, actionInfo); + } +// } + + // infinite loop + FlowInfo mergedInfo; + if (isConditionOptimizedTrue) { + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates( + mergedInfo = loopingContext.initsOnBreak); + return mergedInfo; + } + + // end of loop: either condition false or break + mergedInfo = + postCondInfo.initsWhenFalse().unconditionalInits().mergedWith( + loopingContext.initsOnBreak); + if (isConditionOptimizedTrue && continueLabel == null){ + mergedInfo.setReachMode(FlowInfo.UNREACHABLE); + } + mergedInitStateIndex = + currentScope.methodScope().recordInitializationStates(mergedInfo); + return mergedInfo; + } + + /** + * While code generation + * + * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope + * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + */ +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// breakLabel.codeStream = codeStream; +// +// // generate condition +// if (continueLabel == null) { +// // no need to reverse condition +// if (condition.constant == NotAConstant) { +// condition.generateOptimizedBoolean( +// currentScope, +// codeStream, +// null, +// breakLabel, +// true); +// } +// } else { +// continueLabel.codeStream = codeStream; +// if (!(((condition.constant != NotAConstant) +// && (condition.constant.booleanValue() == true)) +// || (action == null) +// || action.isEmptyBlock())) { +// int jumpPC = codeStream.position; +// codeStream.goto_(continueLabel); +// codeStream.recordPositionsFrom(jumpPC, condition.sourceStart); +// } +// } +// // generate the action +// Label actionLabel; +// (actionLabel = new Label(codeStream)).place(); +// if (action != null) { +// // Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect +// if (condIfTrueInitStateIndex != -1) { +// // insert all locals initialized inside the condition into the action generated prior to the condition +// codeStream.addDefinitelyAssignedVariables( +// currentScope, +// condIfTrueInitStateIndex); +// } +// action.generateCode(currentScope, codeStream); +// // May loose some local variable initializations : affecting the local variable attributes +// if (preCondInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// preCondInitStateIndex); +// } +// +// } +// // output condition and branch back to the beginning of the repeated action +// if (continueLabel != null) { +// continueLabel.place(); +// condition.generateOptimizedBoolean( +// currentScope, +// codeStream, +// actionLabel, +// null, +// true); +// } +// breakLabel.place(); +// +// // May loose some local variable initializations : affecting the local variable attributes +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + + public void resetStateForCodeGeneration() { + if (this.breakLabel != null) { + this.breakLabel.resetStateForCodeGeneration(); + } + if (this.continueLabel != null) { + this.continueLabel.resetStateForCodeGeneration(); + } + } + + public void resolve(BlockScope scope) { + + TypeBinding type = condition.resolveTypeExpecting(scope, BooleanBinding); + condition.implicitWidening(type, type); + if (action != null) + action.resolve(scope); + } + + public String toString(int tab) { + + String s = tabString(tab); + s = s + "while (" + condition.toStringExpression() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + if (action == null) + s = s + " {} ;"; //$NON-NLS-1$ + else if (action instanceof Block) + s = s + "\n" + action.toString(tab + 1); //$NON-NLS-1$ + else + s = s + " {\n" + action.toString(tab + 1) + "}"; //$NON-NLS-2$ //$NON-NLS-1$ + return s; + } + + public void traverse( + IAbstractSyntaxTreeVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + condition.traverse(visitor, blockScope); + if (action != null) + action.traverse(visitor, blockScope); + } + visitor.endVisit(this, blockScope); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_DE.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_DE.properties new file mode 100644 index 0000000..d522c65 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_DE.properties @@ -0,0 +1,82 @@ +######################################### +# PHPProjectLibraryPage +######################################### + +PHPProjectLibraryPage.elementNotIProject=FEHLER: Element ist kein IProject +PHPProjectLibraryPage.project=Projekt +PHPProjectLibraryPage.tabName=Projekte + + +######################################### +# Property Pages +######################################### + +PHPProjectPropertyPage.phpProjectClosed=Das ausgewählte Projekt ist ein PHP Projekt, aber es ist geschlossen. +PHPProjectPropertyPage.performOkExceptionDialogTitle=Kann nicht sichern +PHPProjectPropertyPage.performOkExceptionDialogMessage=FEHLER: Kann die Projekt Eigenschaften nicht sichern + +PHPObfuscatorPropertyPage.hasnature=PHP Projekt. +PHPObfuscatorPropertyPage.publish=Obfuscator Ausgabe Verzeichnis: +PHPObfuscatorPropertyPage.dialogtitle=PHP +PHPObfuscatorPropertyPage.projecterror=Kann das neue Projekt nicht anlegen. +PHPObfuscatorPropertyPage.properties=PHP Obfuscator Projekt Eigenschaften + +######################################### +# Preference Pages +######################################### +PHPBasePreferencePage.description=PHP Voreinstellungen +PHPBasePreferencePage.websettingsGroup=Webserver Einstellungen +PHPBasePreferencePage.websettingsGroup.localhost=Localhost +PHPBasePreferencePage.websettingsGroup.docroot=DocumentRoot +PHPBasePreferencePage.websettingsGroup.browser=Externes Browser Kommando +PHPBasePreferencePage.websettingsGroup.useexternal=Benutze externen Browser +PHPBasePreferencePage.websettingsGroup.showexternalpreview=Vorschau beim Öffnen des Editors (nur win32) +PHPBasePreferencePage.apacheGroup=Apache Einstellungen +PHPBasePreferencePage.apacheGroup.run=Apache +PHPBasePreferencePage.apacheGroup.start=Start Apache +PHPBasePreferencePage.apacheGroup.start_background=Im Hintergrund ausführen? +PHPBasePreferencePage.apacheGroup.stop=Stop Apache +PHPBasePreferencePage.apacheGroup.stop_background=Im Hintergrund ausführen? +PHPBasePreferencePage.apacheGroup.restart=Restart Apache +PHPBasePreferencePage.apacheGroup.restart_background=Im Hintergrund ausführen? +PHPBasePreferencePage.console.php=Run PHP command +PHPBasePreferencePage.mySQLGroup=MySQL Einstellungen +PHPBasePreferencePage.mySQLGroup.run=MySQL +PHPBasePreferencePage.mySQLGroup.start_background=Im Hintergrund ausführen? +PHPBasePreferencePage.mySQLGroup.command=Start MySQL + +PHPBasePreferencePage.parsers=Parser Einstellungen +PHPBasePreferencePage.parsers.pos=Parse beim Sichern +PHPBasePreferencePage.parsers.external=Externer Parser +PHPBasePreferencePage.parsers.internal=Interner Parser +PHPBasePreferencePage.parsers.extcommand=Parser command +PHPBasePreferencePage.parsers.choose=PHP Parser auswählen + +PHPEditorSyntaxPreferencePage.description:PHP Editor Preferences +PHPEditorSyntaxPreferencePage.background:Background settings +PHPEditorSyntaxPreferencePage.foreground:Foreground settings +PHPEditorSyntaxPreferencePage.syntax:Syntax highlighting +PHPEditorSyntaxPreferencePage.color:Colour +PHPEditorSyntaxPreferencePage.bold:Bold +PHPEditorSyntaxPreferencePage.italic:Italic +PHPEditorSyntaxPreferencePage.underline:Underline +PHPEditorSyntaxPreferencePage.multiLineComment=Multi-line comment +PHPEditorSyntaxPreferencePage.singleLineComment=Single-line comment +PHPEditorSyntaxPreferencePage.keywords=Keywords +PHPEditorSyntaxPreferencePage.variables=Variables +PHPEditorSyntaxPreferencePage.types=Types +PHPEditorSyntaxPreferencePage.functions=Functions +PHPEditorSyntaxPreferencePage.constants=Constants +PHPEditorSyntaxPreferencePage.strings=Strings +PHPEditorSyntaxPreferencePage.others=Others +PHPEditorSyntaxPreferencePage.syntaxdialog=Custom PHP Syntax File: +PHPEditorSyntaxPreferencePage.browse=Browse.. +PHPEditorSyntaxPreferencePage.textfont=Text font + +PHPLanguagePreferencePage.description=PHP Editor Language +PHPLanguagePreferencePage.preflingo=PHP Language Preference +PHPLanguagePreferencePage.choose=Choose Language +PHPLanguagePreferencePage.english=Englisch +PHPLanguagePreferencePage.german=Deutsch +PHPLanguagePreferencePage.french=Frensch +PHPLanguagePreferencePage.spanish=Spanish diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_FR.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_FR.properties new file mode 100644 index 0000000..9e03703 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_FR.properties @@ -0,0 +1,82 @@ +######################################### +# PHPProjectLibraryPage +######################################### + +PHPProjectLibraryPage.elementNotIProject=ERREUR: L'élément n'est pas un IProject +PHPProjectLibraryPage.project=Projet +PHPProjectLibraryPage.tabName=Projets + + +######################################### +# Property Pages +######################################### + +PHPProjectPropertyPage.phpProjectClosed=Le project choisi est un projet PHP, mais est fermé. +PHPProjectPropertyPage.performOkExceptionDialogTitle=Impossible de sauver +PHPProjectPropertyPage.performOkExceptionDialogMessage=ERREUR: Impossible de sauver les propriétés du projet. + +PHPObfuscatorPropertyPage.hasnature=Is PHP project. +PHPObfuscatorPropertyPage.publish=Obfuscator directory: +PHPObfuscatorPropertyPage.dialogtitle=PHP +PHPObfuscatorPropertyPage.projecterror=Could not create the new project. +PHPObfuscatorPropertyPage.properties=PHP Obfuscator Project Properties + +######################################### +# Preference Pages +######################################### +PHPBasePreferencePage.description=PHP Preferences +PHPBasePreferencePage.websettingsGroup=Configuration du serveur Web +PHPBasePreferencePage.websettingsGroup.localhost=Localhost +PHPBasePreferencePage.websettingsGroup.docroot=DocumentRoot +PHPBasePreferencePage.websettingsGroup.browser=Commande du navigateur externe +PHPBasePreferencePage.websettingsGroup.useexternal=Utiliser navigateur externe +PHPBasePreferencePage.websettingsGroup.showexternalpreview=Show preview on editor load (win32 only) +PHPBasePreferencePage.apacheGroup=Configuration Apache +PHPBasePreferencePage.apacheGroup.run=Apache +PHPBasePreferencePage.apacheGroup.start=Lancer Apache +PHPBasePreferencePage.apacheGroup.start_background=Run in background mode +PHPBasePreferencePage.apacheGroup.stop=Stopper Apache +PHPBasePreferencePage.apacheGroup.stop_background=Run in background mode +PHPBasePreferencePage.apacheGroup.restart=Relancer Apache +PHPBasePreferencePage.apacheGroup.restart_background=Run in background mode +PHPBasePreferencePage.console.php=Run PHP command +PHPBasePreferencePage.mySQLGroup=Configuration MySQL +PHPBasePreferencePage.mySQLGroup.run=MySQL +PHPBasePreferencePage.mySQLGroup.start_background=Run in background mode +PHPBasePreferencePage.mySQLGroup.command=Lancer MySQL + +PHPBasePreferencePage.parsers=Configuration de parsing +PHPBasePreferencePage.parsers.pos=Parser à la sauvegarde +PHPBasePreferencePage.parsers.external=Externe +PHPBasePreferencePage.parsers.internal=Interne +PHPBasePreferencePage.parsers.extcommand=Parser command +PHPBasePreferencePage.parsers.choose=Choisissez un parseur PHP + +PHPEditorSyntaxPreferencePage.description:Configuration de l'éditeur PHP +PHPEditorSyntaxPreferencePage.background:Paramètres d'arrière plan +PHPEditorSyntaxPreferencePage.foreground:Paramètres d'avant plan +PHPEditorSyntaxPreferencePage.syntax:Coloration syntaxique +PHPEditorSyntaxPreferencePage.color:Couleur +PHPEditorSyntaxPreferencePage.bold:Gras +PHPEditorSyntaxPreferencePage.italic:Italique +PHPEditorSyntaxPreferencePage.underline:Sousligné +PHPEditorSyntaxPreferencePage.multiLineComment=Commentaire Multi-ligne +PHPEditorSyntaxPreferencePage.singleLineComment=Commenaire Mono-ligne +PHPEditorSyntaxPreferencePage.keywords=Mots clef +PHPEditorSyntaxPreferencePage.variables=Variables +PHPEditorSyntaxPreferencePage.types=Types +PHPEditorSyntaxPreferencePage.functions=Fonctions +PHPEditorSyntaxPreferencePage.constants=Constantes +PHPEditorSyntaxPreferencePage.strings=Strings +PHPEditorSyntaxPreferencePage.others=Autres +PHPEditorSyntaxPreferencePage.syntaxdialog=Fichier de syntaxe PHP personnalisé : +PHPEditorSyntaxPreferencePage.browse=Parcourir.. +PHPEditorSyntaxPreferencePage.textfont=Text font + +PHPLanguagePreferencePage.description=PHP Langue de l'éditeur +PHPLanguagePreferencePage.preflingo=PHP Configuration de langue +PHPLanguagePreferencePage.choose=Choisissez une langue +PHPLanguagePreferencePage.english=English +PHPLanguagePreferencePage.german=Deutsch +PHPLanguagePreferencePage.french=Francais +PHPLanguagePreferencePage.spanish=Spanish diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_en_GB.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_en_GB.properties new file mode 100644 index 0000000..c02902b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_en_GB.properties @@ -0,0 +1,81 @@ +######################################### +# PHPProjectLibraryPage +######################################### + +PHPProjectLibraryPage.elementNotIProject=ERROR: Element not IProject +PHPProjectLibraryPage.project=Project +PHPProjectLibraryPage.tabName=Projects + + +######################################### +# Property Pages +######################################### + +PHPProjectPropertyPage.phpProjectClosed=The project selected is a PHP project, but is closed. +PHPProjectPropertyPage.performOkExceptionDialogTitle=Unable to save +PHPProjectPropertyPage.performOkExceptionDialogMessage=ERROR: Unable to save project properties. + +PHPObfuscatorPropertyPage.hasnature=Is PHP project. +PHPObfuscatorPropertyPage.publish=Obfuscator directory: +PHPObfuscatorPropertyPage.dialogtitle=PHP +PHPObfuscatorPropertyPage.projecterror=Could not create the new project. +PHPObfuscatorPropertyPage.properties=PHP Obfuscator Project Properties + +######################################### +# Preference Pages +######################################### +PHPBasePreferencePage.description=PHP Preferences +PHPBasePreferencePage.websettingsGroup=Webserver Settings +PHPBasePreferencePage.websettingsGroup.localhost=Localhost +PHPBasePreferencePage.websettingsGroup.docroot=DocumentRoot +PHPBasePreferencePage.websettingsGroup.browser=External browser command +PHPBasePreferencePage.websettingsGroup.useexternal=Use external browser +PHPBasePreferencePage.websettingsGroup.showexternalpreview=Show preview on editor load (win32 only) +PHPBasePreferencePage.apacheGroup=Apache Settings +PHPBasePreferencePage.apacheGroup.run=Apache +PHPBasePreferencePage.apacheGroup.start=Start Apache +PHPBasePreferencePage.apacheGroup.start_background=Run in background mode +PHPBasePreferencePage.apacheGroup.stop=Stop Apache +PHPBasePreferencePage.apacheGroup.stop_background=Run in background mode +PHPBasePreferencePage.apacheGroup.restart=Restart Apache +PHPBasePreferencePage.apacheGroup.restart_background=Run in background mode +PHPBasePreferencePage.console.php=Run PHP command +PHPBasePreferencePage.mySQLGroup=MySQL Settings +PHPBasePreferencePage.mySQLGroup.run=MySQL +PHPBasePreferencePage.mySQLGroup.start_background=Run in background mode +PHPBasePreferencePage.mySQLGroup.command=Start MySQL +PHPBasePreferencePage.parsers=Parsing settings +PHPBasePreferencePage.parsers.pos=Parse on save +PHPBasePreferencePage.parsers.external=External +PHPBasePreferencePage.parsers.internal=Internal +PHPBasePreferencePage.parsers.extcommand=Parser command +PHPBasePreferencePage.parsers.choose=Choose PHP Parser + +PHPEditorSyntaxPreferencePage.description:PHP Editor Preferences +PHPEditorSyntaxPreferencePage.background:Background settings +PHPEditorSyntaxPreferencePage.foreground:Foreground settings +PHPEditorSyntaxPreferencePage.syntax:Syntax highlighting +PHPEditorSyntaxPreferencePage.color:Colour +PHPEditorSyntaxPreferencePage.bold:Bold +PHPEditorSyntaxPreferencePage.italic:Italic +PHPEditorSyntaxPreferencePage.underline:Underline +PHPEditorSyntaxPreferencePage.multiLineComment=Multi-line comment +PHPEditorSyntaxPreferencePage.singleLineComment=Single-line comment +PHPEditorSyntaxPreferencePage.keywords=Keywords +PHPEditorSyntaxPreferencePage.variables=Variables +PHPEditorSyntaxPreferencePage.types=Types +PHPEditorSyntaxPreferencePage.functions=Functions +PHPEditorSyntaxPreferencePage.constants=Constants +PHPEditorSyntaxPreferencePage.strings=Strings +PHPEditorSyntaxPreferencePage.others=Others +PHPEditorSyntaxPreferencePage.syntaxdialog=Custom PHP Syntax File: +PHPEditorSyntaxPreferencePage.browse=Browse.. +PHPEditorSyntaxPreferencePage.textfont=Text font + +PHPLanguagePreferencePage.description=PHP Editor Language +PHPLanguagePreferencePage.preflingo=PHP Language Preference +PHPLanguagePreferencePage.choose=Choose Language +PHPLanguagePreferencePage.english=English +PHPLanguagePreferencePage.german=German +PHPLanguagePreferencePage.french=French +PHPLanguagePreferencePage.spanish=Spanish diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_es_ES.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_es_ES.properties new file mode 100644 index 0000000..a93dd07 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_es_ES.properties @@ -0,0 +1,84 @@ +######################################### +# PHPProjectLibraryPage +######################################### + +PHPProjectLibraryPage.elementNotIProject=ERROR: El elemento no es IProject +PHPProjectLibraryPage.project=Proyecto +PHPProjectLibraryPage.tabName=Proyectos + + +######################################### +# Property Pages +######################################### + +PHPProjectPropertyPage.phpProjectClosed=El proyecto seleccionado es un proyecto PHP, pero está cerrado. +PHPProjectPropertyPage.performOkExceptionDialogTitle=No se pudo guardar. +PHPProjectPropertyPage.performOkExceptionDialogMessage=ERROR: No se pudo guardar las propiedades del proyecto. + +PHPObfuscatorPropertyPage.hasnature=Is PHP project. +PHPObfuscatorPropertyPage.publish=Obfuscator directory: +PHPObfuscatorPropertyPage.dialogtitle=PHP +PHPObfuscatorPropertyPage.projecterror=Could not create the new project. +PHPObfuscatorPropertyPage.properties=PHP Obfuscator Project Properties + +######################################### +# Preference Pages +######################################### +PHPBasePreferencePage.description=Preferencias PHP +PHPBasePreferencePage.websettingsGroup=Configuración Webserver +PHPBasePreferencePage.websettingsGroup.localhost=Localhost +PHPBasePreferencePage.websettingsGroup.docroot=DocumentRoot +PHPBasePreferencePage.websettingsGroup.browser=Comando navegador externo +PHPBasePreferencePage.websettingsGroup.useexternal=Usar navegador externo +PHPBasePreferencePage.websettingsGroup.showexternalpreview=Show preview on editor load (win32 only) +PHPBasePreferencePage.apacheGroup=Configuración Apache +PHPBasePreferencePage.apacheGroup.run=Apache +PHPBasePreferencePage.apacheGroup.start=Arranchar Apache +PHPBasePreferencePage.apacheGroup.start_background=Run in background mode +PHPBasePreferencePage.apacheGroup.stop=Parar Apache +PHPBasePreferencePage.apacheGroup.stop_background=Run in background mode +PHPBasePreferencePage.apacheGroup.restart=Reiniciar Apache +PHPBasePreferencePage.apacheGroup.restart_background=Run in background mode +PHPBasePreferencePage.console.php=Run PHP command +PHPBasePreferencePage.mySQLGroup=Configuración MySQL +PHPBasePreferencePage.mySQLGroup.run=MySQL +PHPBasePreferencePage.mySQLGroup.start_background=Run in background mode +PHPBasePreferencePage.mySQLGroup.command=Arranchar MySQL + +PHPBasePreferencePage.console.php=Run PHP command + +PHPBasePreferencePage.parsers=Configuración Parser +PHPBasePreferencePage.parsers.pos=Parsear al guardar +PHPBasePreferencePage.parsers.external=Externo +PHPBasePreferencePage.parsers.internal=Interno +PHPBasePreferencePage.parsers.extcommand=Parser command +PHPBasePreferencePage.parsers.choose=Escoja Parser PHP + +PHPEditorSyntaxPreferencePage.description:Preferencias Editor PHP +PHPEditorSyntaxPreferencePage.background:Background settings +PHPEditorSyntaxPreferencePage.foreground:Preferencias primer plano +PHPEditorSyntaxPreferencePage.syntax:Resaltar sintaxis +PHPEditorSyntaxPreferencePage.color:Color +PHPEditorSyntaxPreferencePage.bold:Negrita +PHPEditorSyntaxPreferencePage.italic:Cursiva +PHPEditorSyntaxPreferencePage.underline:Subrayado +PHPEditorSyntaxPreferencePage.multiLineComment=Comentario varias líneas +PHPEditorSyntaxPreferencePage.singleLineComment=Comentario una línia +PHPEditorSyntaxPreferencePage.keywords=Palabras clave +PHPEditorSyntaxPreferencePage.variables=Variables +PHPEditorSyntaxPreferencePage.types=Tipos +PHPEditorSyntaxPreferencePage.functions=Funciones +PHPEditorSyntaxPreferencePage.constants=Constantes +PHPEditorSyntaxPreferencePage.strings=Cadenas +PHPEditorSyntaxPreferencePage.others=Otros +PHPEditorSyntaxPreferencePage.syntaxdialog=Fichero de sintaxis personalizado: +PHPEditorSyntaxPreferencePage.browse=Examinar.. +PHPEditorSyntaxPreferencePage.textfont=Fuente del texto + +PHPLanguagePreferencePage.description=Idioma editor PHP +PHPLanguagePreferencePage.preflingo=Configuración idioma PHP +PHPLanguagePreferencePage.choose=Escoja idioma +PHPLanguagePreferencePage.english=Inglés +PHPLanguagePreferencePage.german=Alemán +PHPLanguagePreferencePage.french=Francés +PHPLanguagePreferencePage.spanish=Español diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/CompilationUnitAnnotationModelEvent.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/CompilationUnitAnnotationModelEvent.java new file mode 100644 index 0000000..069e68b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/CompilationUnitAnnotationModelEvent.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.phpeditor; + + + +import org.eclipse.core.resources.IResource; + +import org.eclipse.jface.text.source.AnnotationModelEvent; +import org.eclipse.jface.text.source.IAnnotationModel; + +/** + * Event sent out by changes of the compilation unit annotation model. + */ +public class CompilationUnitAnnotationModelEvent extends AnnotationModelEvent { + + private boolean fIncludesMarkerAnnotationChanges; + private IResource fUnderlyingResource; + + + /** + * Constructor for CompilationUnitAnnotationModelEvent. + * @param model + * @param underlyingResource The annotation model's underlying resource + * @param includesMarkerAnnotationChanges + */ + public CompilationUnitAnnotationModelEvent(IAnnotationModel model, IResource underlyingResource, boolean includesMarkerAnnotationChanges) { + super(model); + fIncludesMarkerAnnotationChanges= includesMarkerAnnotationChanges; + fUnderlyingResource= underlyingResource; + } + + /** + * Returns whether the change included marker annotations. + * + * @return true if the change included marker annotations + */ + public boolean includesMarkerAnnotationChanges() { + return fIncludesMarkerAnnotationChanges; + } + + /** + * Returns the annotation model's underlying resource + */ + public IResource getUnderlyingResource() { + return fUnderlyingResource; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/DocumentAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/DocumentAdapter.java new file mode 100644 index 0000000..70e1767 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/DocumentAdapter.java @@ -0,0 +1,492 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package net.sourceforge.phpeclipse.phpeditor; + + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import net.sourceforge.phpdt.core.BufferChangedEvent; +import net.sourceforge.phpdt.core.IBuffer; +import net.sourceforge.phpdt.core.IBufferChangedListener; +import net.sourceforge.phpdt.core.IOpenable; +import net.sourceforge.phpdt.core.JavaModelException; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.text.Assert; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentListener; +import org.eclipse.jface.text.ILineTracker; +import org.eclipse.jface.text.IRegion; +import org.eclipse.swt.widgets.Display; + + + +/** + * Adapts IDocument to IBuffer. Uses the + * same algorithm as the text widget to determine the buffer's line delimiter. + * All text inserted into the buffer is converted to this line delimiter. + * This class is public for test purposes only. + */ +public class DocumentAdapter implements IBuffer, IDocumentListener { + + /** + * Internal implementation of a NULL instanceof IBuffer. + */ + static private class NullBuffer implements IBuffer { + + public void addBufferChangedListener(IBufferChangedListener listener) {} + + public void append(char[] text) {} + + public void append(String text) {} + + public void close() {} + + public char getChar(int position) { + return 0; + } + + public char[] getCharacters() { + return null; + } + + public String getContents() { + return null; + } + + public int getLength() { + return 0; + } + + public IOpenable getOwner() { + return null; + } + + public String getText(int offset, int length) { + return null; + } + + public IResource getUnderlyingResource() { + return null; + } + + public boolean hasUnsavedChanges() { + return false; + } + + public boolean isClosed() { + return false; + } + + public boolean isReadOnly() { + return true; + } + + public void removeBufferChangedListener(IBufferChangedListener listener) {} + + public void replace(int position, int length, char[] text) {} + + public void replace(int position, int length, String text) {} + + public void save(IProgressMonitor progress, boolean force) throws JavaModelException {} + + public void setContents(char[] contents) {} + + public void setContents(String contents) {} + }; + + + /** NULL implementing IBuffer */ + public final static IBuffer NULL= new NullBuffer(); + + + /** + * Executes a document set content call in the ui thread. + */ + protected class DocumentSetCommand implements Runnable { + + private String fContents; + + public void run() { + fDocument.set(fContents); + } + + public void set(String contents) { + fContents= contents; + Display.getDefault().syncExec(this); + } + }; + + /** + * Executes a document replace call in the ui thread. + */ + protected class DocumentReplaceCommand implements Runnable { + + private int fOffset; + private int fLength; + private String fText; + + public void run() { + try { + fDocument.replace(fOffset, fLength, fText); + } catch (BadLocationException x) { + // ignore + } + } + + public void replace(int offset, int length, String text) { + fOffset= offset; + fLength= length; + fText= text; + Display.getDefault().syncExec(this); + } + }; + + private IOpenable fOwner; + private IDocument fDocument; + private DocumentSetCommand fSetCmd= new DocumentSetCommand(); + private DocumentReplaceCommand fReplaceCmd= new DocumentReplaceCommand(); + + private Object fProviderKey; + private PHPDocumentProvider fProvider; + private String fLineDelimiter; + private ILineTracker fLineTracker; + + private List fBufferListeners= new ArrayList(3); + + private IStatus fStatus; + + /** + * This method is public for test purposes only. + */ + public DocumentAdapter(IOpenable owner, IDocument document, ILineTracker lineTracker, PHPDocumentProvider provider, Object providerKey) { + + Assert.isNotNull(document); + Assert.isNotNull(lineTracker); + + fOwner= owner; + fDocument= document; + fLineTracker= lineTracker; + fProvider= provider; + fProviderKey= providerKey; + + fDocument.addPrenotifiedDocumentListener(this); + } + + /** + * Sets the status of this document adapter. + */ + public void setStatus(IStatus status) { + fStatus= status; + } + + /** + * Returns the status of this document adapter. + */ + public IStatus getStatus() { + return fStatus; + } + + /** + * Returns the adapted document. + * + * @return the adapted document + */ + public IDocument getDocument() { + return fDocument; + } + + /** + * Returns the line delimiter of this buffer. As a document has a set of + * valid line delimiters, this set must be reduced to size 1. + */ + protected String getLineDelimiter() { + + if (fLineDelimiter == null) { + + try { + fLineDelimiter= fDocument.getLineDelimiter(0); + } catch (BadLocationException x) { + } + + if (fLineDelimiter == null) { + /* + * Follow up fix for: 1GF5UU0: ITPJUI:WIN2000 - "Organize Imports" in java editor inserts lines in wrong format + * The line delimiter must always be a legal document line delimiter. + */ + String sysLineDelimiter= System.getProperty("line.separator"); //$NON-NLS-1$ + String[] delimiters= fDocument.getLegalLineDelimiters(); + Assert.isTrue(delimiters.length > 0); + for (int i= 0; i < delimiters.length; i++) { + if (delimiters[i].equals(sysLineDelimiter)) { + fLineDelimiter= sysLineDelimiter; + break; + } + } + + if (fLineDelimiter == null) { + // system line delimiter is not a legal document line delimiter + fLineDelimiter= delimiters[0]; + } + } + } + + return fLineDelimiter; + } + + /** + * Converts the given string to the line delimiter of this buffer. + * This method is public for test purposes only. + */ + public String normalize(String text) { + fLineTracker.set(text); + + int lines= fLineTracker.getNumberOfLines(); + if (lines <= 1) + return text; + + StringBuffer buffer= new StringBuffer(text); + + try { + IRegion previous= fLineTracker.getLineInformation(0); + for (int i= 1; i < lines; i++) { + int lastLineEnd= previous.getOffset() + previous.getLength(); + int lineStart= fLineTracker.getLineInformation(i).getOffset(); + fLineTracker.replace(lastLineEnd, lineStart - lastLineEnd, getLineDelimiter()); + buffer.replace(lastLineEnd, lineStart, getLineDelimiter()); + previous= fLineTracker.getLineInformation(i); + } + + // last line + String delimiter= fLineTracker.getLineDelimiter(lines -1); + if (delimiter != null && delimiter.length() > 0) + buffer.replace(previous.getOffset() + previous.getLength(), buffer.length(), getLineDelimiter()); + + return buffer.toString(); + } catch (BadLocationException x) { + } + + return text; + } + + /* + * @see IBuffer#addBufferChangedListener(IBufferChangedListener) + */ + public void addBufferChangedListener(IBufferChangedListener listener) { + Assert.isNotNull(listener); + if (!fBufferListeners.contains(listener)) + fBufferListeners.add(listener); + } + + /* + * @see IBuffer#removeBufferChangedListener(IBufferChangedListener) + */ + public void removeBufferChangedListener(IBufferChangedListener listener) { + Assert.isNotNull(listener); + fBufferListeners.remove(listener); + } + + /* + * @see IBuffer#append(char[]) + */ + public void append(char[] text) { + append(new String(text)); + } + + /* + * @see IBuffer#append(String) + */ + public void append(String text) { + fReplaceCmd.replace(fDocument.getLength(), 0, normalize(text)); + } + + /* + * @see IBuffer#close() + */ + public void close() { + + if (isClosed()) + return; + + IDocument d= fDocument; + fDocument= null; + d.removePrenotifiedDocumentListener(this); + + fireBufferChanged(new BufferChangedEvent(this, 0, 0, null)); + fBufferListeners.clear(); + } + + /* + * @see IBuffer#getChar(int) + */ + public char getChar(int position) { + try { + return fDocument.getChar(position); + } catch (BadLocationException x) { + throw new ArrayIndexOutOfBoundsException(); + } + } + + /* + * @see IBuffer#getCharacters() + */ + public char[] getCharacters() { + String content= getContents(); + return content == null ? null : content.toCharArray(); + } + + /* + * @see IBuffer#getContents() + */ + public String getContents() { + return fDocument.get(); + } + + /* + * @see IBuffer#getLength() + */ + public int getLength() { + return fDocument.getLength(); + } + + /* + * @see IBuffer#getOwner() + */ + public IOpenable getOwner() { + return (IOpenable) fOwner; + } + + /* + * @see IBuffer#getText(int, int) + */ + public String getText(int offset, int length) { + try { + return fDocument.get(offset, length); + } catch (BadLocationException x) { + throw new ArrayIndexOutOfBoundsException(); + } + } + + /* + * @see IBuffer#getUnderlyingResource() + */ + public IResource getUnderlyingResource() { + return fProvider != null ? fProvider.getUnderlyingResource(fProviderKey) : null; + } + + /* + * @see IBuffer#hasUnsavedChanges() + */ + public boolean hasUnsavedChanges() { + return fProvider != null ? fProvider.canSaveDocument(fProviderKey) : false; + } + + /* + * @see IBuffer#isClosed() + */ + public boolean isClosed() { + return fDocument == null; + } + + /* + * @see IBuffer#isReadOnly() + */ + public boolean isReadOnly() { + IResource resource= getUnderlyingResource(); + return resource == null ? true : resource.isReadOnly(); + } + + /* + * @see IBuffer#replace(int, int, char[]) + */ + public void replace(int position, int length, char[] text) { + replace(position, length, new String(text)); + } + + /* + * @see IBuffer#replace(int, int, String) + */ + public void replace(int position, int length, String text) { + fReplaceCmd.replace(position, length, normalize(text)); + } + + /* + * @see IBuffer#save(IProgressMonitor, boolean) + */ + public void save(IProgressMonitor progress, boolean force) throws JavaModelException { + if (fProvider != null) { + try { + fProvider.saveDocumentContent(progress, fProviderKey, fDocument, force); + } catch (CoreException e) { + throw new JavaModelException(e); + } + } + } + + /* + * @see IBuffer#setContents(char[]) + */ + public void setContents(char[] contents) { + setContents(new String(contents)); + } + + /* + * @see IBuffer#setContents(String) + */ + public void setContents(String contents) { + int oldLength= fDocument.getLength(); + + if (contents == null) { + + if (oldLength != 0) + fSetCmd.set(""); //$NON-NLS-1$ + + } else { + + // set only if different + String newContents= normalize(contents); + int newLength= newContents.length(); + + if (oldLength != newLength || !newContents.equals(fDocument.get())) + fSetCmd.set(newContents); + } + } + + /* + * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent event) { + // there is nothing to do here + } + + /* + * @see IDocumentListener#documentChanged(DocumentEvent) + */ + public void documentChanged(DocumentEvent event) { + fireBufferChanged(new BufferChangedEvent(this, event.getOffset(), event.getLength(), event.getText())); + } + + private void fireBufferChanged(BufferChangedEvent event) { + if (fBufferListeners != null && fBufferListeners.size() > 0) { + Iterator e= new ArrayList(fBufferListeners).iterator(); + while (e.hasNext()) + ((IBufferChangedListener) e.next()).bufferChanged(event); + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/EditorUtility.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/EditorUtility.java index 2cff713..b593805 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/EditorUtility.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/EditorUtility.java @@ -12,11 +12,17 @@ package net.sourceforge.phpeclipse.phpeditor; +import net.sourceforge.phpdt.core.ICompilationUnit; import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IMember; +import net.sourceforge.phpdt.core.IWorkingCopy; import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil; +import net.sourceforge.phpdt.ui.JavaUI; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; import org.eclipse.jface.action.Action; import org.eclipse.swt.SWT; import org.eclipse.ui.IEditorDescriptor; @@ -43,11 +49,11 @@ public class EditorUtility { public static boolean isEditorInput(Object element, IEditorPart editor) { if (editor != null) { -// try { + try { return editor.getEditorInput().equals(getEditorInput(element)); -// } catch (JavaModelException x) { -// JavaPlugin.log(x.getStatus()); -// } + } catch (JavaModelException x) { + PHPeclipsePlugin.log(x.getStatus()); + } } return false; } @@ -59,11 +65,11 @@ public class EditorUtility { public static IEditorPart isOpenInEditor(Object inputElement) { IEditorInput input= null; -// try { + try { input= getEditorInput(inputElement); -// } catch (JavaModelException x) { -// JavaPlugin.log(x.getStatus()); -// } + } catch (JavaModelException x) { + PHPeclipsePlugin.log(x.getStatus()); + } if (input != null) { IWorkbenchPage p= PHPeclipsePlugin.getActivePage(); @@ -108,11 +114,11 @@ public class EditorUtility { /** * Selects a Java Element in an editor */ -// public static void revealInEditor(IEditorPart part, IJavaElement element) { -// if (element != null && part instanceof PHPEditor) { -// ((PHPEditor) part).setSelection(element); -// } -// } + public static void revealInEditor(IEditorPart part, IJavaElement element) { + if (element != null && part instanceof PHPEditor) { + ((PHPEditor) part).setSelection(element); + } + } private static IEditorPart openInEditor(IFile file, boolean activate) throws PartInitException { if (file != null) { @@ -159,29 +165,28 @@ public class EditorUtility { return null; } -// private static IEditorInput getEditorInput(IJavaElement element) throws JavaModelException { -// while (element != null) { -// if (element instanceof IWorkingCopy && ((IWorkingCopy) element).isWorkingCopy()) -// element= ((IWorkingCopy) element).getOriginalElement(); -// -// if (element instanceof ICompilationUnit) { -// ICompilationUnit unit= (ICompilationUnit) element; -// IResource resource= unit.getResource(); -// if (resource instanceof IFile) -// return new FileEditorInput((IFile) resource); -// } -// + private static IEditorInput getEditorInput(IJavaElement element) throws JavaModelException { + while (element != null) { + if (element instanceof IWorkingCopy && ((IWorkingCopy) element).isWorkingCopy()) + element= ((IWorkingCopy) element).getOriginalElement(); + + if (element instanceof ICompilationUnit) { + ICompilationUnit unit= (ICompilationUnit) element; + IResource resource= unit.getResource(); + if (resource instanceof IFile) + return new FileEditorInput((IFile) resource); + } + // if (element instanceof IClassFile) // return new InternalClassFileEditorInput((IClassFile) element); // -// element= element.getParent(); -// } -// -// return null; -// } + element= element.getParent(); + } + + return null; + } - public static IEditorInput getEditorInput(Object input) { -// throws JavaModelException { + public static IEditorInput getEditorInput(Object input) throws JavaModelException { if (input instanceof IJavaElement) return getEditorInput((IJavaElement) input); @@ -219,14 +224,14 @@ public class EditorUtility { * @param cu the original compilation unit (or another working copy) * @return the working copy of the compilation unit, or null if not found */ -// public static ICompilationUnit getWorkingCopy(ICompilationUnit cu) { -// if (cu == null) -// return null; -// if (cu.isWorkingCopy()) -// return cu; -// -// return (ICompilationUnit)cu.findSharedWorkingCopy(JavaUI.getBufferFactory()); -// } + public static ICompilationUnit getWorkingCopy(ICompilationUnit cu) { + if (cu == null) + return null; + if (cu.isWorkingCopy()) + return cu; + + return (ICompilationUnit)cu.findSharedWorkingCopy(JavaUI.getBufferFactory()); + } /** * Gets the working copy of an member opened in an editor @@ -234,38 +239,38 @@ public class EditorUtility { * @param member the original member or a member in a working copy * @return the corresponding member in the shared working copy or null if not found */ -// public static IMember getWorkingCopy(IMember member) throws JavaModelException { -// ICompilationUnit cu= member.getCompilationUnit(); -// if (cu != null) { -// ICompilationUnit workingCopy= getWorkingCopy(cu); -// if (workingCopy != null) { -// return JavaModelUtil.findMemberInCompilationUnit(workingCopy, member); -// } -// } -// return null; -// } + public static IMember getWorkingCopy(IMember member) throws JavaModelException { + ICompilationUnit cu= member.getCompilationUnit(); + if (cu != null) { + ICompilationUnit workingCopy= getWorkingCopy(cu); + if (workingCopy != null) { + return JavaModelUtil.findMemberInCompilationUnit(workingCopy, member); + } + } + return null; + } /** * Returns the compilation unit for the given java element. * @param element the java element whose compilation unit is searched for * @return the compilation unit of the given java element */ -// private static ICompilationUnit getCompilationUnit(IJavaElement element) { -// -// if (element == null) -// return null; -// -// if (element instanceof IMember) -// return ((IMember) element).getCompilationUnit(); -// -// int type= element.getElementType(); -// if (IJavaElement.COMPILATION_UNIT == type) -// return (ICompilationUnit) element; -// if (IJavaElement.CLASS_FILE == type) -// return null; -// -// return getCompilationUnit(element.getParent()); -// } + private static ICompilationUnit getCompilationUnit(IJavaElement element) { + + if (element == null) + return null; + + if (element instanceof IMember) + return ((IMember) element).getCompilationUnit(); + + int type= element.getElementType(); + if (IJavaElement.COMPILATION_UNIT == type) + return (ICompilationUnit) element; + if (IJavaElement.CLASS_FILE == type) + return null; + + return getCompilationUnit(element.getParent()); + } /** * Returns the working copy of the given java element. @@ -273,28 +278,28 @@ public class EditorUtility { * @param reconcile indicates whether the working copy must be reconcile prior to searching it * @return the working copy of the given element or null if none */ -// public static IJavaElement getWorkingCopy(IJavaElement element, boolean reconcile) throws JavaModelException { -// ICompilationUnit unit= getCompilationUnit(element); -// if (unit == null) -// return null; -// -// if (unit.isWorkingCopy()) -// return element; -// -// ICompilationUnit workingCopy= getWorkingCopy(unit); -// if (workingCopy != null) { -// if (reconcile) { -// synchronized (workingCopy) { -// workingCopy.reconcile(); -// return JavaModelUtil.findInCompilationUnit(workingCopy, element); -// } -// } else { -// return JavaModelUtil.findInCompilationUnit(workingCopy, element); -// } -// } -// -// return null; -// } + public static IJavaElement getWorkingCopy(IJavaElement element, boolean reconcile) throws JavaModelException { + ICompilationUnit unit= getCompilationUnit(element); + if (unit == null) + return null; + + if (unit.isWorkingCopy()) + return element; + + ICompilationUnit workingCopy= getWorkingCopy(unit); + if (workingCopy != null) { + if (reconcile) { + synchronized (workingCopy) { + workingCopy.reconcile(); + return JavaModelUtil.findInCompilationUnit(workingCopy, element); + } + } else { + return JavaModelUtil.findInCompilationUnit(workingCopy, element); + } + } + + return null; + } /** * Maps the localized modifier name to a code in the same diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/GotoErrorAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/GotoErrorAction.java new file mode 100644 index 0000000..a4e1010 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/GotoErrorAction.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package net.sourceforge.phpeclipse.phpeditor; + +import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds; + +import org.eclipse.ui.help.WorkbenchHelp; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.TextEditorAction; + + +public class GotoErrorAction extends TextEditorAction { + + private boolean fForward; + + public GotoErrorAction(String prefix, boolean forward) { + super(PHPEditorMessages.getResourceBundle(), prefix, null); + fForward= forward; + if (forward) + WorkbenchHelp.setHelp(this, IJavaHelpContextIds.GOTO_NEXT_ERROR_ACTION); + else + WorkbenchHelp.setHelp(this, IJavaHelpContextIds.GOTO_PREVIOUS_ERROR_ACTION); + } + + public void run() { + PHPEditor e= (PHPEditor) getTextEditor(); + e.gotoError(fForward); + } + + public void setEditor(ITextEditor editor) { + if (editor instanceof PHPEditor) + super.setEditor(editor); + update(); + } + + public void update() { + setEnabled(getTextEditor() instanceof PHPEditor); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/IJavaEditorActionConstants.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/IJavaEditorActionConstants.java new file mode 100644 index 0000000..85b94d9 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/IJavaEditorActionConstants.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.phpeditor; + +/** + * Defines action IDs for private JavaEditor actions. + */ +public interface IJavaEditorActionConstants { + + /** + * ID of the action to toggle the style of the presentation. + */ + public static final String TOGGLE_PRESENTATION= "togglePresentation"; //$NON-NLS-1$ + + + /** + * ID of the toolbar action to go to the previous error. + */ + public static final String PREVIOUS_ERROR= "gotoPreviousError"; //$NON-NLS-1$ + + /** + * ID of the toolbar action to go to the next error. + */ + public static final String NEXT_ERROR= "gotoNextError"; //$NON-NLS-1$ +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/ISavePolicy.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/ISavePolicy.java new file mode 100644 index 0000000..4228763 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/ISavePolicy.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.phpeditor; + + + +import net.sourceforge.phpdt.core.ICompilationUnit; + +public interface ISavePolicy { + + /** + * + */ + void preSave(ICompilationUnit unit); + + /** + * Returns the compilation unit in which the argument + * has been changed. If the argument is not changed, the + * returned result is null. + */ + ICompilationUnit postSave(ICompilationUnit unit); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaEditorErrorTickUpdater.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaEditorErrorTickUpdater.java new file mode 100644 index 0000000..af78de1 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaEditorErrorTickUpdater.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.phpeditor; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.internal.ui.viewsupport.IProblemChangedListener; +import net.sourceforge.phpdt.internal.ui.viewsupport.JavaElementImageProvider; +import net.sourceforge.phpdt.internal.ui.viewsupport.JavaUILabelProvider; +import net.sourceforge.phpdt.ui.ProblemsLabelDecorator; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.text.Assert; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; + +/** + * The JavaEditorErrorTickUpdater will register as a IProblemChangedListener + * to listen on problem changes of the editor's input. It updates the title images when the annotation + * model changed. + */ +public class JavaEditorErrorTickUpdater implements IProblemChangedListener { + + private PHPEditor fJavaEditor; + private JavaUILabelProvider fLabelProvider; + + public JavaEditorErrorTickUpdater(PHPEditor editor) { + Assert.isNotNull(editor); + fJavaEditor= editor; + fLabelProvider= new JavaUILabelProvider(0, JavaElementImageProvider.SMALL_ICONS); + fLabelProvider.addLabelDecorator(new ProblemsLabelDecorator(null)); + PHPeclipsePlugin.getDefault().getProblemMarkerManager().addListener(this); + } + + /* (non-Javadoc) + * @see IProblemChangedListener#problemsChanged(IResource[], boolean) + */ + public void problemsChanged(IResource[] changedResources, boolean isMarkerChange) { + if (isMarkerChange) { + return; + } + IEditorInput input= fJavaEditor.getEditorInput(); + if (input != null) { // might run async, tests needed + IJavaElement jelement= (IJavaElement) input.getAdapter(IJavaElement.class); + if (jelement != null) { + IResource resource= jelement.getResource(); + for (int i = 0; i < changedResources.length; i++) { + if (changedResources[i].equals(resource)) { + updateEditorImage(jelement); + } + } + } + } + } + + public void updateEditorImage(IJavaElement jelement) { + Image titleImage= fJavaEditor.getTitleImage(); + if (titleImage == null) { + return; + } + Image newImage= fLabelProvider.getImage(jelement); + if (titleImage != newImage) { + postImageChange(newImage); + } + } + + private void postImageChange(final Image newImage) { + Shell shell= fJavaEditor.getEditorSite().getShell(); + if (shell != null && !shell.isDisposed()) { + shell.getDisplay().syncExec(new Runnable() { + public void run() { + fJavaEditor.updatedTitleImage(newImage); + } + }); + } + } + + public void dispose() { + fLabelProvider.dispose(); + PHPeclipsePlugin.getDefault().getProblemMarkerManager().removeListener(this); + } + + +} + + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaOutlinePage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaOutlinePage.java new file mode 100644 index 0000000..98681fa --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaOutlinePage.java @@ -0,0 +1,1171 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.phpeditor; + + +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.List; +import java.util.Vector; + +import net.sourceforge.phpdt.core.ElementChangedEvent; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IElementChangedListener; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaElementDelta; +import net.sourceforge.phpdt.core.IMember; +import net.sourceforge.phpdt.core.IMethod; +import net.sourceforge.phpdt.core.IParent; +import net.sourceforge.phpdt.core.ISourceRange; +import net.sourceforge.phpdt.core.ISourceReference; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.ui.PHPUiImages; +import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup; +import net.sourceforge.phpdt.internal.ui.packageview.SelectionTransferDragAdapter; +import net.sourceforge.phpdt.internal.ui.viewsupport.AppearanceAwareLabelProvider; +import net.sourceforge.phpdt.internal.ui.viewsupport.DecoratingJavaLabelProvider; +import net.sourceforge.phpdt.internal.ui.viewsupport.JavaElementLabels; +import net.sourceforge.phpdt.internal.ui.viewsupport.StatusBarUpdater; +import net.sourceforge.phpdt.ui.JavaElementSorter; +import net.sourceforge.phpdt.ui.JavaUI; +import net.sourceforge.phpdt.ui.PreferenceConstants; +import net.sourceforge.phpdt.ui.ProblemsLabelDecorator.ProblemsLabelChangedEvent; +import net.sourceforge.phpdt.ui.actions.GenerateActionGroup; +import net.sourceforge.phpdt.ui.actions.MemberFilterActionGroup; +import net.sourceforge.phpeclipse.PHPCore; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IAdaptable; +import net.sourceforge.phpdt.internal.ui.dnd.JdtViewerDragAdapter; +import net.sourceforge.phpdt.internal.ui.dnd.TransferDragSourceListener; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.Assert; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.ListenerList; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProviderChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.Widget; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.actions.ActionContext; +import org.eclipse.ui.actions.ActionGroup; +import org.eclipse.ui.internal.model.WorkbenchAdapter; +import org.eclipse.ui.model.IWorkbenchAdapter; +import org.eclipse.ui.part.IPageSite; +import org.eclipse.ui.part.IShowInSource; +import org.eclipse.ui.part.IShowInTarget; +import org.eclipse.ui.part.IShowInTargetList; +import org.eclipse.ui.part.Page; +import org.eclipse.ui.part.ShowInContext; +import org.eclipse.ui.texteditor.ITextEditorActionConstants; +import org.eclipse.ui.texteditor.IUpdate; +import org.eclipse.ui.texteditor.TextEditorAction; +import org.eclipse.ui.texteditor.TextOperationAction; +import org.eclipse.ui.views.contentoutline.IContentOutlinePage; +import org.eclipse.ui.views.navigator.LocalSelectionTransfer; + + + + + +/** + * The content outline page of the Java editor. The viewer implements a proprietary + * update mechanism based on Java model deltas. It does not react on domain changes. + * It is specified to show the content of ICompilationUnits and IClassFiles. + * Pulishes its context menu under JavaPlugin.getDefault().getPluginId() + ".outline". + */ +public class JavaOutlinePage extends Page implements IContentOutlinePage, IAdaptable { + + static Object[] NO_CHILDREN= new Object[0]; + + /** + * The element change listener of the java outline viewer. + * @see IElementChangedListener + */ + class ElementChangedListener implements IElementChangedListener { + + public void elementChanged(final ElementChangedEvent e) { + + if (getControl() == null) + return; + + Display d= getControl().getDisplay(); + if (d != null) { + d.asyncExec(new Runnable() { + public void run() { + ICompilationUnit cu= (ICompilationUnit) fInput; + IJavaElement base= cu; + if (fTopLevelTypeOnly) { + base= getMainType(cu); + if (base == null) { + if (fOutlineViewer != null) + fOutlineViewer.refresh(true); + return; + } + } + IJavaElementDelta delta= findElement(base, e.getDelta()); + if (delta != null && fOutlineViewer != null) { + fOutlineViewer.reconcile(delta); + } + } + }); + } + } + + protected IJavaElementDelta findElement(IJavaElement unit, IJavaElementDelta delta) { + + if (delta == null || unit == null) + return null; + + IJavaElement element= delta.getElement(); + + if (unit.equals(element)) + return delta; + + if (element.getElementType() > IJavaElement.CLASS_FILE) + return null; + + IJavaElementDelta[] children= delta.getAffectedChildren(); + if (children == null || children.length == 0) + return null; + + for (int i= 0; i < children.length; i++) { + IJavaElementDelta d= findElement(unit, children[i]); + if (d != null) + return d; + } + + return null; + } + }; + + static class NoClassElement extends WorkbenchAdapter implements IAdaptable { + /* + * @see java.lang.Object#toString() + */ + public String toString() { + return PHPEditorMessages.getString("JavaOutlinePage.error.NoTopLevelType"); //$NON-NLS-1$ + } + + /* + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(Class) + */ + public Object getAdapter(Class clas) { + if (clas == IWorkbenchAdapter.class) + return this; + return null; + } + } + + /** + * Content provider for the children of an ICompilationUnit or + * an IClassFile + * @see ITreeContentProvider + */ + class ChildrenProvider implements ITreeContentProvider { + + private Object[] NO_CLASS= new Object[] {new NoClassElement()}; + private ElementChangedListener fListener; + + protected boolean matches(IJavaElement element) { + if (element.getElementType() == IJavaElement.METHOD) { + String name= element.getElementName(); + return (name != null && name.indexOf('<') >= 0); + } + return false; + } + + protected IJavaElement[] filter(IJavaElement[] children) { + boolean initializers= false; + for (int i= 0; i < children.length; i++) { + if (matches(children[i])) { + initializers= true; + break; + } + } + + if (!initializers) + return children; + + Vector v= new Vector(); + for (int i= 0; i < children.length; i++) { + if (matches(children[i])) + continue; + v.addElement(children[i]); + } + + IJavaElement[] result= new IJavaElement[v.size()]; + v.copyInto(result); + return result; + } + + public Object[] getChildren(Object parent) { + if (parent instanceof IParent) { + IParent c= (IParent) parent; + try { + return filter(c.getChildren()); + } catch (JavaModelException x) { + PHPeclipsePlugin.log(x); + } + } + return NO_CHILDREN; + } + + public Object[] getElements(Object parent) { + if (fTopLevelTypeOnly) { + if (parent instanceof ICompilationUnit) { + try { + IType type= getMainType((ICompilationUnit) parent); + return type != null ? type.getChildren() : NO_CLASS; + } catch (JavaModelException e) { + PHPeclipsePlugin.log(e); + } + } +// else if (parent instanceof IClassFile) { +// try { +// IType type= getMainType((IClassFile) parent); +// return type != null ? type.getChildren() : NO_CLASS; +// } catch (JavaModelException e) { +// JavaPlugin.log(e); +// } +// } + } + return getChildren(parent); + } + + public Object getParent(Object child) { + if (child instanceof IJavaElement) { + IJavaElement e= (IJavaElement) child; + return e.getParent(); + } + return null; + } + + public boolean hasChildren(Object parent) { + if (parent instanceof IParent) { + IParent c= (IParent) parent; + try { + IJavaElement[] children= filter(c.getChildren()); + return (children != null && children.length > 0); + } catch (JavaModelException x) { + PHPeclipsePlugin.log(x); + } + } + return false; + } + + public boolean isDeleted(Object o) { + return false; + } + + public void dispose() { + if (fListener != null) { + PHPCore.removeElementChangedListener(fListener); + fListener= null; + } + } + + /* + * @see IContentProvider#inputChanged(Viewer, Object, Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + boolean isCU= (newInput instanceof ICompilationUnit); + + if (isCU && fListener == null) { + fListener= new ElementChangedListener(); + PHPCore.addElementChangedListener(fListener); + } else if (!isCU && fListener != null) { + PHPCore.removeElementChangedListener(fListener); + fListener= null; + } + } + }; + + + class JavaOutlineViewer extends TreeViewer { + + /** + * Indicates an item which has been reused. At the point of + * its reuse it has been expanded. This field is used to + * communicate between internalExpandToLevel and + * reuseTreeItem. + */ + private Item fReusedExpandedItem; + private boolean fReorderedMembers; + + public JavaOutlineViewer(Tree tree) { + super(tree); + setAutoExpandLevel(ALL_LEVELS); + } + + /** + * Investigates the given element change event and if affected incrementally + * updates the outline. + */ + public void reconcile(IJavaElementDelta delta) { + fReorderedMembers= false; + if (getSorter() == null) { + if (fTopLevelTypeOnly + && delta.getElement() instanceof IType + && (delta.getKind() & IJavaElementDelta.ADDED) != 0) + { + refresh(true); + + } else { + Widget w= findItem(fInput); + if (w != null && !w.isDisposed()) + update(w, delta); + if (fReorderedMembers) { + refresh(false); + fReorderedMembers= false; + } + } + } else { + // just for now + refresh(true); + } + } + + /* + * @see TreeViewer#internalExpandToLevel + */ + protected void internalExpandToLevel(Widget node, int level) { + if (node instanceof Item) { + Item i= (Item) node; + if (i.getData() instanceof IJavaElement) { + IJavaElement je= (IJavaElement) i.getData(); + if (je.getElementType() == IJavaElement.IMPORT_CONTAINER || isInnerType(je)) { + if (i != fReusedExpandedItem) { + setExpanded(i, false); + return; + } + } + } + } + super.internalExpandToLevel(node, level); + } + + protected void reuseTreeItem(Item item, Object element) { + + // remove children + Item[] c= getChildren(item); + if (c != null && c.length > 0) { + + if (getExpanded(item)) + fReusedExpandedItem= item; + + for (int k= 0; k < c.length; k++) { + if (c[k].getData() != null) + disassociate(c[k]); + c[k].dispose(); + } + } + + updateItem(item, element); + updatePlus(item, element); + internalExpandToLevel(item, ALL_LEVELS); + + fReusedExpandedItem= null; + } + + protected boolean mustUpdateParent(IJavaElementDelta delta, IJavaElement element) { + if (element instanceof IMethod) { + if ((delta.getKind() & IJavaElementDelta.ADDED) != 0) { + try { + return ((IMethod)element).isMainMethod(); + } catch (JavaModelException e) { + PHPeclipsePlugin.log(e.getStatus()); + } + } + return "main".equals(element.getElementName()); //$NON-NLS-1$ + } + return false; + } + + protected ISourceRange getSourceRange(IJavaElement element) throws JavaModelException { + if (element instanceof IMember)// && !(element instanceof IInitializer)) + return ((IMember) element).getNameRange(); + if (element instanceof ISourceReference) + return ((ISourceReference) element).getSourceRange(); + return null; + } + + protected boolean overlaps(ISourceRange range, int start, int end) { + return start <= (range.getOffset() + range.getLength() - 1) && range.getOffset() <= end; + } + + protected boolean filtered(IJavaElement parent, IJavaElement child) { + + Object[] result= new Object[] { child }; + ViewerFilter[] filters= getFilters(); + for (int i= 0; i < filters.length; i++) { + result= filters[i].filter(this, parent, result); + if (result.length == 0) + return true; + } + + return false; + } + + protected void update(Widget w, IJavaElementDelta delta) { + + Item item; + + IJavaElement parent= delta.getElement(); + IJavaElementDelta[] affected= delta.getAffectedChildren(); + Item[] children= getChildren(w); + + boolean doUpdateParent= false; + + Vector deletions= new Vector(); + Vector additions= new Vector(); + + for (int i= 0; i < affected.length; i++) { + IJavaElementDelta affectedDelta= affected[i]; + IJavaElement affectedElement= affectedDelta.getElement(); + int status= affected[i].getKind(); + + // find tree item with affected element + int j; + for (j= 0; j < children.length; j++) + if (affectedElement.equals(children[j].getData())) + break; + + if (j == children.length) { + // addition + if ((status & IJavaElementDelta.CHANGED) != 0 && + (affectedDelta.getFlags() & IJavaElementDelta.F_MODIFIERS) != 0 && + !filtered(parent, affectedElement)) + { + additions.addElement(affectedDelta); + } + continue; + } + + item= children[j]; + + // removed + if ((status & IJavaElementDelta.REMOVED) != 0) { + deletions.addElement(item); + doUpdateParent= doUpdateParent || mustUpdateParent(affectedDelta, affectedElement); + + // changed + } else if ((status & IJavaElementDelta.CHANGED) != 0) { + int change= affectedDelta.getFlags(); + doUpdateParent= doUpdateParent || mustUpdateParent(affectedDelta, affectedElement); + + if ((change & IJavaElementDelta.F_MODIFIERS) != 0) { + if (filtered(parent, affectedElement)) + deletions.addElement(item); + else + updateItem(item, affectedElement); + } + + if ((change & IJavaElementDelta.F_CONTENT) != 0) + updateItem(item, affectedElement); + + if ((change & IJavaElementDelta.F_CHILDREN) != 0) + update(item, affectedDelta); + + if ((change & IJavaElementDelta.F_REORDER) != 0) + fReorderedMembers= true; + } + } + + // find all elements to add + IJavaElementDelta[] add= delta.getAddedChildren(); + if (additions.size() > 0) { + IJavaElementDelta[] tmp= new IJavaElementDelta[add.length + additions.size()]; + System.arraycopy(add, 0, tmp, 0, add.length); + for (int i= 0; i < additions.size(); i++) + tmp[i + add.length]= (IJavaElementDelta) additions.elementAt(i); + add= tmp; + } + + // add at the right position + go2: for (int i= 0; i < add.length; i++) { + + try { + + IJavaElement e= add[i].getElement(); + if (filtered(parent, e)) + continue go2; + + doUpdateParent= doUpdateParent || mustUpdateParent(add[i], e); + ISourceRange rng= getSourceRange(e); + int start= rng.getOffset(); + int end= start + rng.getLength() - 1; + + Item last= null; + item= null; + children= getChildren(w); + + for (int j= 0; j < children.length; j++) { + item= children[j]; + IJavaElement r= (IJavaElement) item.getData(); + + if (r == null) { + // parent node collapsed and not be opened before -> do nothing + continue go2; + } + + + try { + rng= getSourceRange(r); + if (overlaps(rng, start, end)) { + + // be tolerant if the delta is not correct, or if + // the tree has been updated other than by a delta + reuseTreeItem(item, e); + continue go2; + + } else if (rng.getOffset() > start) { + + if (last != null && deletions.contains(last)) { + // reuse item + deletions.removeElement(last); + reuseTreeItem(last, (Object) e); + } else { + // nothing to reuse + createTreeItem(w, (Object) e, j); + } + continue go2; + } + + } catch (JavaModelException x) { + // stumbled over deleted element + } + + last= item; + } + + // add at the end of the list + if (last != null && deletions.contains(last)) { + // reuse item + deletions.removeElement(last); + reuseTreeItem(last, e); + } else { + // nothing to reuse + createTreeItem(w, e, -1); + } + + } catch (JavaModelException x) { + // the element to be added is not present -> don't add it + } + } + + + // remove items which haven't been reused + Enumeration e= deletions.elements(); + while (e.hasMoreElements()) { + item= (Item) e.nextElement(); + disassociate(item); + item.dispose(); + } + + if (doUpdateParent) + updateItem(w, delta.getElement()); + } + + + + /* + * @see ContentViewer#handleLabelProviderChanged(LabelProviderChangedEvent) + */ + protected void handleLabelProviderChanged(LabelProviderChangedEvent event) { + Object input= getInput(); + if (event instanceof ProblemsLabelChangedEvent) { + ProblemsLabelChangedEvent e= (ProblemsLabelChangedEvent) event; + if (e.isMarkerChange() && input instanceof ICompilationUnit) { + return; // marker changes can be ignored + } + } + // look if the underlying resource changed + Object[] changed= event.getElements(); + if (changed != null) { + IResource resource= getUnderlyingResource(); + if (resource != null) { + for (int i= 0; i < changed.length; i++) { + if (changed[i] != null && changed[i].equals(resource)) { + // change event to a full refresh + event= new LabelProviderChangedEvent((IBaseLabelProvider) event.getSource()); + break; + } + } + } + } + super.handleLabelProviderChanged(event); + } + + private IResource getUnderlyingResource() { + Object input= getInput(); + if (input instanceof ICompilationUnit) { + ICompilationUnit cu= (ICompilationUnit) input; + if (cu.isWorkingCopy()) { + return cu.getOriginalElement().getResource(); + } else { + return cu.getResource(); + } + } +// else if (input instanceof IClassFile) { +// return ((IClassFile) input).getResource(); +// } + return null; + } + + + }; + + class LexicalSortingAction extends Action { + + private JavaElementSorter fSorter= new JavaElementSorter(); + + public LexicalSortingAction() { + super(); +// WorkbenchHelp.setHelp(this, IJavaHelpContextIds.LEXICAL_SORTING_OUTLINE_ACTION); + setText(PHPEditorMessages.getString("JavaOutlinePage.Sort.label")); //$NON-NLS-1$ + PHPUiImages.setLocalImageDescriptors(this, "alphab_sort_co.gif"); //$NON-NLS-1$ + setToolTipText(PHPEditorMessages.getString("JavaOutlinePage.Sort.tooltip")); //$NON-NLS-1$ + setDescription(PHPEditorMessages.getString("JavaOutlinePage.Sort.description")); //$NON-NLS-1$ + + boolean checked= PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean("LexicalSortingAction.isChecked"); //$NON-NLS-1$ + valueChanged(checked, false); + } + + public void run() { + valueChanged(isChecked(), true); + } + + private void valueChanged(final boolean on, boolean store) { + setChecked(on); + BusyIndicator.showWhile(fOutlineViewer.getControl().getDisplay(), new Runnable() { + public void run() { + fOutlineViewer.setSorter(on ? fSorter : null); } + }); + + if (store) + PHPeclipsePlugin.getDefault().getPreferenceStore().setValue("LexicalSortingAction.isChecked", on); //$NON-NLS-1$ + } + }; + + class ClassOnlyAction extends Action { + + public ClassOnlyAction() { + super(); +// WorkbenchHelp.setHelp(this, IJavaHelpContextIds.GO_INTO_TOP_LEVEL_TYPE_ACTION); + setText(PHPEditorMessages.getString("JavaOutlinePage.GoIntoTopLevelType.label")); //$NON-NLS-1$ + setToolTipText(PHPEditorMessages.getString("JavaOutlinePage.GoIntoTopLevelType.tooltip")); //$NON-NLS-1$ + setDescription(PHPEditorMessages.getString("JavaOutlinePage.GoIntoTopLevelType.description")); //$NON-NLS-1$ + PHPUiImages.setLocalImageDescriptors(this, "gointo_toplevel_type.gif"); //$NON-NLS-1$ + + IPreferenceStore preferenceStore= PHPeclipsePlugin.getDefault().getPreferenceStore(); + boolean showclass= preferenceStore.getBoolean("GoIntoTopLevelTypeAction.isChecked"); //$NON-NLS-1$ + setTopLevelTypeOnly(showclass); + } + + /* + * @see org.eclipse.jface.action.Action#run() + */ + public void run() { + setTopLevelTypeOnly(!fTopLevelTypeOnly); + } + + private void setTopLevelTypeOnly(boolean show) { + fTopLevelTypeOnly= show; + setChecked(show); + fOutlineViewer.refresh(false); + + IPreferenceStore preferenceStore= PHPeclipsePlugin.getDefault().getPreferenceStore(); + preferenceStore.setValue("GoIntoTopLevelTypeAction.isChecked", show); //$NON-NLS-1$ + } + }; + + /** A flag to show contents of top level type only */ + private boolean fTopLevelTypeOnly; + + private IJavaElement fInput; + private String fContextMenuID; + private Menu fMenu; + private JavaOutlineViewer fOutlineViewer; + private PHPEditor fEditor; + + private MemberFilterActionGroup fMemberFilterActionGroup; + + private ListenerList fSelectionChangedListeners= new ListenerList(); + private Hashtable fActions= new Hashtable(); + + private TogglePresentationAction fTogglePresentation; + private GotoErrorAction fPreviousError; + private GotoErrorAction fNextError; + private TextEditorAction fShowJavadoc; + private TextOperationAction fUndo; + private TextOperationAction fRedo; + + private CompositeActionGroup fActionGroups; +// private CCPActionGroup fCCPActionGroup; + + private IPropertyChangeListener fPropertyChangeListener; + + public JavaOutlinePage(String contextMenuID, PHPEditor editor) { + super(); + + Assert.isNotNull(editor); + + fContextMenuID= contextMenuID; + fEditor= editor; + + fTogglePresentation= new TogglePresentationAction(); + fPreviousError= new GotoErrorAction("PreviousError.", false); //$NON-NLS-1$ + fPreviousError.setImageDescriptor(PHPUiImages.DESC_TOOL_GOTO_PREV_ERROR); + fNextError= new GotoErrorAction("NextError.", true); //$NON-NLS-1$ + fNextError.setImageDescriptor(PHPUiImages.DESC_TOOL_GOTO_NEXT_ERROR); + fShowJavadoc= (TextEditorAction) fEditor.getAction("ShowJavaDoc"); //$NON-NLS-1$ + fUndo= (TextOperationAction) fEditor.getAction(ITextEditorActionConstants.UNDO); + fRedo= (TextOperationAction) fEditor.getAction(ITextEditorActionConstants.REDO); + + fTogglePresentation.setEditor(editor); + fPreviousError.setEditor(editor); + fNextError.setEditor(editor); + + fPropertyChangeListener= new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + doPropertyChange(event); + } + }; + PHPeclipsePlugin.getDefault().getPreferenceStore().addPropertyChangeListener(fPropertyChangeListener); + } + + /** + * Returns the primary type of a compilation unit (has the same + * name as the compilation unit). + * + * @param compilationUnit the compilation unit + * @return returns the primary type of the compilation unit, or + * null if is does not have one + */ + protected IType getMainType(ICompilationUnit compilationUnit) { + String name= compilationUnit.getElementName(); + int index= name.indexOf('.'); + if (index != -1) + name= name.substring(0, index); + IType type= compilationUnit.getType(name); + return type.exists() ? type : null; + } + + /** + * Returns the primary type of a class file. + * + * @param classFile the class file + * @return returns the primary type of the class file, or null + * if is does not have one + */ +// protected IType getMainType(IClassFile classFile) { +// try { +// IType type= classFile.getType(); +// return type != null && type.exists() ? type : null; +// } catch (JavaModelException e) { +// return null; +// } +// } + + /* (non-Javadoc) + * Method declared on Page + */ + public void init(IPageSite pageSite) { + super.init(pageSite); + } + + private void doPropertyChange(PropertyChangeEvent event) { + if (fOutlineViewer != null) { + if (PreferenceConstants.APPEARANCE_MEMBER_SORT_ORDER.equals(event.getProperty())) { + fOutlineViewer.refresh(false); + } + } + } + + /* + * @see ISelectionProvider#addSelectionChangedListener(ISelectionChangedListener) + */ + public void addSelectionChangedListener(ISelectionChangedListener listener) { + if (fOutlineViewer != null) + fOutlineViewer.addPostSelectionChangedListener(listener); + else + fSelectionChangedListeners.add(listener); + } + + /* + * @see ISelectionProvider#removeSelectionChangedListener(ISelectionChangedListener) + */ + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + if (fOutlineViewer != null) + fOutlineViewer.removePostSelectionChangedListener(listener); + else + fSelectionChangedListeners.remove(listener); + } + + /* + * @see ISelectionProvider#setSelection(ISelection) + */ + public void setSelection(ISelection selection) { + if (fOutlineViewer != null) + fOutlineViewer.setSelection(selection); + } + + /* + * @see ISelectionProvider#getSelection() + */ + public ISelection getSelection() { + if (fOutlineViewer == null) + return StructuredSelection.EMPTY; + return fOutlineViewer.getSelection(); + } + + private void registerToolbarActions() { + + IToolBarManager toolBarManager= getSite().getActionBars().getToolBarManager(); + if (toolBarManager != null) { + toolBarManager.add(new ClassOnlyAction()); + toolBarManager.add(new LexicalSortingAction()); + + fMemberFilterActionGroup= new MemberFilterActionGroup(fOutlineViewer, "JavaOutlineViewer"); //$NON-NLS-1$ + fMemberFilterActionGroup.contributeToToolBar(toolBarManager); + } + } + + /* + * @see IPage#createControl + */ + public void createControl(Composite parent) { + + Tree tree= new Tree(parent, SWT.MULTI); + + AppearanceAwareLabelProvider lprovider= new AppearanceAwareLabelProvider( + AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS | JavaElementLabels.F_APP_TYPE_SIGNATURE, + AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS + ); + + fOutlineViewer= new JavaOutlineViewer(tree); + fOutlineViewer.setContentProvider(new ChildrenProvider()); + fOutlineViewer.setLabelProvider(new DecoratingJavaLabelProvider(lprovider)); + + Object[] listeners= fSelectionChangedListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) { + fSelectionChangedListeners.remove(listeners[i]); + fOutlineViewer.addPostSelectionChangedListener((ISelectionChangedListener) listeners[i]); + } + + MenuManager manager= new MenuManager(fContextMenuID, fContextMenuID); + manager.setRemoveAllWhenShown(true); + manager.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + contextMenuAboutToShow(manager); + } + }); + fMenu= manager.createContextMenu(tree); + tree.setMenu(fMenu); + + IPageSite site= getSite(); + site.registerContextMenu(PHPeclipsePlugin.getPluginId() + ".outline", manager, fOutlineViewer); //$NON-NLS-1$ + site.setSelectionProvider(fOutlineViewer); + + // we must create the groups after we have set the selection provider to the site + fActionGroups= new CompositeActionGroup(new ActionGroup[] { +// new OpenViewActionGroup(this), +// fCCPActionGroup= new CCPActionGroup(this), + new GenerateActionGroup(this)}); +// new RefactorActionGroup(this), +// new JavaSearchActionGroup(this)}); + + // register global actions + IActionBars bars= site.getActionBars(); + + bars.setGlobalActionHandler(ITextEditorActionConstants.UNDO, fUndo); + bars.setGlobalActionHandler(ITextEditorActionConstants.REDO, fRedo); + bars.setGlobalActionHandler(ITextEditorActionConstants.PREVIOUS, fPreviousError); + bars.setGlobalActionHandler(ITextEditorActionConstants.NEXT, fNextError); +// bars.setGlobalActionHandler(PHPdtActionConstants.SHOW_PHP_DOC, fShowJavadoc); + bars.setGlobalActionHandler(IJavaEditorActionConstants.TOGGLE_PRESENTATION, fTogglePresentation); + // http://dev.eclipse.org/bugs/show_bug.cgi?id=18968 + bars.setGlobalActionHandler(IJavaEditorActionConstants.PREVIOUS_ERROR, fPreviousError); + bars.setGlobalActionHandler(IJavaEditorActionConstants.NEXT_ERROR, fNextError); + + fActionGroups.fillActionBars(bars); + + IStatusLineManager statusLineManager= site.getActionBars().getStatusLineManager(); + if (statusLineManager != null) { + StatusBarUpdater updater= new StatusBarUpdater(statusLineManager); + fOutlineViewer.addPostSelectionChangedListener(updater); + } + + registerToolbarActions(); + + fOutlineViewer.setInput(fInput); + fOutlineViewer.getControl().addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + handleKeyReleased(e); + } + }); + + initDragAndDrop(); + } + + public void dispose() { + + if (fEditor == null) + return; + + if (fMemberFilterActionGroup != null) { + fMemberFilterActionGroup.dispose(); + fMemberFilterActionGroup= null; + } + + + fEditor.outlinePageClosed(); + fEditor= null; + + fSelectionChangedListeners.clear(); + fSelectionChangedListeners= null; + + if (fPropertyChangeListener != null) { + PHPeclipsePlugin.getDefault().getPreferenceStore().removePropertyChangeListener(fPropertyChangeListener); + fPropertyChangeListener= null; + } + + if (fMenu != null && !fMenu.isDisposed()) { + fMenu.dispose(); + fMenu= null; + } + + if (fActionGroups != null) + fActionGroups.dispose(); + + fTogglePresentation.setEditor(null); + fPreviousError.setEditor(null); + fNextError.setEditor(null); + + fOutlineViewer= null; + + super.dispose(); + } + + public Control getControl() { + if (fOutlineViewer != null) + return fOutlineViewer.getControl(); + return null; + } + + public void setInput(IJavaElement inputElement) { + fInput= inputElement; + if (fOutlineViewer != null) + fOutlineViewer.setInput(fInput); + } + + public void select(ISourceReference reference) { + if (fOutlineViewer != null) { + + ISelection s= fOutlineViewer.getSelection(); + if (s instanceof IStructuredSelection) { + IStructuredSelection ss= (IStructuredSelection) s; + List elements= ss.toList(); + if (!elements.contains(reference)) { + s= (reference == null ? StructuredSelection.EMPTY : new StructuredSelection(reference)); + fOutlineViewer.setSelection(s, true); + } + } + } + } + + public void setAction(String actionID, IAction action) { + Assert.isNotNull(actionID); + if (action == null) + fActions.remove(actionID); + else + fActions.put(actionID, action); + } + + public IAction getAction(String actionID) { + Assert.isNotNull(actionID); + return (IAction) fActions.get(actionID); + } + + /** + * Answer the property defined by key. + */ + public Object getAdapter(Class key) { + if (key == IShowInSource.class) { + return getShowInSource(); + } + if (key == IShowInTargetList.class) { + return new IShowInTargetList() { + public String[] getShowInTargetIds() { + return new String[] { JavaUI.ID_PACKAGES }; + } + + }; + } + if (key == IShowInTarget.class) { + return getShowInTarget(); + } + + return null; + } + + /** + * Convenience method to add the action installed under the given actionID to the + * specified group of the menu. + */ + protected void addAction(IMenuManager menu, String group, String actionID) { + IAction action= getAction(actionID); + if (action != null) { + if (action instanceof IUpdate) + ((IUpdate) action).update(); + + if (action.isEnabled()) { + IMenuManager subMenu= menu.findMenuUsingPath(group); + if (subMenu != null) + subMenu.add(action); + else + menu.appendToGroup(group, action); + } + } + } + + protected void contextMenuAboutToShow(IMenuManager menu) { + + PHPeclipsePlugin.createStandardGroups(menu); + + IStructuredSelection selection= (IStructuredSelection)getSelection(); + fActionGroups.setContext(new ActionContext(selection)); + fActionGroups.fillContextMenu(menu); + } + + /* + * @see Page#setFocus() + */ + public void setFocus() { + if (fOutlineViewer != null) + fOutlineViewer.getControl().setFocus(); + } + + /** + * Checkes whether a given Java element is an inner type. + */ + private boolean isInnerType(IJavaElement element) { + + if (element.getElementType() == IJavaElement.TYPE) { + IJavaElement parent= element.getParent(); + int type= parent.getElementType(); + return (type != IJavaElement.COMPILATION_UNIT && type != IJavaElement.CLASS_FILE); + } + + return false; + } + + /** + * Handles key events in viewer. + */ + private void handleKeyReleased(KeyEvent event) { + + if (event.stateMask != 0) + return; + + IAction action= null; +// if (event.character == SWT.DEL) { +// action= fCCPActionGroup.getDeleteAction(); +// } + + if (action != null && action.isEnabled()) + action.run(); + } + + /** + * Returns the IShowInSource for this view. + */ + protected IShowInSource getShowInSource() { + return new IShowInSource() { + public ShowInContext getShowInContext() { + return new ShowInContext( + null, + getSite().getSelectionProvider().getSelection()); + } + }; + } + + /** + * Returns the IShowInTarget for this view. + */ + protected IShowInTarget getShowInTarget() { + return new IShowInTarget() { + public boolean show(ShowInContext context) { + ISelection sel= context.getSelection(); + if (sel instanceof ITextSelection) { + ITextSelection tsel= (ITextSelection) sel; + int offset= tsel.getOffset(); + IJavaElement element= fEditor.getElementAt(offset); + if (element != null) { + setSelection(new StructuredSelection(element)); + return true; + } + } + return false; + } + }; + } + + private void initDragAndDrop() { + int ops= DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; + Transfer[] transfers= new Transfer[] { + LocalSelectionTransfer.getInstance() + }; + + // Drop Adapter +// TransferDropTargetListener[] dropListeners= new TransferDropTargetListener[] { +// new SelectionTransferDropAdapter(fOutlineViewer) +// }; +// fOutlineViewer.addDropSupport(ops | DND.DROP_DEFAULT, transfers, new DelegatingDropAdapter(dropListeners)); + + // Drag Adapter + TransferDragSourceListener[] dragListeners= new TransferDragSourceListener[] { + new SelectionTransferDragAdapter(fOutlineViewer) + }; + fOutlineViewer.addDragSupport(ops, transfers, new JdtViewerDragAdapter(fOutlineViewer, dragListeners)); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectMarkerRulerAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectMarkerRulerAction.java new file mode 100644 index 0000000..b32d137 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectMarkerRulerAction.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.phpeditor; + +import java.util.Iterator; +import java.util.ResourceBundle; + +import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextOperationTarget; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.ui.help.WorkbenchHelp; +import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.ITextEditorExtension; +import org.eclipse.ui.texteditor.SelectMarkerRulerAction; + +/** + * A special select marker ruler action which activates quick fix if clicked on a quick fixable problem. + */ +public class JavaSelectMarkerRulerAction extends SelectMarkerRulerAction { + + private ITextEditor fMyTextEditor; + private Position fPosition; + + public JavaSelectMarkerRulerAction(ResourceBundle bundle, String prefix, ITextEditor editor, IVerticalRulerInfo ruler) { + super(bundle, prefix, editor, ruler); + fMyTextEditor= editor; + WorkbenchHelp.setHelp(this, IJavaHelpContextIds.JAVA_SELECT_MARKER_RULER_ACTION); + } + + public void run() { + superCall: { + if (fPosition == null) + break superCall; + ITextOperationTarget operation= (ITextOperationTarget) fMyTextEditor.getAdapter(ITextOperationTarget.class); +// final int opCode= CompilationUnitEditor.CORRECTIONASSIST_PROPOSALS; + if (operation == null ) { //|| !operation.canDoOperation(opCode)) { + break superCall; + } + fMyTextEditor.selectAndReveal(fPosition.getOffset(), 0); +// operation.doOperation(opCode); + return; + } + super.run(); + } + + public void update() { + // Begin Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20114 + if (!(fMyTextEditor instanceof ITextEditorExtension) || ((ITextEditorExtension) fMyTextEditor).isEditorInputReadOnly()) { + fPosition= null; + super.update(); + return; + } + // End Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20114 + fPosition= getJavaAnnotationPosition(); + if (fPosition != null) + setEnabled(true); + else + super.update(); + } + + private Position getJavaAnnotationPosition() { + AbstractMarkerAnnotationModel model= getAnnotationModel(); + IDocument document= getDocument(); + if (model == null) + return null; + Iterator iter= model.getAnnotationIterator(); + while (iter.hasNext()) { + Annotation annotation= (Annotation) iter.next(); + if (annotation instanceof IJavaAnnotation) { + IJavaAnnotation javaAnnotation= (IJavaAnnotation)annotation; + if (javaAnnotation.isRelevant()) { + Position position= model.getPosition(annotation); +// if (includesRulerLine(position, document) && JavaCorrectionProcessor.hasCorrections(javaAnnotation)) +// return position; + } + } + } + return null; + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectRulerAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectRulerAction.java new file mode 100644 index 0000000..edb4565 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectRulerAction.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.phpeditor; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.ui.texteditor.AbstractRulerActionDelegate; +import org.eclipse.ui.texteditor.ITextEditor; + +public class JavaSelectRulerAction extends AbstractRulerActionDelegate { + + /* + * @see AbstractRulerActionDelegate#createAction(ITextEditor, IVerticalRulerInfo) + */ + protected IAction createAction(ITextEditor editor, IVerticalRulerInfo rulerInfo) { + return new JavaSelectMarkerRulerAction(PHPEditorMessages.getResourceBundle(), "JavaSelectMarkerRulerAction.", editor, rulerInfo); //$NON-NLS-1$ + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaSourceViewer.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaSourceViewer.java new file mode 100644 index 0000000..80e6949 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaSourceViewer.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package net.sourceforge.phpeclipse.phpeditor; + + +import org.eclipse.swt.widgets.Composite; + +import org.eclipse.jface.text.information.IInformationPresenter; +import org.eclipse.jface.text.source.IOverviewRuler; +import org.eclipse.jface.text.source.IVerticalRuler; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; + +//import net.sourceforge.phpdt.ui.text.JavaSourceViewerConfiguration; + + + +public class JavaSourceViewer extends SourceViewer { + + /** + * Text operation code for requesting the outline for the current input. + */ + public static final int SHOW_OUTLINE= 51; + + /** + * Text operation code for requesting the outline for the element at the current position. + */ + public static final int OPEN_STRUCTURE= 52; + + + private IInformationPresenter fOutlinePresenter; + private IInformationPresenter fStructurePresenter; + + public JavaSourceViewer(Composite parent, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler, boolean showAnnotationsOverview, int styles) { + super(parent, verticalRuler, overviewRuler, showAnnotationsOverview, styles); + } + + /* + * @see ITextOperationTarget#doOperation(int) + */ + public void doOperation(int operation) { + if (getTextWidget() == null) + return; + + switch (operation) { + case SHOW_OUTLINE: + fOutlinePresenter.showInformation(); + return; + case OPEN_STRUCTURE: + fStructurePresenter.showInformation(); + return; + } + + super.doOperation(operation); + } + + /* + * @see ITextOperationTarget#canDoOperation(int) + */ + public boolean canDoOperation(int operation) { + if (operation == SHOW_OUTLINE) + return fOutlinePresenter != null; + if (operation == OPEN_STRUCTURE) + return fStructurePresenter != null; + return super.canDoOperation(operation); + } + + /* + * @see ISourceViewer#configure(SourceViewerConfiguration) + */ + public void configure(SourceViewerConfiguration configuration) { + super.configure(configuration); + if (configuration instanceof PHPSourceViewerConfiguration) { + fOutlinePresenter= ((PHPSourceViewerConfiguration)configuration).getOutlinePresenter(this, false); + fOutlinePresenter.install(this); + } + if (configuration instanceof PHPSourceViewerConfiguration) { + fStructurePresenter= ((PHPSourceViewerConfiguration)configuration).getOutlinePresenter(this, true); + fStructurePresenter.install(this); + } + } + + /* + * @see TextViewer#handleDispose() + */ + protected void handleDispose() { + if (fOutlinePresenter != null) { + fOutlinePresenter.uninstall(); + fOutlinePresenter= null; + } + if (fStructurePresenter != null) { + fStructurePresenter.uninstall(); + fStructurePresenter= null; + } + super.handleDispose(); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPAnnotationHover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPAnnotationHover.java new file mode 100644 index 0000000..4dd82ea --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPAnnotationHover.java @@ -0,0 +1,187 @@ +package net.sourceforge.phpeclipse.phpeditor; + +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation + Klaus Hartlage - www.eclipseproject.de +**********************************************************************/ + +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.IAnnotationHover; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.ui.texteditor.MarkerAnnotation; + +/** + * The PHPAnnotationHover provides the hover support for PHP editors. + */ + +public class PHPAnnotationHover implements IAnnotationHover { + + /* (non-Javadoc) + * Method declared on IAnnotationHover + */ +// public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) { +// IDocument document= sourceViewer.getDocument(); +// +// try { +// IRegion info= document.getLineInformation(lineNumber); +// return document.get(info.getOffset(), info.getLength()); +// } catch (BadLocationException x) { +// } +// +// return null; +// } +// + static final int MAX_INFO_LENGTH = 80; + + /** + * @see org.eclipse.jface.text.source.IAnnotationHover#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer, int) + */ + + public String getHoverInfo(ISourceViewer viewer, int line) { + String info = null; + List markers = getMarkersForLine(viewer, line); + if (markers != null) { + info = ""; + for (int i = 0; i < markers.size(); i++) { + IMarker marker = (IMarker) markers.get(i); + String message = + marker.getAttribute(IMarker.MESSAGE, (String) null); + if (message != null && message.trim().length() > 0) { + + if (message.length() > MAX_INFO_LENGTH) { + message = splitMessage(message); + } + info += message; + + if(i != markers.size() - 1) { + info += "\n"; + } + } + } + } + return info; + } + + private String splitMessage(String message) { + String result = ""; + + if(message.length() <= MAX_INFO_LENGTH) { + return message; + } + + String tmpStr = new String(message); + + while(tmpStr.length() > MAX_INFO_LENGTH) { + + int spacepos = tmpStr.indexOf(" ", MAX_INFO_LENGTH); + + if(spacepos != -1) { + result += tmpStr.substring(0, spacepos) + "\n"; + tmpStr = tmpStr.substring(spacepos); + } + else { + result += tmpStr.substring(0, MAX_INFO_LENGTH) + "\n"; + tmpStr = tmpStr.substring(MAX_INFO_LENGTH); + } + + + + } + + result += tmpStr; + + return result; + } + + /** + * Returns all markers which includes the ruler's line of activity. + */ + protected List getMarkersForLine(ISourceViewer aViewer, int aLine) { + List markers = new ArrayList(); + IAnnotationModel model = aViewer.getAnnotationModel(); + if (model != null) { + Iterator e = model.getAnnotationIterator(); + while (e.hasNext()) { + Object o = e.next(); + if (o instanceof MarkerAnnotation) { + MarkerAnnotation a = (MarkerAnnotation) o; + if (compareRulerLine(model.getPosition(a), + aViewer.getDocument(), + aLine) + != 0) { + markers.add(a.getMarker()); + } + } + } + } + return markers; + } + + /** + * Returns one marker which includes the ruler's line of activity. + */ + protected IMarker getMarkerForLine(ISourceViewer aViewer, int aLine) { + IMarker marker = null; + IAnnotationModel model = aViewer.getAnnotationModel(); + if (model != null) { + Iterator e = model.getAnnotationIterator(); + while (e.hasNext()) { + Object o = e.next(); + if (o instanceof MarkerAnnotation) { + MarkerAnnotation a = (MarkerAnnotation) o; + if (compareRulerLine(model.getPosition(a), + aViewer.getDocument(), + aLine) + != 0) { + marker = a.getMarker(); + } + } + } + } + return marker; + } + + /** + * Returns distance of given line to specified position (1 = same line, + * 2 = included in given position, 0 = not related). + */ + protected int compareRulerLine( + Position aPosition, + IDocument aDocument, + int aLine) { + int distance = 0; + if (aPosition.getOffset() > -1 && aPosition.getLength() > -1) { + try { + int markerLine = + aDocument.getLineOfOffset(aPosition.getOffset()); + if (aLine == markerLine) { + distance = 1; + } else if ( + markerLine <= aLine + && aLine + <= aDocument.getLineOfOffset( + aPosition.getOffset() + + aPosition.getLength())) { + distance = 2; + } + } catch (BadLocationException e) { + } + } + return distance; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java index 891f7f2..fb4f623 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java @@ -12,36 +12,65 @@ Contributors: Klaus Hartlage - www.eclipseproject.de **********************************************************************/ +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import net.sourceforge.phpdt.core.IBuffer; +import net.sourceforge.phpdt.core.IBufferFactory; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; +import net.sourceforge.phpdt.core.IOpenable; import net.sourceforge.phpdt.core.IProblemRequestor; +import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.ui.PHPStatusConstants; +import net.sourceforge.phpdt.internal.ui.PHPUIStatus; import net.sourceforge.phpdt.internal.ui.text.java.IProblemRequestorExtension; -import net.sourceforge.phpeclipse.phpeditor.php.IPHPPartitionScannerConstants; -import net.sourceforge.phpeclipse.phpeditor.php.PHPPartitionScanner; +import net.sourceforge.phpdt.ui.PreferenceConstants; +import net.sourceforge.phpdt.ui.text.JavaTextTools; +import net.sourceforge.phpeclipse.PHPCore; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.DefaultLineTracker; +import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentPartitioner; import org.eclipse.jface.text.ILineTracker; import org.eclipse.jface.text.Position; -import org.eclipse.jface.text.rules.DefaultPartitioner; import org.eclipse.jface.text.source.Annotation; import org.eclipse.jface.text.source.AnnotationModelEvent; import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.jface.text.source.IAnnotationModelListener; import org.eclipse.jface.text.source.IAnnotationModelListenerExtension; +import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.ListenerList; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.editors.text.FileDocumentProvider; import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel; import org.eclipse.ui.texteditor.MarkerAnnotation; import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel; @@ -50,107 +79,34 @@ import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel; */ public class PHPDocumentProvider extends FileDocumentProvider { - - // private final static String[] TYPES= new String[] { PHPPartitionScanner.PHP, PHPPartitionScanner.JAVA_DOC, PHPPartitionScanner.JAVA_MULTILINE_COMMENT }; - private final static String[] TYPES = - new String[] { - IPHPPartitionScannerConstants.PHP, - IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT, - IPHPPartitionScannerConstants.HTML, - IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT, - IPHPPartitionScannerConstants.JAVASCRIPT, - IPHPPartitionScannerConstants.CSS, - IPHPPartitionScannerConstants.SMARTY, - IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT }; - - private static PHPPartitionScanner PHP_PARTITION_SCANNER = null; - private static PHPPartitionScanner HTML_PARTITION_SCANNER = null; - private static PHPPartitionScanner XML_PARTITION_SCANNER = null; - private static PHPPartitionScanner SMARTY_PARTITION_SCANNER = null; - - /** annotation model listener added to all created CU annotation models */ - // private GlobalAnnotationModelListener fGlobalAnnotationModelListener; - /** - * Internal structure for mapping positions to some value. - * The reason for this specific structure is that positions can - * change over time. Thus a lookup is based on value and not - * on hash value. - */ - protected static class ReverseMap { - - static class Entry { - Position fPosition; - Object fValue; - }; - - private List fList = new ArrayList(2); - private int fAnchor = 0; - - public ReverseMap() { - } - - public Object get(Position position) { - - Entry entry; - - // behind anchor - int length = fList.size(); - for (int i = fAnchor; i < length; i++) { - entry = (Entry) fList.get(i); - if (entry.fPosition.equals(position)) { - fAnchor = i; - return entry.fValue; - } - } - - // before anchor - for (int i = 0; i < fAnchor; i++) { - entry = (Entry) fList.get(i); - if (entry.fPosition.equals(position)) { - fAnchor = i; - return entry.fValue; - } - } - - return null; + * Here for visibility issues only. + */ + protected class _FileSynchronizer extends FileSynchronizer { + public _FileSynchronizer(IFileEditorInput fileEditorInput) { + super(fileEditorInput); } + }; + /** + * Bundle of all required informations to allow working copy management. + */ + protected class CompilationUnitInfo extends FileInfo { - private int getIndex(Position position) { - Entry entry; - int length = fList.size(); - for (int i = 0; i < length; i++) { - entry = (Entry) fList.get(i); - if (entry.fPosition.equals(position)) - return i; - } - return -1; - } + ICompilationUnit fCopy; - public void put(Position position, Object value) { - int index = getIndex(position); - if (index == -1) { - Entry entry = new Entry(); - entry.fPosition = position; - entry.fValue = value; - fList.add(entry); - } else { - Entry entry = (Entry) fList.get(index); - entry.fValue = value; - } + public CompilationUnitInfo( + IDocument document, + IAnnotationModel model, + _FileSynchronizer fileSynchronizer, + ICompilationUnit copy) { + super(document, model, fileSynchronizer); + fCopy = copy; } - public void remove(Position position) { - int index = getIndex(position); - if (index > -1) - fList.remove(index); - } - - public void clear() { - fList.clear(); + public void setModificationStamp(long timeStamp) { + fModificationStamp = timeStamp; } }; - /** * Annotation model dealing with java marker annotations and temporary problems. * Also acts as problem requestor for its compilation unit. Initialiy inactive. Must explicitly be @@ -159,22 +115,61 @@ public class PHPDocumentProvider extends FileDocumentProvider { protected class CompilationUnitAnnotationModel extends ResourceMarkerAnnotationModel implements IProblemRequestor, IProblemRequestorExtension { - - private IFileEditorInput fInput; private List fCollectedProblems; + private List fCurrentlyOverlaid = new ArrayList(); private List fGeneratedAnnotations; - private IProgressMonitor fProgressMonitor; + + private IFileEditorInput fInput; private boolean fIsActive = false; + private List fPreviouslyOverlaid = null; + private IProgressMonitor fProgressMonitor; private ReverseMap fReverseMap = new ReverseMap(); - private List fPreviouslyOverlaid = null; - private List fCurrentlyOverlaid = new ArrayList(); public CompilationUnitAnnotationModel(IFileEditorInput input) { super(input.getFile()); fInput = input; } + /* + * @see IProblemRequestor#acceptProblem(IProblem) + */ + public void acceptProblem(IProblem problem) { + if (isActive()) + fCollectedProblems.add(problem); + } + + /* + * @see AnnotationModel#addAnnotation(Annotation, Position, boolean) + */ + protected void addAnnotation(Annotation annotation, Position position, boolean fireModelChanged) { + super.addAnnotation(annotation, position, fireModelChanged); + + Object cached = fReverseMap.get(position); + if (cached == null) + fReverseMap.put(position, annotation); + else if (cached instanceof List) { + List list = (List) cached; + list.add(annotation); + } else if (cached instanceof Annotation) { + List list = new ArrayList(2); + list.add(cached); + list.add(annotation); + fReverseMap.put(position, list); + } + } + + /* + * @see IProblemRequestor#beginReporting() + */ + public void beginReporting() { + ICompilationUnit unit = getWorkingCopy(fInput); + if (unit != null) // && unit.getJavaProject().isOnClasspath(unit)) + fCollectedProblems = new ArrayList(); + else + fCollectedProblems = null; + } + protected MarkerAnnotation createMarkerAnnotation(IMarker marker) { return new JavaMarkerAnnotation(marker); } @@ -191,40 +186,6 @@ public class PHPDocumentProvider extends FileDocumentProvider { return new Position(start, length); } - protected void update(IMarkerDelta[] markerDeltas) { - - super.update(markerDeltas); - - // if (markerDeltas != null && markerDeltas.length > 0) { - // try { - // ICompilationUnit workingCopy = getWorkingCopy(fInput); - // if (workingCopy != null) - // workingCopy.reconcile(true, null); - // } catch (JavaModelException ex) { - // handleCoreException(ex, ex.getMessage()); - // } - // } - } - - /* - * @see IProblemRequestor#beginReporting() - */ - public void beginReporting() { - // ICompilationUnit unit= getWorkingCopy(fInput); - // if (unit != null && unit.getJavaProject().isOnClasspath(unit)) - // fCollectedProblems= new ArrayList(); - // else - fCollectedProblems = null; - } - - /* - * @see IProblemRequestor#acceptProblem(IProblem) - */ - public void acceptProblem(IProblem problem) { - if (isActive()) - fCollectedProblems.add(problem); - } - /* * @see IProblemRequestor#endReporting() */ @@ -263,10 +224,10 @@ public class PHPDocumentProvider extends FileDocumentProvider { Position position = createPositionFromProblem(problem); if (position != null) { - // ProblemAnnotation annotation= new ProblemAnnotation(problem); - // overlayMarkers(position, annotation); - // fGeneratedAnnotations.add(annotation); - // addAnnotation(annotation, position, false); + ProblemAnnotation annotation = new ProblemAnnotation(problem); + overlayMarkers(position, annotation); + fGeneratedAnnotations.add(annotation); + addAnnotation(annotation, position, false); temporaryProblemsChanged = true; } @@ -280,8 +241,54 @@ public class PHPDocumentProvider extends FileDocumentProvider { fPreviouslyOverlaid = null; } - // if (temporaryProblemsChanged) - // fireModelChanged(new CompilationUnitAnnotationModelEvent(this, getResource(), false)); + if (temporaryProblemsChanged) + fireModelChanged(new CompilationUnitAnnotationModelEvent(this, getResource(), false)); + } + + private Object getAnnotations(Position position) { + return fReverseMap.get(position); + } + + /* + * @see AnnotationModel#fireModelChanged() + */ + protected void fireModelChanged() { + fireModelChanged(new CompilationUnitAnnotationModelEvent(this, getResource(), true)); + } + + /* + * @see IProblemRequestor#isActive() + */ + public boolean isActive() { + return fIsActive && (fCollectedProblems != null); + } + + /* + * @see AnnotationModel#removeAllAnnotations(boolean) + */ + protected void removeAllAnnotations(boolean fireModelChanged) { + super.removeAllAnnotations(fireModelChanged); + fReverseMap.clear(); + } + + /* + * @see AnnotationModel#removeAnnotation(Annotation, boolean) + */ + protected void removeAnnotation(Annotation annotation, boolean fireModelChanged) { + Position position = getPosition(annotation); + Object cached = fReverseMap.get(position); + if (cached instanceof List) { + List list = (List) cached; + list.remove(annotation); + if (list.size() == 1) { + fReverseMap.put(position, list.get(0)); + list.clear(); + } + } else if (cached instanceof Annotation) { + fReverseMap.remove(position); + } + + super.removeAnnotation(annotation, fireModelChanged); } private void removeMarkerOverlays(boolean isCanceled) { @@ -296,31 +303,51 @@ public class PHPDocumentProvider extends FileDocumentProvider { } } + /* + * @see IProblemRequestorExtension#setIsActive(boolean) + */ + public void setIsActive(boolean isActive) { + if (fIsActive != isActive) { + fIsActive = isActive; + if (fIsActive) + startCollectingProblems(); + else + stopCollectingProblems(); + } + } + + /* + * @see IProblemRequestorExtension#setProgressMonitor(IProgressMonitor) + */ + public void setProgressMonitor(IProgressMonitor monitor) { + fProgressMonitor = monitor; + } + /** * Overlays value with problem annotation. * @param problemAnnotation */ - // private void setOverlay(Object value, ProblemAnnotation problemAnnotation) { - // if (value instanceof JavaMarkerAnnotation) { - // JavaMarkerAnnotation annotation= (JavaMarkerAnnotation) value; - // if (annotation.isProblem()) { - // annotation.setOverlay(problemAnnotation); - // fPreviouslyOverlaid.remove(annotation); - // fCurrentlyOverlaid.add(annotation); - // } - // } - // } - - // private void overlayMarkers(Position position, ProblemAnnotation problemAnnotation) { - // Object value= getAnnotations(position); - // if (value instanceof List) { - // List list= (List) value; - // for (Iterator e = list.iterator(); e.hasNext();) - // setOverlay(e.next(), problemAnnotation); - // } else { - // setOverlay(value, problemAnnotation); - // } - // } + private void setOverlay(Object value, ProblemAnnotation problemAnnotation) { + if (value instanceof JavaMarkerAnnotation) { + JavaMarkerAnnotation annotation = (JavaMarkerAnnotation) value; + if (annotation.isProblem()) { + annotation.setOverlay(problemAnnotation); + fPreviouslyOverlaid.remove(annotation); + fCurrentlyOverlaid.add(annotation); + } + } + } + + private void overlayMarkers(Position position, ProblemAnnotation problemAnnotation) { + Object value = getAnnotations(position); + if (value instanceof List) { + List list = (List) value; + for (Iterator e = list.iterator(); e.hasNext();) + setOverlay(e.next(), problemAnnotation); + } else { + setOverlay(value, problemAnnotation); + } + } /** * Tells this annotation model to collect temporary problems from now on. @@ -342,260 +369,938 @@ public class PHPDocumentProvider extends FileDocumentProvider { fGeneratedAnnotations = null; } + protected void update(IMarkerDelta[] markerDeltas) { + + super.update(markerDeltas); + + if (markerDeltas != null && markerDeltas.length > 0) { + try { + ICompilationUnit workingCopy = getWorkingCopy(fInput); + if (workingCopy != null) + workingCopy.reconcile(true, null); + } catch (JavaModelException ex) { + handleCoreException(ex, ex.getMessage()); + } + } + } + } + /** + * Creates IBuffers based on documents. + */ + protected class BufferFactory implements IBufferFactory { + + private IDocument internalGetDocument(IFileEditorInput input) throws CoreException { + IDocument document = getDocument(input); + if (document != null) + return document; + return PHPDocumentProvider.this.createDocument(input); + } + + public IBuffer createBuffer(IOpenable owner) { + if (owner instanceof ICompilationUnit) { + + ICompilationUnit unit = (ICompilationUnit) owner; + ICompilationUnit original = (ICompilationUnit) unit.getOriginalElement(); + IResource resource = original.getResource(); + if (resource instanceof IFile) { + IFileEditorInput providerKey = new FileEditorInput((IFile) resource); + + IDocument document = null; + IStatus status = null; + + try { + document = internalGetDocument(providerKey); + } catch (CoreException x) { + status = x.getStatus(); + document = new Document(); + initializeDocument(document, providerKey); + } + + DocumentAdapter adapter = + new DocumentAdapter(unit, document, new DefaultLineTracker(), PHPDocumentProvider.this, providerKey); + adapter.setStatus(status); + return adapter; + } + + } + return DocumentAdapter.NULL; + } + }; + + protected static class GlobalAnnotationModelListener implements IAnnotationModelListener, IAnnotationModelListenerExtension { + + private ListenerList fListenerList; + + public GlobalAnnotationModelListener() { + fListenerList = new ListenerList(); + } + + public void addListener(IAnnotationModelListener listener) { + fListenerList.add(listener); + } + + /** + * @see IAnnotationModelListenerExtension#modelChanged(AnnotationModelEvent) + */ + public void modelChanged(AnnotationModelEvent event) { + Object[] listeners = fListenerList.getListeners(); + for (int i = 0; i < listeners.length; i++) { + Object curr = listeners[i]; + if (curr instanceof IAnnotationModelListenerExtension) { + ((IAnnotationModelListenerExtension) curr).modelChanged(event); + } + } + } + + /** + * @see IAnnotationModelListener#modelChanged(IAnnotationModel) + */ + public void modelChanged(IAnnotationModel model) { + Object[] listeners = fListenerList.getListeners(); + for (int i = 0; i < listeners.length; i++) { + ((IAnnotationModelListener) listeners[i]).modelChanged(model); + } + } + + public void removeListener(IAnnotationModelListener listener) { + fListenerList.remove(listener); + } + } + + /** + * Annotation representating an IProblem. + */ + static protected class ProblemAnnotation extends Annotation implements IJavaAnnotation { + + // private static Image fgQuickFixImage; + // private static Image fgQuickFixErrorImage; + // private static boolean fgQuickFixImagesInitialized = false; + + private List fOverlaids; + private IProblem fProblem; + private Image fImage; + // private boolean fQuickFixImagesInitialized = false; + private AnnotationType fType; + + public ProblemAnnotation(IProblem problem) { + + fProblem = problem; + setLayer(MarkerAnnotation.PROBLEM_LAYER + 1); + + if (IProblem.Task == fProblem.getID()) + fType = AnnotationType.TASK; + else if (fProblem.isWarning()) + fType = AnnotationType.WARNING; + else + fType = AnnotationType.ERROR; + } + + private void initializeImages() { + // http://bugs.eclipse.org/bugs/show_bug.cgi?id=18936 + // if (!fQuickFixImagesInitialized) { + // if (indicateQuixFixableProblems() && JavaCorrectionProcessor.hasCorrections(fProblem.getID())) { + // if (!fgQuickFixImagesInitialized) { + // fgQuickFixImage = JavaPluginImages.get(JavaPluginImages.IMG_OBJS_FIXABLE_PROBLEM); + // fgQuickFixErrorImage = JavaPluginImages.get(JavaPluginImages.IMG_OBJS_FIXABLE_ERROR); + // fgQuickFixImagesInitialized = true; + // } + // if (fType == AnnotationType.ERROR) + // fImage = fgQuickFixErrorImage; + // else + // fImage = fgQuickFixImage; + // } + // fQuickFixImagesInitialized = true; + // } + } + + private boolean indicateQuixFixableProblems() { + return PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_CORRECTION_INDICATION); + } + /* - * @see AnnotationModel#fireModelChanged() + * @see Annotation#paint */ - // protected void fireModelChanged() { - // fireModelChanged(new CompilationUnitAnnotationModelEvent(this, getResource(), true)); - // } + public void paint(GC gc, Canvas canvas, Rectangle r) { + initializeImages(); + if (fImage != null) + drawImage(fImage, gc, canvas, r, SWT.CENTER, SWT.TOP); + } /* - * @see IProblemRequestor#isActive() + * @see IJavaAnnotation#getImage(Display) */ - public boolean isActive() { - return fIsActive && (fCollectedProblems != null); + public Image getImage(Display display) { + initializeImages(); + return fImage; } /* - * @see IProblemRequestorExtension#setProgressMonitor(IProgressMonitor) + * @see IJavaAnnotation#getMessage() */ - public void setProgressMonitor(IProgressMonitor monitor) { - fProgressMonitor = monitor; + public String getMessage() { + return fProblem.getMessage(); } /* - * @see IProblemRequestorExtension#setIsActive(boolean) + * @see IJavaAnnotation#isTemporary() */ - public void setIsActive(boolean isActive) { - if (fIsActive != isActive) { - fIsActive = isActive; - if (fIsActive) - startCollectingProblems(); - else - stopCollectingProblems(); - } + public boolean isTemporary() { + return true; } - private Object getAnnotations(Position position) { - return fReverseMap.get(position); + /* + * @see IJavaAnnotation#getArguments() + */ + public String[] getArguments() { + return isProblem() ? fProblem.getArguments() : null; } /* - * @see AnnotationModel#addAnnotation(Annotation, Position, boolean) + * @see IJavaAnnotation#getId() */ - protected void addAnnotation(Annotation annotation, Position position, boolean fireModelChanged) { - super.addAnnotation(annotation, position, fireModelChanged); + public int getId() { + return isProblem() ? fProblem.getID() : -1; + } - Object cached = fReverseMap.get(position); - if (cached == null) - fReverseMap.put(position, annotation); - else if (cached instanceof List) { - List list = (List) cached; - list.add(annotation); - } else if (cached instanceof Annotation) { - List list = new ArrayList(2); - list.add(cached); - list.add(annotation); - fReverseMap.put(position, list); - } + /* + * @see IJavaAnnotation#isProblem() + */ + public boolean isProblem() { + return fType == AnnotationType.WARNING || fType == AnnotationType.ERROR; } /* - * @see AnnotationModel#removeAllAnnotations(boolean) + * @see IJavaAnnotation#isRelevant() */ - protected void removeAllAnnotations(boolean fireModelChanged) { - super.removeAllAnnotations(fireModelChanged); - fReverseMap.clear(); + public boolean isRelevant() { + return true; } /* - * @see AnnotationModel#removeAnnotation(Annotation, boolean) + * @see IJavaAnnotation#hasOverlay() */ - protected void removeAnnotation(Annotation annotation, boolean fireModelChanged) { - Position position = getPosition(annotation); - Object cached = fReverseMap.get(position); - if (cached instanceof List) { - List list = (List) cached; - list.remove(annotation); - if (list.size() == 1) { - fReverseMap.put(position, list.get(0)); - list.clear(); - } - } else if (cached instanceof Annotation) { - fReverseMap.remove(position); + public boolean hasOverlay() { + return false; + } + + /* + * @see IJavaAnnotation#addOverlaid(IJavaAnnotation) + */ + public void addOverlaid(IJavaAnnotation annotation) { + if (fOverlaids == null) + fOverlaids = new ArrayList(1); + fOverlaids.add(annotation); + } + + /* + * @see IJavaAnnotation#removeOverlaid(IJavaAnnotation) + */ + public void removeOverlaid(IJavaAnnotation annotation) { + if (fOverlaids != null) { + fOverlaids.remove(annotation); + if (fOverlaids.size() == 0) + fOverlaids = null; } + } - super.removeAnnotation(annotation, fireModelChanged); + /* + * @see IJavaAnnotation#getOverlaidIterator() + */ + public Iterator getOverlaidIterator() { + if (fOverlaids != null) + return fOverlaids.iterator(); + return null; + } + + public AnnotationType getAnnotationType() { + return fType; } }; + /** + * Internal structure for mapping positions to some value. + * The reason for this specific structure is that positions can + * change over time. Thus a lookup is based on value and not + * on hash value. + */ + protected static class ReverseMap { - protected static class GlobalAnnotationModelListener implements IAnnotationModelListener, IAnnotationModelListenerExtension { + static class Entry { + Position fPosition; + Object fValue; + } + private int fAnchor = 0; - private ListenerList fListenerList; + private List fList = new ArrayList(2); - public GlobalAnnotationModelListener() { - fListenerList = new ListenerList(); + public ReverseMap() { } - /** - * @see IAnnotationModelListener#modelChanged(IAnnotationModel) - */ - public void modelChanged(IAnnotationModel model) { - Object[] listeners = fListenerList.getListeners(); - for (int i = 0; i < listeners.length; i++) { - ((IAnnotationModelListener) listeners[i]).modelChanged(model); - } + public void clear() { + fList.clear(); } - /** - * @see IAnnotationModelListenerExtension#modelChanged(AnnotationModelEvent) - */ - public void modelChanged(AnnotationModelEvent event) { - Object[] listeners = fListenerList.getListeners(); - for (int i = 0; i < listeners.length; i++) { - Object curr = listeners[i]; - if (curr instanceof IAnnotationModelListenerExtension) { - ((IAnnotationModelListenerExtension) curr).modelChanged(event); + public Object get(Position position) { + + Entry entry; + + // behind anchor + int length = fList.size(); + for (int i = fAnchor; i < length; i++) { + entry = (Entry) fList.get(i); + if (entry.fPosition.equals(position)) { + fAnchor = i; + return entry.fValue; } } + + // before anchor + for (int i = 0; i < fAnchor; i++) { + entry = (Entry) fList.get(i); + if (entry.fPosition.equals(position)) { + fAnchor = i; + return entry.fValue; + } + } + + return null; + } + + private int getIndex(Position position) { + Entry entry; + int length = fList.size(); + for (int i = 0; i < length; i++) { + entry = (Entry) fList.get(i); + if (entry.fPosition.equals(position)) + return i; + } + return -1; } - public void addListener(IAnnotationModelListener listener) { - fListenerList.add(listener); + public void put(Position position, Object value) { + int index = getIndex(position); + if (index == -1) { + Entry entry = new Entry(); + entry.fPosition = position; + entry.fValue = value; + fList.add(entry); + } else { + Entry entry = (Entry) fList.get(index); + entry.fValue = value; + } } - public void removeListener(IAnnotationModelListener listener) { - fListenerList.remove(listener); + public void remove(Position position) { + int index = getIndex(position); + if (index > -1) + fList.remove(index); + } + } + + /** + * Document that can also be used by a background reconciler. + */ + protected static class PartiallySynchronizedDocument extends Document { + + /* + * @see IDocumentExtension#startSequentialRewrite(boolean) + */ + synchronized public void startSequentialRewrite(boolean normalized) { + super.startSequentialRewrite(normalized); + } + + /* + * @see IDocumentExtension#stopSequentialRewrite() + */ + synchronized public void stopSequentialRewrite() { + super.stopSequentialRewrite(); + } + + /* + * @see IDocument#get() + */ + synchronized public String get() { + return super.get(); + } + + /* + * @see IDocument#get(int, int) + */ + synchronized public String get(int offset, int length) throws BadLocationException { + return super.get(offset, length); + } + + /* + * @see IDocument#getChar(int) + */ + synchronized public char getChar(int offset) throws BadLocationException { + return super.getChar(offset); + } + + /* + * @see IDocument#replace(int, int, String) + */ + synchronized public void replace(int offset, int length, String text) throws BadLocationException { + super.replace(offset, length, text); + } + + /* + * @see IDocument#set(String) + */ + synchronized public void set(String text) { + super.set(text); } }; + // + // private static PHPPartitionScanner HTML_PARTITION_SCANNER = null; + // + // private static PHPPartitionScanner PHP_PARTITION_SCANNER = null; + // private static PHPPartitionScanner SMARTY_PARTITION_SCANNER = null; + // + // // private final static String[] TYPES= new String[] { PHPPartitionScanner.PHP, PHPPartitionScanner.JAVA_DOC, PHPPartitionScanner.JAVA_MULTILINE_COMMENT }; + // private final static String[] TYPES = + // new String[] { + // IPHPPartitionScannerConstants.PHP, + // IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT, + // IPHPPartitionScannerConstants.HTML, + // IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT, + // IPHPPartitionScannerConstants.JAVASCRIPT, + // IPHPPartitionScannerConstants.CSS, + // IPHPPartitionScannerConstants.SMARTY, + // IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT }; + // private static PHPPartitionScanner XML_PARTITION_SCANNER = null; + + /* Preference key for temporary problems */ + private final static String HANDLE_TEMPORARY_PROBLEMS = PreferenceConstants.EDITOR_EVALUTE_TEMPORARY_PROBLEMS; + + /** The buffer factory */ + private IBufferFactory fBufferFactory = new BufferFactory(); + /** Indicates whether the save has been initialized by this provider */ + private boolean fIsAboutToSave = false; + /** The save policy used by this provider */ + private ISavePolicy fSavePolicy; + /** Internal property changed listener */ + private IPropertyChangeListener fPropertyListener; + + /** annotation model listener added to all created CU annotation models */ + private GlobalAnnotationModelListener fGlobalAnnotationModelListener; public PHPDocumentProvider() { - super(); - // fGlobalAnnotationModelListener= new GlobalAnnotationModelListener(); + fPropertyListener = new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + if (HANDLE_TEMPORARY_PROBLEMS.equals(event.getProperty())) + enableHandlingTemporaryProblems(); + } + }; + + fGlobalAnnotationModelListener = new GlobalAnnotationModelListener(); + PHPeclipsePlugin.getDefault().getPreferenceStore().addPropertyChangeListener(fPropertyListener); + + } + + /** + * Sets the document provider's save policy. + */ + public void setSavePolicy(ISavePolicy savePolicy) { + fSavePolicy = savePolicy; } + /** + * Creates a compilation unit from the given file. + * + * @param file the file from which to create the compilation unit + */ + protected ICompilationUnit createCompilationUnit(IFile file) { + Object element = PHPCore.create(file); + if (element instanceof ICompilationUnit) + return (ICompilationUnit) element; + return null; + } + + /* + * @see AbstractDocumentProvider#createElementInfo(Object) + */ + protected ElementInfo createElementInfo(Object element) throws CoreException { + + if (!(element instanceof IFileEditorInput)) + return super.createElementInfo(element); + + IFileEditorInput input = (IFileEditorInput) element; + ICompilationUnit original = createCompilationUnit(input.getFile()); + if (original != null) { + + try { + + try { + refreshFile(input.getFile()); + } catch (CoreException x) { + handleCoreException(x, PHPEditorMessages.getString("PHPDocumentProvider.error.createElementInfo")); //$NON-NLS-1$ + } + + IAnnotationModel m = createCompilationUnitAnnotationModel(input); + IProblemRequestor r = m instanceof IProblemRequestor ? (IProblemRequestor) m : null; + ICompilationUnit c = (ICompilationUnit) original.getSharedWorkingCopy(getProgressMonitor(), fBufferFactory, r); + + DocumentAdapter a = null; + try { + a = (DocumentAdapter) c.getBuffer(); + } catch (ClassCastException x) { + IStatus status = new Status(IStatus.ERROR, PHPeclipsePlugin.PLUGIN_ID, PHPStatusConstants.TEMPLATE_IO_EXCEPTION, "Shared working copy has wrong buffer", x); //$NON-NLS-1$ + throw new CoreException(status); + } + + _FileSynchronizer f = new _FileSynchronizer(input); + f.install(); + + CompilationUnitInfo info = new CompilationUnitInfo(a.getDocument(), m, f, c); + info.setModificationStamp(computeModificationStamp(input.getFile())); + info.fStatus = a.getStatus(); + info.fEncoding = getPersistedEncoding(input); + + if (r instanceof IProblemRequestorExtension) { + IProblemRequestorExtension extension = (IProblemRequestorExtension) r; + extension.setIsActive(isHandlingTemporaryProblems()); + } + m.addAnnotationModelListener(fGlobalAnnotationModelListener); + + return info; + + } catch (JavaModelException x) { + throw new CoreException(x.getStatus()); + } + } else { + return super.createElementInfo(element); + } + } + + /* + * @see AbstractDocumentProvider#disposeElementInfo(Object, ElementInfo) + */ + protected void disposeElementInfo(Object element, ElementInfo info) { + + if (info instanceof CompilationUnitInfo) { + CompilationUnitInfo cuInfo = (CompilationUnitInfo) info; + cuInfo.fCopy.destroy(); + cuInfo.fModel.removeAnnotationModelListener(fGlobalAnnotationModelListener); + } + + super.disposeElementInfo(element, info); + } + + /* + * @see AbstractDocumentProvider#doSaveDocument(IProgressMonitor, Object, IDocument, boolean) + */ + protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) + throws CoreException { + + ElementInfo elementInfo = getElementInfo(element); + if (elementInfo instanceof CompilationUnitInfo) { + CompilationUnitInfo info = (CompilationUnitInfo) elementInfo; + + // update structure, assumes lock on info.fCopy + info.fCopy.reconcile(); + + ICompilationUnit original = (ICompilationUnit) info.fCopy.getOriginalElement(); + IResource resource = original.getResource(); + + if (resource == null) { + // underlying resource has been deleted, just recreate file, ignore the rest + super.doSaveDocument(monitor, element, document, overwrite); + return; + } + + if (resource != null && !overwrite) + checkSynchronizationState(info.fModificationStamp, resource); + + if (fSavePolicy != null) + fSavePolicy.preSave(info.fCopy); + + // inform about the upcoming content change + fireElementStateChanging(element); + try { + fIsAboutToSave = true; + // commit working copy + info.fCopy.commit(overwrite, monitor); + } catch (CoreException x) { + // inform about the failure + fireElementStateChangeFailed(element); + throw x; + } catch (RuntimeException x) { + // inform about the failure + fireElementStateChangeFailed(element); + throw x; + } finally { + fIsAboutToSave = false; + } + + // If here, the dirty state of the editor will change to "not dirty". + // Thus, the state changing flag will be reset. + + AbstractMarkerAnnotationModel model = (AbstractMarkerAnnotationModel) info.fModel; + model.updateMarkers(info.fDocument); + + if (resource != null) + info.setModificationStamp(computeModificationStamp(resource)); + + if (fSavePolicy != null) { + ICompilationUnit unit = fSavePolicy.postSave(original); + if (unit != null) { + IResource r = unit.getResource(); + IMarker[] markers = r.findMarkers(IMarker.MARKER, true, IResource.DEPTH_ZERO); + if (markers != null && markers.length > 0) { + for (int i = 0; i < markers.length; i++) + model.updateMarker(markers[i], info.fDocument, null); + } + } + } + + } else { + super.doSaveDocument(monitor, element, document, overwrite); + } + } + + /** + * Replaces createAnnotionModel of the super class. + */ + protected IAnnotationModel createCompilationUnitAnnotationModel(Object element) throws CoreException { + if ( !(element instanceof IFileEditorInput)) + throw new CoreException(PHPUIStatus.createError( + IJavaModelStatusConstants.INVALID_RESOURCE_TYPE, "", null)); //$NON-NLS-1$ + + IFileEditorInput input= (IFileEditorInput) element; + return new CompilationUnitAnnotationModel(input); + } + + // private IDocumentPartitioner createCSSPartitioner() { + // return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES); + // } + /* (non-Javadoc) * Method declared on AbstractDocumentProvider */ protected IDocument createDocument(Object element) throws CoreException { - IDocument document = super.createDocument(element); + if (element instanceof IEditorInput) { + Document document = new PartiallySynchronizedDocument(); + if (setDocumentContent(document, (IEditorInput) element, getEncoding(element))) { + initializeDocument(document, (IEditorInput) element); + + // + // IDocument document = super.createDocument(element); + // if (document != null) { + // IDocumentPartitioner partitioner = null; + // if (element instanceof FileEditorInput) { + // IFile file = (IFile) ((FileEditorInput) element).getAdapter(IFile.class); + // String filename = file.getLocation().toString(); + // String extension = filename.substring(filename.lastIndexOf("."), filename.length()); + // // System.out.println(extension); + // if (extension.equalsIgnoreCase(".html") || extension.equalsIgnoreCase(".htm")) { + // // html + // partitioner = createHTMLPartitioner(); + // } else if (extension.equalsIgnoreCase(".xml")) { + // // xml + // partitioner = createXMLPartitioner(); + // } else if (extension.equalsIgnoreCase(".js")) { + // // javascript + // partitioner = createJavaScriptPartitioner(); + // } else if (extension.equalsIgnoreCase(".css")) { + // // cascading style sheets + // partitioner = createCSSPartitioner(); + // } else if (extension.equalsIgnoreCase(".tpl")) { + // // smarty ? + // partitioner = createSmartyPartitioner(); + // } else if (extension.equalsIgnoreCase(".inc")) { + // // php include files ? + // partitioner = createIncludePartitioner(); + // } + // } + // + // if (partitioner == null) { + // partitioner = createPHPPartitioner(); + // } + // document.setDocumentPartitioner(partitioner); + // partitioner.connect(document); + } + return document; + } + return null; + } + + // /** + // * Return a partitioner for .html files. + // */ + // private IDocumentPartitioner createHTMLPartitioner() { + // return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES); + // } + // + // private IDocumentPartitioner createIncludePartitioner() { + // return new DefaultPartitioner(getPHPPartitionScanner(), TYPES); + // } + // + // private IDocumentPartitioner createJavaScriptPartitioner() { + // return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES); + // } + + /** + * Creates a line tracker working with the same line delimiters as the document + * of the given element. Assumes the element to be managed by this document provider. + * + * @param element the element serving as blue print + * @return a line tracker based on the same line delimiters as the element's document + */ + public ILineTracker createLineTracker(Object element) { + return new DefaultLineTracker(); + } + + // /** + // * Return a partitioner for .php files. + // */ + // private IDocumentPartitioner createPHPPartitioner() { + // return new DefaultPartitioner(getPHPPartitionScanner(), TYPES); + // } + // + // private IDocumentPartitioner createSmartyPartitioner() { + // return new DefaultPartitioner(getSmartyPartitionScanner(), TYPES); + // } + // + // private IDocumentPartitioner createXMLPartitioner() { + // return new DefaultPartitioner(getXMLPartitionScanner(), TYPES); + // } + // + // /** + // * Return a scanner for creating html partitions. + // */ + // private PHPPartitionScanner getHTMLPartitionScanner() { + // if (HTML_PARTITION_SCANNER == null) + // HTML_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.HTML_FILE); + // return HTML_PARTITION_SCANNER; + // } + // /** + // * Return a scanner for creating php partitions. + // */ + // private PHPPartitionScanner getPHPPartitionScanner() { + // if (PHP_PARTITION_SCANNER == null) + // PHP_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.PHP_FILE); + // return PHP_PARTITION_SCANNER; + // } + // + // /** + // * Return a scanner for creating smarty partitions. + // */ + // private PHPPartitionScanner getSmartyPartitionScanner() { + // if (SMARTY_PARTITION_SCANNER == null) + // SMARTY_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.SMARTY_FILE); + // return SMARTY_PARTITION_SCANNER; + // } + // + // /** + // * Return a scanner for creating xml partitions. + // */ + // private PHPPartitionScanner getXMLPartitionScanner() { + // if (XML_PARTITION_SCANNER == null) + // XML_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.XML_FILE); + // return XML_PARTITION_SCANNER; + // } + + protected void initializeDocument(IDocument document, IEditorInput editorInput) { if (document != null) { - // int fileType = 0; // PHP + JavaTextTools tools = PHPeclipsePlugin.getDefault().getJavaTextTools(); IDocumentPartitioner partitioner = null; - if (element instanceof FileEditorInput) { - IFile file = (IFile) ((FileEditorInput) element).getAdapter(IFile.class); + if (editorInput != null && editorInput instanceof FileEditorInput) { + IFile file = (IFile) ((FileEditorInput) editorInput).getAdapter(IFile.class); String filename = file.getLocation().toString(); String extension = filename.substring(filename.lastIndexOf("."), filename.length()); - // System.out.println(extension); - if (extension.equalsIgnoreCase(".html") || extension.equalsIgnoreCase(".htm")) { - // html - partitioner = createHTMLPartitioner(); - } else if (extension.equalsIgnoreCase(".xml")) { - // xml - partitioner = createXMLPartitioner(); - } else if (extension.equalsIgnoreCase(".js")) { - // javascript - partitioner = createJavaScriptPartitioner(); - } else if (extension.equalsIgnoreCase(".css")) { - // cascading style sheets - partitioner = createCSSPartitioner(); - } else if (extension.equalsIgnoreCase(".tpl")) { - // smarty ? - partitioner = createSmartyPartitioner(); - } else if (extension.equalsIgnoreCase(".inc")) { - // php include files ? - partitioner = createIncludePartitioner(); - } - } - - if (partitioner == null) { - partitioner = createPHPPartitioner(); + partitioner = tools.createDocumentPartitioner(extension); + } else { + partitioner = tools.createDocumentPartitioner(".php"); } document.setDocumentPartitioner(partitioner); partitioner.connect(document); } - return document; } + /* + * @see AbstractDocumentProvider#resetDocument(Object) + */ + public void resetDocument(Object element) throws CoreException { + if (element == null) + return; + + ElementInfo elementInfo = getElementInfo(element); + if (elementInfo instanceof CompilationUnitInfo) { + CompilationUnitInfo info = (CompilationUnitInfo) elementInfo; + + IDocument document; + IStatus status = null; + + try { + + ICompilationUnit original = (ICompilationUnit) info.fCopy.getOriginalElement(); + IResource resource = original.getResource(); + if (resource instanceof IFile) { + + IFile file = (IFile) resource; + + try { + refreshFile(file); + } catch (CoreException x) { + handleCoreException(x, PHPEditorMessages.getString("PHPDocumentProvider.error.resetDocument")); //$NON-NLS-1$ + } + + IFileEditorInput input = new FileEditorInput(file); + document = super.createDocument(input); + + } else { + document = new Document(); + } + + } catch (CoreException x) { + document = new Document(); + status = x.getStatus(); + } + + fireElementContentAboutToBeReplaced(element); + + removeUnchangedElementListeners(element, info); + info.fDocument.set(document.get()); + info.fCanBeSaved = false; + info.fStatus = status; + addUnchangedElementListeners(element, info); + + fireElementContentReplaced(element); + fireElementDirtyStateChanged(element, false); + + } else { + super.resetDocument(element); + } + } /** - * Return a partitioner for .php files. + * Saves the content of the given document to the given element. + * This is only performed when this provider initiated the save. + * + * @param monitor the progress monitor + * @param element the element to which to save + * @param document the document to save + * @param overwrite true if the save should be enforced + */ + public void saveDocumentContent(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) + throws CoreException { + + if (!fIsAboutToSave) + return; + + if (element instanceof IFileEditorInput) { + IFileEditorInput input = (IFileEditorInput) element; + try { + String encoding = getEncoding(element); + if (encoding == null) + encoding = ResourcesPlugin.getEncoding(); + InputStream stream = new ByteArrayInputStream(document.get().getBytes(encoding)); + IFile file = input.getFile(); + file.setContents(stream, overwrite, true, monitor); + } catch (IOException x) { + IStatus s = new Status(IStatus.ERROR, PHPeclipsePlugin.PLUGIN_ID, IStatus.OK, x.getMessage(), x); + throw new CoreException(s); + } + } + } + /** + * Returns the underlying resource for the given element. + * + * @param the element + * @return the underlying resource of the given element */ - private IDocumentPartitioner createPHPPartitioner() { - return new DefaultPartitioner(getPHPPartitionScanner(), TYPES); + public IResource getUnderlyingResource(Object element) { + if (element instanceof IFileEditorInput) { + IFileEditorInput input = (IFileEditorInput) element; + return input.getFile(); + } + return null; } /** - * Return a partitioner for .html files. + * Returns the working copy this document provider maintains for the given + * element. + * + * @param element the given element + * @return the working copy for the given element */ - private IDocumentPartitioner createHTMLPartitioner() { - return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES); - } + ICompilationUnit getWorkingCopy(IEditorInput element) { - private IDocumentPartitioner createXMLPartitioner() { - return new DefaultPartitioner(getXMLPartitionScanner(), TYPES); - } + ElementInfo elementInfo = getElementInfo(element); + if (elementInfo instanceof CompilationUnitInfo) { + CompilationUnitInfo info = (CompilationUnitInfo) elementInfo; + return info.fCopy; + } - private IDocumentPartitioner createJavaScriptPartitioner() { - return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES); + return null; } - private IDocumentPartitioner createCSSPartitioner() { - return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES); + /** + * Gets the BufferFactory. + */ + public IBufferFactory getBufferFactory() { + return fBufferFactory; } - private IDocumentPartitioner createSmartyPartitioner() { - return new DefaultPartitioner(getSmartyPartitionScanner(), TYPES); - } + /** + * Shuts down this document provider. + */ + public void shutdown() { - private IDocumentPartitioner createIncludePartitioner() { - return new DefaultPartitioner(getPHPPartitionScanner(), TYPES); + PHPeclipsePlugin.getDefault().getPreferenceStore().removePropertyChangeListener(fPropertyListener); + + Iterator e = getConnectedElements(); + while (e.hasNext()) + disconnect(e.next()); } + /** - * Return a scanner for creating php partitions. + * Returns the preference whether handling temporary problems is enabled. */ - private PHPPartitionScanner getPHPPartitionScanner() { - if (PHP_PARTITION_SCANNER == null) - PHP_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.PHP_FILE); - return PHP_PARTITION_SCANNER; + protected boolean isHandlingTemporaryProblems() { + IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore(); + return store.getBoolean(HANDLE_TEMPORARY_PROBLEMS); } /** - * Return a scanner for creating html partitions. + * Switches the state of problem acceptance according to the value in the preference store. */ - private PHPPartitionScanner getHTMLPartitionScanner() { - if (HTML_PARTITION_SCANNER == null) - HTML_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.HTML_FILE); - return HTML_PARTITION_SCANNER; + protected void enableHandlingTemporaryProblems() { + boolean enable = isHandlingTemporaryProblems(); + for (Iterator iter = getConnectedElements(); iter.hasNext();) { + ElementInfo element = getElementInfo(iter.next()); + if (element instanceof CompilationUnitInfo) { + CompilationUnitInfo info = (CompilationUnitInfo) element; + if (info.fModel instanceof IProblemRequestorExtension) { + IProblemRequestorExtension extension = (IProblemRequestorExtension) info.fModel; + extension.setIsActive(enable); + } + } + } } /** - * Return a scanner for creating xml partitions. + * Adds a listener that reports changes from all compilation unit annotation models. */ - private PHPPartitionScanner getXMLPartitionScanner() { - if (XML_PARTITION_SCANNER == null) - XML_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.XML_FILE); - return XML_PARTITION_SCANNER; + public void addGlobalAnnotationModelListener(IAnnotationModelListener listener) { + fGlobalAnnotationModelListener.addListener(listener); } /** - * Return a scanner for creating smarty partitions. + * Removes the listener. */ - private PHPPartitionScanner getSmartyPartitionScanner() { - if (SMARTY_PARTITION_SCANNER == null) - SMARTY_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.SMARTY_FILE); - return SMARTY_PARTITION_SCANNER; + public void removeGlobalAnnotationModelListener(IAnnotationModelListener listener) { + fGlobalAnnotationModelListener.removeListener(listener); } /** - * Creates a line tracker working with the same line delimiters as the document - * of the given element. Assumes the element to be managed by this document provider. + * Returns whether the given element is connected to this document provider. * - * @param element the element serving as blue print - * @return a line tracker based on the same line delimiters as the element's document + * @param element the element + * @return true if the element is connected, false otherwise */ - public ILineTracker createLineTracker(Object element) { - return new DefaultLineTracker(); + boolean isConnected(Object element) { + return getElementInfo(element) != null; } } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java index ef1bbab..a2f3ae0 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java @@ -12,26 +12,35 @@ Contributors: Klaus Hartlage - www.eclipseproject.de **********************************************************************/ import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.ResourceBundle; import java.util.StringTokenizer; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IMember; +import net.sourceforge.phpdt.core.ISourceRange; +import net.sourceforge.phpdt.core.ISourceReference; +import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup; import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter; import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher; import net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider; import net.sourceforge.phpdt.ui.IContextMenuConstants; +import net.sourceforge.phpdt.ui.JavaUI; import net.sourceforge.phpdt.ui.PreferenceConstants; import net.sourceforge.phpdt.ui.actions.GenerateActionGroup; import net.sourceforge.phpdt.ui.actions.GotoMatchingBracketAction; import net.sourceforge.phpdt.ui.text.IColorManager; import net.sourceforge.phpdt.ui.text.JavaTextTools; +import net.sourceforge.phpeclipse.PHPCore; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.phpeditor.php.IPHPPartitionScannerConstants; +import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Preferences; import org.eclipse.jface.action.Action; @@ -52,18 +61,21 @@ import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextHover; import org.eclipse.jface.text.ITextInputListener; import org.eclipse.jface.text.ITextOperationTarget; +import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.ITextViewerExtension2; import org.eclipse.jface.text.ITextViewerExtension3; import org.eclipse.jface.text.ITypedRegion; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextSelection; import org.eclipse.jface.text.information.IInformationProvider; import org.eclipse.jface.text.information.InformationPresenter; import org.eclipse.jface.text.source.Annotation; import org.eclipse.jface.text.source.AnnotationRulerColumn; import org.eclipse.jface.text.source.CompositeRuler; import org.eclipse.jface.text.source.IAnnotationAccess; +import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.jface.text.source.IOverviewRuler; import org.eclipse.jface.text.source.ISharedTextColors; import org.eclipse.jface.text.source.ISourceViewer; @@ -76,8 +88,12 @@ import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.jface.text.source.SourceViewerConfiguration; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BidiSegmentEvent; import org.eclipse.swt.custom.BidiSegmentListener; @@ -95,6 +111,7 @@ import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Composite; @@ -102,13 +119,17 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPartService; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.actions.ActionContext; import org.eclipse.ui.actions.ActionGroup; import org.eclipse.ui.editors.text.DefaultEncodingSupport; import org.eclipse.ui.editors.text.IEncodingSupport; +import org.eclipse.ui.part.IShowInTargetList; import org.eclipse.ui.texteditor.AddTaskAction; import org.eclipse.ui.texteditor.ContentAssistAction; import org.eclipse.ui.texteditor.DefaultRangeIndicator; @@ -117,17 +138,52 @@ import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.IEditorStatusLine; import org.eclipse.ui.texteditor.ITextEditorActionConstants; import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; +import org.eclipse.ui.texteditor.MarkerAnnotation; import org.eclipse.ui.texteditor.ResourceAction; import org.eclipse.ui.texteditor.SourceViewerDecorationSupport; import org.eclipse.ui.texteditor.StatusTextEditor; import org.eclipse.ui.texteditor.TextEditorAction; import org.eclipse.ui.texteditor.TextOperationAction; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; +import org.eclipse.ui.views.tasklist.TaskList; /** * PHP specific text editor. */ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInputProvider { // extends TextEditor { + /** + * "Smart" runnable for updating the outline page's selection. + */ + class OutlinePageSelectionUpdater implements Runnable { + + /** Has the runnable already been posted? */ + private boolean fPosted = false; + + public OutlinePageSelectionUpdater() { + } + + /* + * @see Runnable#run() + */ + public void run() { + synchronizeOutlinePageSelection(); + fPosted = false; + } + + /** + * Posts this runnable into the event queue. + */ + public void post() { + if (fPosted) + return; + + Shell shell = getSite().getShell(); + if (shell != null & !shell.isDisposed()) { + fPosted = true; + shell.getDisplay().asyncExec(this); + } + } + }; class SelectionChangedListener implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent event) { doSelectionChanged(event); @@ -138,15 +194,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp * Link mode. */ class MouseClickListener - implements - KeyListener, - MouseListener, - MouseMoveListener, - FocusListener, - PaintListener, - IPropertyChangeListener, - IDocumentListener, - ITextInputListener { + implements KeyListener, MouseListener, MouseMoveListener, FocusListener, PaintListener, IPropertyChangeListener, IDocumentListener, ITextInputListener { /** The session is active. */ private boolean fActive; @@ -402,25 +450,25 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp return null; return null; - // IJavaElement input= SelectionConverter.getInput(PHPEditor.this); - // if (input == null) - // return null; - // - // try { - // - // IJavaElement[] elements= null; - // synchronized (input) { - // elements= ((ICodeAssist) input).codeSelect(offset, 0); - // } - // - // if (elements == null || elements.length == 0) - // return null; - // - // return selectWord(viewer.getDocument(), offset); - // - // } catch (JavaModelException e) { - // return null; - // } + // IJavaElement input= SelectionConverter.getInput(PHPEditor.this); + // if (input == null) + // return null; + // + // try { + // + // IJavaElement[] elements= null; + // synchronized (input) { + // elements= ((ICodeAssist) input).codeSelect(offset, 0); + // } + // + // if (elements == null || elements.length == 0) + // return null; + // + // return selectWord(viewer.getDocument(), offset); + // + // } catch (JavaModelException e) { + // return null; + // } } private int getCurrentTextOffset(ISourceViewer viewer) { @@ -765,8 +813,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp } private boolean includes(IRegion region, IRegion position) { - return position.getOffset() >= region.getOffset() - && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength(); + return position.getOffset() >= region.getOffset() && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength(); } private Point getMinimumLocation(StyledText text, int offset, int length) { @@ -960,11 +1007,21 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp private final static String LINE_NUMBER_COLOR = PreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR; /** Preference key for the link color */ private final static String LINK_COLOR = PreferenceConstants.EDITOR_LINK_COLOR; + /** Preference key for compiler task tags */ + private final static String COMPILER_TASK_TAGS = PHPCore.COMPILER_TASK_TAGS; // protected PHPActionGroup fActionGroups; + // /** The outline page */ + // private AbstractContentOutlinePage fOutlinePage; /** The outline page */ - private AbstractContentOutlinePage fOutlinePage; - + protected JavaOutlinePage fOutlinePage; + /** Outliner context menu Id */ + protected String fOutlinerContextMenuId; + /** Indicates whether this editor should react on outline page selection changes */ + private int fIgnoreOutlinePageSelection; + + /** The outline page selection updater */ + private OutlinePageSelectionUpdater fUpdater; // protected PHPSyntaxParserThread fValidationThread = null; // private IPreferenceStore fPHPPrefStore; @@ -973,6 +1030,8 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp /** The editor's bracket matcher */ private PHPPairMatcher fBracketMatcher = new PHPPairMatcher(BRACKETS); + + /** The line number ruler column */ private LineNumberRulerColumn fLineNumberRulerColumn; /** This editor's encoding support */ @@ -998,6 +1057,21 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp /** The preference property change listener for java core. */ private org.eclipse.core.runtime.Preferences.IPropertyChangeListener fPropertyChangeListener = new PropertyChangeListener(); + /** + * Returns the most narrow java element including the given offset + * + * @param offset the offset inside of the requested element + */ + abstract protected IJavaElement getElementAt(int offset); + + /** + * Returns the java element of this editor's input corresponding to the given IJavaElement + */ + abstract protected IJavaElement getCorrespondingElement(IJavaElement element); + /** + * Sets the input of the editor's outline page. + */ + abstract protected void setOutlinePageInput(JavaOutlinePage page, IEditorInput input); /** * Default constructor. @@ -1012,8 +1086,8 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp // don't activate this scope without synchronizing plugin.xml !!! // setKeyBindingScopes(new String[] { "net.sourceforge.phpdt.ui.phpEditorScope" }); //$NON-NLS-1$ - // if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE)) - // fUpdater= new OutlinePageSelectionUpdater(); + if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE)) + fUpdater= new OutlinePageSelectionUpdater(); } // // /** @@ -1038,7 +1112,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp if (fEncodingSupport != null) fEncodingSupport.reset(); } - + /* * Update the hovering behavior depending on the preferences. */ @@ -1069,13 +1143,22 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp } } + public void updatedTitleImage(Image image) { + setTitleImage(image); + } /* * @see net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput() */ public Object getViewPartInput() { return getEditorInput().getAdapter(IResource.class); } - + /* + * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetSelection(ISelection) + */ + protected void doSetSelection(ISelection selection) { + super.doSetSelection(selection); + synchronizeOutlinePageSelection(); + } /* * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt. * widgets.Composite) @@ -1099,6 +1182,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp fInformationPresenter = new InformationPresenter(informationControlCreator); fInformationPresenter.setSizeConstraints(60, 10, true, true); fInformationPresenter.install(getSourceViewer()); + } /** @@ -1112,15 +1196,22 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp } /** + * Sets the outliner's context menu ID. + */ + protected void setOutlinerContextMenuId(String menuId) { + fOutlinerContextMenuId = menuId; + } + + /** * Returns the standard action group of this editor. */ protected ActionGroup getActionGroup() { return fActionGroups; } - public AbstractContentOutlinePage getfOutlinePage() { - return fOutlinePage; - } + // public JavaOutlinePage getfOutlinePage() { + // return fOutlinePage; + // } /** The PHPEditor implementation of this * AbstractTextEditor method extend the @@ -1144,11 +1235,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp setAction( "ContentAssistTip", - new TextOperationAction( - PHPEditorMessages.getResourceBundle(), - "ContentAssistTip.", - this, - ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION)); + new TextOperationAction(PHPEditorMessages.getResourceBundle(), "ContentAssistTip.", this, ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION)); action = new ContentAssistAction(PHPEditorMessages.getResourceBundle(), "ContentAssistProposal.", this); //$NON-NLS-1$ action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); @@ -1244,46 +1331,46 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp * AbstractTextEditor method performs any extra * revert behavior required by the php editor. */ - public void doRevertToSaved() { - super.doRevertToSaved(); - if (fOutlinePage != null) - fOutlinePage.update(); - } + // public void doRevertToSaved() { + // super.doRevertToSaved(); + // if (fOutlinePage != null) + // fOutlinePage.update(); + // } /** The PHPEditor implementation of this * AbstractTextEditor method performs any extra * save behavior required by the php editor. */ - public void doSave(IProgressMonitor monitor) { - super.doSave(monitor); - // compile or not, according to the user preferences - // IPreferenceStore store = getPreferenceStore(); - - // the parse on save was changed to the eclipse "builders" concept - // if (store.getBoolean(PHPeclipsePlugin.PHP_PARSE_ON_SAVE)) { - // IAction a = PHPParserAction.getInstance(); - // if (a != null) - // a.run(); - // } + // public void doSave(IProgressMonitor monitor) { + // super.doSave(monitor); + // compile or not, according to the user preferences + // IPreferenceStore store = getPreferenceStore(); + + // the parse on save was changed to the eclipse "builders" concept + // if (store.getBoolean(PHPeclipsePlugin.PHP_PARSE_ON_SAVE)) { + // IAction a = PHPParserAction.getInstance(); + // if (a != null) + // a.run(); + // } - // if (SWT.getPlatform().equals("win32")) { - // IAction a = ShowExternalPreviewAction.getInstance(); - // if (a != null) - // a.run(); - // } - if (fOutlinePage != null) - fOutlinePage.update(); - } + // if (SWT.getPlatform().equals("win32")) { + // IAction a = ShowExternalPreviewAction.getInstance(); + // if (a != null) + // a.run(); + // } + // if (fOutlinePage != null) + // fOutlinePage.update(); + // } /** The PHPEditor implementation of this * AbstractTextEditor method performs any extra * save as behavior required by the php editor. */ - public void doSaveAs() { - super.doSaveAs(); - if (fOutlinePage != null) - fOutlinePage.update(); - } + // public void doSaveAs() { + // super.doSaveAs(); + // if (fOutlinePage != null) + // fOutlinePage.update(); + // } /* * @see StatusTextEditor#getStatusHeader(IStatus) */ @@ -1323,16 +1410,21 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp * AbstractTextEditor method performs sets the * input of the outline page after AbstractTextEditor has set input. */ + // protected void doSetInput(IEditorInput input) throws CoreException { + // super.doSetInput(input); + // + // if (fEncodingSupport != null) + // fEncodingSupport.reset(); + // if (fOutlinePage != null) + // fOutlinePage.setInput(input); + // // setOutlinePageInput(fOutlinePage, input); + // } protected void doSetInput(IEditorInput input) throws CoreException { super.doSetInput(input); - if (fEncodingSupport != null) fEncodingSupport.reset(); - if (fOutlinePage != null) - fOutlinePage.setInput(input); - // setOutlinePageInput(fOutlinePage, input); + setOutlinePageInput(fOutlinePage, input); } - /* * @see org.phpeclipse.phpdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput() */ @@ -1365,14 +1457,20 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp /** * Creates the outline page used with this editor. */ - protected AbstractContentOutlinePage createOutlinePage() { + protected JavaOutlinePage createOutlinePage() { - AbstractContentOutlinePage page = new PHPContentOutlinePage(getDocumentProvider(), this); + // AbstractContentOutlinePage page = new PHPContentOutlinePage(getDocumentProvider(), this); + // + // page.addSelectionChangedListener(fSelectionChangedListener); + // // setOutlinePageInput(page, getEditorInput()); + // if (getEditorInput() != null) + // fOutlinePage.setInput(getEditorInput()); + // + // return page; + JavaOutlinePage page = new JavaOutlinePage(fOutlinerContextMenuId, this); page.addSelectionChangedListener(fSelectionChangedListener); - // setOutlinePageInput(page, getEditorInput()); - if (getEditorInput() != null) - fOutlinePage.setInput(getEditorInput()); + setOutlinePageInput(page, getEditorInput()); return page; } @@ -1387,56 +1485,263 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp resetHighlightRange(); } } + /** + * Synchronizes the outliner selection with the actual cursor + * position in the editor. + */ + public void synchronizeOutlinePageSelection() { + + // if (isEditingScriptRunning()) + // return; + + ISourceViewer sourceViewer = getSourceViewer(); + if (sourceViewer == null || fOutlinePage == null) + return; + + StyledText styledText = sourceViewer.getTextWidget(); + if (styledText == null) + return; + + int caret = 0; + if (sourceViewer instanceof ITextViewerExtension3) { + ITextViewerExtension3 extension = (ITextViewerExtension3) sourceViewer; + caret = extension.widgetOffset2ModelOffset(styledText.getCaretOffset()); + } else { + int offset = sourceViewer.getVisibleRegion().getOffset(); + caret = offset + styledText.getCaretOffset(); + } + + IJavaElement element = getElementAt(caret); + if (element instanceof ISourceReference) { + fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener); + fOutlinePage.select((ISourceReference) element); + fOutlinePage.addSelectionChangedListener(fSelectionChangedListener); + } + } protected void updateStateDependentActions() { super.updateStateDependentActions(); fGenerateActionGroup.editorStateChanged(); } + protected void setSelection(ISourceReference reference, boolean moveCursor) { + + ISelection selection = getSelectionProvider().getSelection(); + if (selection instanceof TextSelection) { + TextSelection textSelection = (TextSelection) selection; + if (textSelection.getOffset() != 0 || textSelection.getLength() != 0) + markInNavigationHistory(); + } + + if (reference != null) { + + StyledText textWidget = null; + + ISourceViewer sourceViewer = getSourceViewer(); + if (sourceViewer != null) + textWidget = sourceViewer.getTextWidget(); + + if (textWidget == null) + return; + + try { + + ISourceRange range = reference.getSourceRange(); + if (range == null) + return; + + int offset = range.getOffset(); + int length = range.getLength(); + + if (offset < 0 || length < 0) + return; + + textWidget.setRedraw(false); + + setHighlightRange(offset, length, moveCursor); + + if (!moveCursor) + return; + + offset = -1; + length = -1; + + if (reference instanceof IMember) { + range = ((IMember) reference).getNameRange(); + if (range != null) { + offset = range.getOffset(); + length = range.getLength(); + } + } + // else if (reference instanceof IImportDeclaration) { + // String name= ((IImportDeclaration) reference).getElementName(); + // if (name != null && name.length() > 0) { + // String content= reference.getSource(); + // if (content != null) { + // offset= range.getOffset() + content.indexOf(name); + // length= name.length(); + // } + // } + // } else if (reference instanceof IPackageDeclaration) { + // String name= ((IPackageDeclaration) reference).getElementName(); + // if (name != null && name.length() > 0) { + // String content= reference.getSource(); + // if (content != null) { + // offset= range.getOffset() + content.indexOf(name); + // length= name.length(); + // } + // } + // } + + if (offset > -1 && length > 0) { + sourceViewer.revealRange(offset, length); + sourceViewer.setSelectedRange(offset, length); + } + + } catch (JavaModelException x) { + } catch (IllegalArgumentException x) { + } finally { + if (textWidget != null) + textWidget.setRedraw(true); + } + + } else if (moveCursor) { + resetHighlightRange(); + } + + markInNavigationHistory(); + } + + public void setSelection(IJavaElement element) { + + if (element == null || element instanceof ICompilationUnit) { // || element instanceof IClassFile) { + /* + * If the element is an ICompilationUnit this unit is either the input + * of this editor or not being displayed. In both cases, nothing should + * happened. (http://dev.eclipse.org/bugs/show_bug.cgi?id=5128) + */ + return; + } + + IJavaElement corresponding = getCorrespondingElement(element); + if (corresponding instanceof ISourceReference) { + ISourceReference reference = (ISourceReference) corresponding; + // set hightlight range + setSelection(reference, true); + // set outliner selection + if (fOutlinePage != null) { + fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener); + fOutlinePage.select(reference); + fOutlinePage.addSelectionChangedListener(fSelectionChangedListener); + } + } + } + + public synchronized void editingScriptStarted() { + ++ fIgnoreOutlinePageSelection; + } + + public synchronized void editingScriptEnded() { + -- fIgnoreOutlinePageSelection; + } + + public synchronized boolean isEditingScriptRunning() { + return (fIgnoreOutlinePageSelection > 0); + } + /** The PHPEditor implementation of this * AbstractTextEditor method performs gets * the java content outline page if request is for a an * outline page. */ public Object getAdapter(Class required) { + if (IContentOutlinePage.class.equals(required)) { - if (fOutlinePage == null) { - fOutlinePage = new PHPContentOutlinePage(getDocumentProvider(), this); - if (getEditorInput() != null) - fOutlinePage.setInput(getEditorInput()); - } + if (fOutlinePage == null) + fOutlinePage = createOutlinePage(); return fOutlinePage; } if (IEncodingSupport.class.equals(required)) return fEncodingSupport; + if (required == IShowInTargetList.class) { + return new IShowInTargetList() { + public String[] getShowInTargetIds() { + return new String[] { JavaUI.ID_PACKAGES, IPageLayout.ID_OUTLINE, IPageLayout.ID_RES_NAV }; + } + + }; + } + return super.getAdapter(required); } + // public Object getAdapter(Class required) { + // if (IContentOutlinePage.class.equals(required)) { + // if (fOutlinePage == null) { + // fOutlinePage = new PHPContentOutlinePage(getDocumentProvider(), this); + // if (getEditorInput() != null) + // fOutlinePage.setInput(getEditorInput()); + // } + // return fOutlinePage; + // } + // + // if (IEncodingSupport.class.equals(required)) + // return fEncodingSupport; + // + // return super.getAdapter(required); + // } protected void doSelectionChanged(SelectionChangedEvent event) { + ISourceReference reference = null; + + ISelection selection = event.getSelection(); + Iterator iter = ((IStructuredSelection) selection).iterator(); + while (iter.hasNext()) { + Object o = iter.next(); + if (o instanceof ISourceReference) { + reference = (ISourceReference) o; + break; + } + } - // ISourceReference reference= null; - // - // ISelection selection= event.getSelection(); - // Iterator iter= ((IStructuredSelection) selection).iterator(); - // while (iter.hasNext()) { - // Object o= iter.next(); - // if (o instanceof ISourceReference) { - // reference= (ISourceReference) o; - // break; - // } - // } if (!isActivePart() && PHPeclipsePlugin.getActivePage() != null) PHPeclipsePlugin.getActivePage().bringToTop(this); - // try { - // editingScriptStarted(); - // setSelection(reference, !isActivePart()); - // } finally { - // editingScriptEnded(); - // } + try { + editingScriptStarted(); + setSelection(reference, !isActivePart()); + } finally { + editingScriptEnded(); + } } + /* + * @see AbstractTextEditor#adjustHighlightRange(int, int) + */ + protected void adjustHighlightRange(int offset, int length) { + + try { + IJavaElement element = getElementAt(offset); + while (element instanceof ISourceReference) { + ISourceRange range = ((ISourceReference) element).getSourceRange(); + if (offset < range.getOffset() + range.getLength() && range.getOffset() < offset + length) { + setHighlightRange(range.getOffset(), range.getLength(), true); + if (fOutlinePage != null) { + fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener); + fOutlinePage.select((ISourceReference) element); + fOutlinePage.addSelectionChangedListener(fSelectionChangedListener); + } + return; + } + element = element.getParent(); + } + + } catch (JavaModelException x) { + PHPeclipsePlugin.log(x.getStatus()); + } + + resetHighlightRange(); + } protected boolean isActivePart() { IWorkbenchWindow window = getSite().getWorkbenchWindow(); IPartService service = window.getPartService(); @@ -1444,7 +1749,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp return part != null && part.equals(this); } - + // public void openContextHelp() { // IDocument doc = this.getDocumentProvider().getDocument(this.getEditorInput()); // ITextSelection selection = (ITextSelection) this.getSelectionProvider().getSelection(); @@ -1518,15 +1823,20 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp } if (fLineNumberRulerColumn != null - && (LINE_NUMBER_COLOR.equals(property) - || PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property) - || PREFERENCE_COLOR_BACKGROUND.equals(property))) { + && (LINE_NUMBER_COLOR.equals(property) || PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property) || PREFERENCE_COLOR_BACKGROUND.equals(property))) { initializeLineNumberRulerColumn(fLineNumberRulerColumn); } - if (isJavaEditorHoverProperty(property)) { + if (isJavaEditorHoverProperty(property)) updateHoverBehavior(); + + if (BROWSER_LIKE_LINKS.equals(property)) { + if (isBrowserLikeLinks()) + enableBrowserLikeLinks(); + else + disableBrowserLikeLinks(); + return; } } finally { @@ -1578,16 +1888,16 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp // } // } - private boolean isJavaEditorHoverProperty(String property) { - return PreferenceConstants.EDITOR_DEFAULT_HOVER.equals(property) - || PreferenceConstants.EDITOR_NONE_HOVER.equals(property) - || PreferenceConstants.EDITOR_CTRL_HOVER.equals(property) - || PreferenceConstants.EDITOR_SHIFT_HOVER.equals(property) - || PreferenceConstants.EDITOR_CTRL_ALT_HOVER.equals(property) - || PreferenceConstants.EDITOR_CTRL_SHIFT_HOVER.equals(property) - || PreferenceConstants.EDITOR_CTRL_ALT_SHIFT_HOVER.equals(property) - || PreferenceConstants.EDITOR_ALT_SHIFT_HOVER.equals(property); - } + // private boolean isJavaEditorHoverProperty(String property) { + // return PreferenceConstants.EDITOR_DEFAULT_HOVER.equals(property) + // || PreferenceConstants.EDITOR_NONE_HOVER.equals(property) + // || PreferenceConstants.EDITOR_CTRL_HOVER.equals(property) + // || PreferenceConstants.EDITOR_SHIFT_HOVER.equals(property) + // || PreferenceConstants.EDITOR_CTRL_ALT_HOVER.equals(property) + // || PreferenceConstants.EDITOR_CTRL_SHIFT_HOVER.equals(property) + // || PreferenceConstants.EDITOR_CTRL_ALT_SHIFT_HOVER.equals(property) + // || PreferenceConstants.EDITOR_ALT_SHIFT_HOVER.equals(property); + // } /** * Shows the line number ruler column. @@ -1599,6 +1909,10 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp c.addDecorator(1, createLineNumberRulerColumn()); } } + private boolean isJavaEditorHoverProperty(String property) { + return PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS.equals(property); + } + /** * Return whether the browser like links should be enabled * according to the preference store settings. @@ -1636,11 +1950,12 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp * @param event the property change event */ protected void handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) { - // if (COMPILER_TASK_TAGS.equals(event.getProperty())) { - // ISourceViewer sourceViewer= getSourceViewer(); - // if (sourceViewer != null && affectsTextPresentation(new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event.getNewValue()))) - // sourceViewer.invalidateTextPresentation(); - // } + if (COMPILER_TASK_TAGS.equals(event.getProperty())) { + ISourceViewer sourceViewer = getSourceViewer(); + if (sourceViewer != null + && affectsTextPresentation(new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event.getNewValue()))) + sourceViewer.invalidateTextPresentation(); + } } /** @@ -1666,6 +1981,15 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp } } + /* + * @see AbstractTextEditor#handleCursorPositionChanged() + */ + protected void handleCursorPositionChanged() { + super.handleCursorPositionChanged(); + if (!isEditingScriptRunning() && fUpdater != null) + fUpdater.post(); + } + /** * Initializes the given line number ruler column from the preference store. * @param rulerColumn the ruler column to be initialized @@ -1785,19 +2109,15 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp /** Preference key for error indication in overview ruler */ protected final static String ERROR_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER; /** Preference key for warning indication in overview ruler */ - protected final static String WARNING_INDICATION_IN_OVERVIEW_RULER = - PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER; + protected final static String WARNING_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER; /** Preference key for task indication in overview ruler */ protected final static String TASK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER; /** Preference key for bookmark indication in overview ruler */ - protected final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER = - PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER; + protected final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER; /** Preference key for search result indication in overview ruler */ - protected final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER = - PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER; + protected final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER; /** Preference key for unknown annotation indication in overview ruler */ - protected final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER = - PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER; + protected final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER; // /** Preference key for compiler task tags */ // private final static String COMPILER_TASK_TAGS= JavaCore.COMPILER_TASK_TAGS; /** Preference key for browser like links */ @@ -1811,8 +2131,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp * * @since 2.1.1 */ - private final static String BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK = - PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK; + private final static String BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK = PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK; private final static char[] BRACKETS = { '{', '}', '(', ')', '[', ']' }; @@ -1881,6 +2200,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp fSourceViewerDecorationSupport.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS, MATCHING_BRACKETS_COLOR); fSourceViewerDecorationSupport.setSymbolicFontName(getFontPropertyPreferenceKey()); + } /** * Jumps to the matching bracket. @@ -2109,4 +2429,99 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp return textTools.affectsBehavior(event); } + /** + * Jumps to the error next according to the given direction. + */ + public void gotoError(boolean forward) { + + ISelectionProvider provider = getSelectionProvider(); + + ITextSelection s = (ITextSelection) provider.getSelection(); + Position errorPosition = new Position(0, 0); + IJavaAnnotation nextError = getNextError(s.getOffset(), forward, errorPosition); + + if (nextError != null) { + + IMarker marker = null; + if (nextError instanceof MarkerAnnotation) + marker = ((MarkerAnnotation) nextError).getMarker(); + else { + Iterator e = nextError.getOverlaidIterator(); + if (e != null) { + while (e.hasNext()) { + Object o = e.next(); + if (o instanceof MarkerAnnotation) { + marker = ((MarkerAnnotation) o).getMarker(); + break; + } + } + } + } + + if (marker != null) { + IWorkbenchPage page = getSite().getPage(); + IViewPart view = view = page.findView("org.eclipse.ui.views.TaskList"); //$NON-NLS-1$ + if (view instanceof TaskList) { + StructuredSelection ss = new StructuredSelection(marker); + ((TaskList) view).setSelection(ss, true); + } + } + + selectAndReveal(errorPosition.getOffset(), errorPosition.getLength()); + setStatusLineErrorMessage(nextError.getMessage()); + + } else { + + setStatusLineErrorMessage(null); + + } + } + + private IJavaAnnotation getNextError(int offset, boolean forward, Position errorPosition) { + + IJavaAnnotation nextError = null; + Position nextErrorPosition = null; + + IDocument document = getDocumentProvider().getDocument(getEditorInput()); + int endOfDocument = document.getLength(); + int distance = 0; + + IAnnotationModel model = getDocumentProvider().getAnnotationModel(getEditorInput()); + Iterator e = new JavaAnnotationIterator(model, false); + while (e.hasNext()) { + + IJavaAnnotation a = (IJavaAnnotation) e.next(); + if (a.hasOverlay() || !a.isProblem()) + continue; + + Position p = model.getPosition((Annotation) a); + if (!p.includes(offset)) { + + int currentDistance = 0; + + if (forward) { + currentDistance = p.getOffset() - offset; + if (currentDistance < 0) + currentDistance = endOfDocument - offset + p.getOffset(); + } else { + currentDistance = offset - p.getOffset(); + if (currentDistance < 0) + currentDistance = offset + endOfDocument - p.getOffset(); + } + + if (nextError == null || currentDistance < distance) { + distance = currentDistance; + nextError = a; + nextErrorPosition = p; + } + } + } + + if (nextErrorPosition != null) { + errorPosition.setOffset(nextErrorPosition.getOffset()); + errorPosition.setLength(nextErrorPosition.getLength()); + } + + return nextError; + } } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParserAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParserAction.java index 3d78be7..8134b38 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParserAction.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParserAction.java @@ -20,6 +20,7 @@ import java.util.List; import net.sourceforge.phpdt.internal.compiler.util.Util; import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.builder.PHPBuilder; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; @@ -69,7 +70,7 @@ public class PHPParserAction extends TextEditorAction { public static void parseFile(IFile fileToParse) { boolean phpFlag = false; - try { +// try { if (fileToParse == null) { // TODO should never happen => should throw an exception @@ -88,12 +89,12 @@ public class PHPParserAction extends TextEditorAction { if (phpFlag) { IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore(); if (store.getString(PHPeclipsePlugin.PHP_PARSER_DEFAULT).equals(PHPeclipsePlugin.PHP_INTERNAL_PARSER)) { - // first delete all the previous markers - fileToParse.deleteMarkers(IMarker.PROBLEM, false, 0); - - //the tasks are removed here - fileToParse.deleteMarkers(IMarker.TASK, false, 0); - +// // first delete all the previous markers +// fileToParse.deleteMarkers(IMarker.PROBLEM, false, 0); +// +// //the tasks are removed here +// fileToParse.deleteMarkers(IMarker.TASK, false, 0); + PHPBuilder.removeProblemsAndTasksFor(fileToParse); // try { // InputStream iStream = fileToParse.getContents(); parse(fileToParse); //, iStream); @@ -104,8 +105,8 @@ public class PHPParserAction extends TextEditorAction { PHPParserSuperclass.phpExternalParse(fileToParse); } } - } catch (CoreException e) { - } +// } catch (CoreException e) { +// } } /** diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSourceViewerConfiguration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSourceViewerConfiguration.java index 7406714..b7f6156 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSourceViewerConfiguration.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSourceViewerConfiguration.java @@ -15,8 +15,14 @@ import java.util.Vector; import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference; import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter; +import net.sourceforge.phpdt.internal.ui.text.JavaElementProvider; +import net.sourceforge.phpdt.internal.ui.text.JavaOutlineInformationControl; +import net.sourceforge.phpdt.internal.ui.text.JavaReconciler; import net.sourceforge.phpdt.internal.ui.text.PHPAnnotationHover; import net.sourceforge.phpdt.internal.ui.text.java.JavaFormattingStrategy; +import net.sourceforge.phpdt.internal.ui.text.java.JavaReconcilingStrategy; +import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor; +import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy; import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCompletionProcessor; import net.sourceforge.phpdt.ui.PreferenceConstants; import net.sourceforge.phpdt.ui.text.JavaTextTools; @@ -31,6 +37,7 @@ import net.sourceforge.phpeclipse.phpeditor.php.PHPDoubleClickSelector; import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider; import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.DefaultAutoIndentStrategy; import org.eclipse.jface.text.DefaultInformationControl; @@ -40,6 +47,7 @@ import org.eclipse.jface.text.IInformationControl; import org.eclipse.jface.text.IInformationControlCreator; import org.eclipse.jface.text.ITextDoubleClickStrategy; import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextViewerExtension2; import org.eclipse.jface.text.TextAttribute; import org.eclipse.jface.text.contentassist.ContentAssistant; import org.eclipse.jface.text.contentassist.IContentAssistProcessor; @@ -47,8 +55,12 @@ import org.eclipse.jface.text.contentassist.IContentAssistant; import org.eclipse.jface.text.formatter.ContentFormatter; import org.eclipse.jface.text.formatter.IContentFormatter; import org.eclipse.jface.text.formatter.IFormattingStrategy; +import org.eclipse.jface.text.information.IInformationPresenter; +import org.eclipse.jface.text.information.IInformationProvider; +import org.eclipse.jface.text.information.InformationPresenter; import org.eclipse.jface.text.presentation.IPresentationReconciler; import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.text.reconciler.IReconciler; import org.eclipse.jface.text.rules.BufferedRuleBasedScanner; import org.eclipse.jface.text.rules.DefaultDamagerRepairer; import org.eclipse.jface.text.rules.DefaultPartitioner; @@ -209,25 +221,102 @@ public class PHPSourceViewerConfiguration extends SourceViewerConfiguration { return fJavaTextTools.getHTMLScanner(); } - /** - * Returns the Smarty source code scanner for this configuration. - * - * @return the Smarty source code scanner - */ - protected RuleBasedScanner getSmartyScanner() { - return fJavaTextTools.getSmartyScanner(); - } - - /** - * Returns the SmartyDoc source code scanner for this configuration. - * - * @return the SmartyDoc source code scanner - */ - protected RuleBasedScanner getSmartyDocScanner() { - return fJavaTextTools.getSmartyDocScanner(); - } - - + /** + * Returns the Smarty source code scanner for this configuration. + * + * @return the Smarty source code scanner + */ + protected RuleBasedScanner getSmartyScanner() { + return fJavaTextTools.getSmartyScanner(); + } + + /* + * @see SourceViewerConfiguration#getReconciler(ISourceViewer) + */ + public IReconciler getReconciler(ISourceViewer sourceViewer) { + + if (getEditor() != null && getEditor().isEditable()) { + JavaReconciler reconciler = new JavaReconciler(getEditor(), new JavaReconcilingStrategy(getEditor()), false); + reconciler.setProgressMonitor(new NullProgressMonitor()); + reconciler.setDelay(500); + return reconciler; + } + + return null; + } + + /* + * @see SourceViewerConfiguration#getConfiguredTextHoverStateMasks(ISourceViewer, String) + * @since 2.1 + */ + public int[] getConfiguredTextHoverStateMasks(ISourceViewer sourceViewer, String contentType) { + JavaEditorTextHoverDescriptor[] hoverDescs = PHPeclipsePlugin.getDefault().getJavaEditorTextHoverDescriptors(); + int stateMasks[] = new int[hoverDescs.length]; + int stateMasksLength = 0; + for (int i = 0; i < hoverDescs.length; i++) { + if (hoverDescs[i].isEnabled()) { + int j = 0; + int stateMask = hoverDescs[i].getStateMask(); + while (j < stateMasksLength) { + if (stateMasks[j] == stateMask) + break; + j++; + } + if (j == stateMasksLength) + stateMasks[stateMasksLength++] = stateMask; + } + } + if (stateMasksLength == hoverDescs.length) + return stateMasks; + + int[] shortenedStateMasks = new int[stateMasksLength]; + System.arraycopy(stateMasks, 0, shortenedStateMasks, 0, stateMasksLength); + return shortenedStateMasks; + } + + /* + * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String, int) + * @since 2.1 + */ + public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType, int stateMask) { + JavaEditorTextHoverDescriptor[] hoverDescs = PHPeclipsePlugin.getDefault().getJavaEditorTextHoverDescriptors(); + int i = 0; + while (i < hoverDescs.length) { + if (hoverDescs[i].isEnabled() && hoverDescs[i].getStateMask() == stateMask) + return new JavaEditorTextHoverProxy(hoverDescs[i], getEditor()); + i++; + } + + if (fEditor != null) { + IEditorInput editorInput = fEditor.getEditorInput(); + if (editorInput instanceof IFileEditorInput) { + try { + IFile f = ((IFileEditorInput) editorInput).getFile(); + return new PHPTextHover(f.getProject()); + } catch (NullPointerException e) { + // this exception occurs, if getTextHover is called by preference pages ! + } + } + } + return new PHPTextHover(null); + } + + /* + * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String) + */ + public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) { + return getTextHover(sourceViewer, contentType, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK); + } + + /** + * Returns the SmartyDoc source code scanner for this configuration. + * + * @return the SmartyDoc source code scanner + */ + protected RuleBasedScanner getSmartyDocScanner() { + return fJavaTextTools.getSmartyDocScanner(); + } + /** * Returns the PHPDoc source code scanner for this configuration. * @@ -251,7 +340,7 @@ public class PHPSourceViewerConfiguration extends SourceViewerConfiguration { IPHPPartitionScannerConstants.JAVASCRIPT, IPHPPartitionScannerConstants.JS_MULTILINE_COMMENT, IPHPPartitionScannerConstants.SMARTY, - IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT, + IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT, IDocument.DEFAULT_CONTENT_TYPE }; } @@ -271,7 +360,7 @@ public class PHPSourceViewerConfiguration extends SourceViewerConfiguration { assistant.setContentAssistProcessor(processor, IPHPPartitionScannerConstants.JS_MULTILINE_COMMENT); // TODO define special smarty partition content assist assistant.setContentAssistProcessor(processor, IPHPPartitionScannerConstants.SMARTY); - assistant.setContentAssistProcessor(processor, IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT); + assistant.setContentAssistProcessor(processor, IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT); assistant.setContentAssistProcessor(new PHPCompletionProcessor(), IPHPPartitionScannerConstants.PHP); @@ -381,15 +470,15 @@ public class PHPSourceViewerConfiguration extends SourceViewerConfiguration { dr = new DefaultDamagerRepairer(getHTMLScanner()); reconciler.setDamager(dr, IPHPPartitionScannerConstants.JS_MULTILINE_COMMENT); reconciler.setRepairer(dr, IPHPPartitionScannerConstants.JS_MULTILINE_COMMENT); - - dr = new DefaultDamagerRepairer(getSmartyScanner()); - reconciler.setDamager(dr, IPHPPartitionScannerConstants.SMARTY); - reconciler.setRepairer(dr, IPHPPartitionScannerConstants.SMARTY); - - dr = new DefaultDamagerRepairer(getSmartyDocScanner()); - reconciler.setDamager(dr, IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT); - reconciler.setRepairer(dr, IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT); - + + dr = new DefaultDamagerRepairer(getSmartyScanner()); + reconciler.setDamager(dr, IPHPPartitionScannerConstants.SMARTY); + reconciler.setRepairer(dr, IPHPPartitionScannerConstants.SMARTY); + + dr = new DefaultDamagerRepairer(getSmartyDocScanner()); + reconciler.setDamager(dr, IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT); + reconciler.setRepairer(dr, IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT); + dr = new DefaultDamagerRepairer( new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor(PHPColorProvider.MULTI_LINE_COMMENT)))); @@ -417,18 +506,20 @@ public class PHPSourceViewerConfiguration extends SourceViewerConfiguration { /* (non-Javadoc) * Method declared on SourceViewerConfiguration */ - public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) { - IEditorInput editorInput = fEditor.getEditorInput(); - if (editorInput instanceof IFileEditorInput) { - try { - IFile f = ((IFileEditorInput) editorInput).getFile(); - return new PHPTextHover(f.getProject()); - } catch (NullPointerException e) { - // this exception occurs, if getTextHover is called by preference pages ! - } - } - return new PHPTextHover(null); - } + // public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) { + // if (fEditor != null) { + // IEditorInput editorInput = fEditor.getEditorInput(); + // if (editorInput instanceof IFileEditorInput) { + // try { + // IFile f = ((IFileEditorInput) editorInput).getFile(); + // return new PHPTextHover(f.getProject()); + // } catch (NullPointerException e) { + // // this exception occurs, if getTextHover is called by preference pages ! + // } + // } + // } + // return new PHPTextHover(null); + // } /* * @see SourceViewerConfiguration#getInformationControlCreator(ISourceViewer) @@ -447,14 +538,14 @@ public class PHPSourceViewerConfiguration extends SourceViewerConfiguration { * @see SourceViewerConfiguration#getInformationPresenter(ISourceViewer) * @since 2.0 */ - // public IInformationPresenter getInformationPresenter(ISourceViewer sourceViewer) { - // InformationPresenter presenter= new InformationPresenter(getInformationPresenterControlCreator(sourceViewer)); - // IInformationProvider provider= new JavaInformationProvider(getEditor()); - // presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE); - // presenter.setInformationProvider(provider, IJavaPartitions.JAVA_DOC); - // presenter.setSizeConstraints(60, 10, true, true); - // return presenter; - // } + // public IInformationPresenter getInformationPresenter(ISourceViewer sourceViewer) { + // InformationPresenter presenter= new InformationPresenter(getInformationPresenterControlCreator(sourceViewer)); + // IInformationProvider provider= new JavaInformationProvider(getEditor()); + // presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE); + // presenter.setInformationProvider(provider, IJavaPartitions.JAVA_DOC); + // presenter.setSizeConstraints(60, 10, true, true); + // return presenter; + // } /** * Returns the information presenter control creator. The creator is a factory creating the @@ -475,4 +566,44 @@ public class PHPSourceViewerConfiguration extends SourceViewerConfiguration { } }; } + /** + * Returns the outline presenter control creator. The creator is a factory creating outline + * presenter controls for the given source viewer. This implementation always returns a creator + * for JavaOutlineInformationControl instances. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return an information control creator + * @since 2.1 + */ + private IInformationControlCreator getOutlinePresenterControlCreator(ISourceViewer sourceViewer) { + return new IInformationControlCreator() { + public IInformationControl createInformationControl(Shell parent) { + int shellStyle = SWT.RESIZE; + int treeStyle = SWT.V_SCROLL | SWT.H_SCROLL; + return new JavaOutlineInformationControl(parent, shellStyle, treeStyle); + } + }; + } + /** + * Returns the outline presenter which will determine and shown + * information requested for the current cursor position. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @param doCodeResolve a boolean which specifies whether code resolve should be used to compute the Java element + * @return an information presenter + * @since 2.1 + */ + public IInformationPresenter getOutlinePresenter(ISourceViewer sourceViewer, boolean doCodeResolve) { + InformationPresenter presenter = new InformationPresenter(getOutlinePresenterControlCreator(sourceViewer)); + presenter.setAnchor(InformationPresenter.ANCHOR_GLOBAL); + IInformationProvider provider = new JavaElementProvider(getEditor(), doCodeResolve); + presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE); + presenter.setInformationProvider(provider, IPHPPartitionScannerConstants.PHP); + presenter.setInformationProvider(provider, IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT); + presenter.setInformationProvider(provider, IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT); + presenter.setInformationProvider(provider, IPHPPartitionScannerConstants.HTML); + presenter.setInformationProvider(provider, IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT); + presenter.setSizeConstraints(40, 20, true, false); + return presenter; + } } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSyntaxParserThread.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSyntaxParserThread.java index 79130b0..b04c4f3 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSyntaxParserThread.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSyntaxParserThread.java @@ -4,9 +4,9 @@ import java.io.IOException; import java.io.InputStream; import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.builder.PHPBuilder; import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.source.ISourceViewer; @@ -135,8 +135,8 @@ public class PHPSyntaxParserThread extends Thread { IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore(); if (store.getString(PHPeclipsePlugin.PHP_PARSER_DEFAULT).equals(PHPeclipsePlugin.PHP_INTERNAL_PARSER)) { // first delete all the previous markers - fileToParse.deleteMarkers(IMarker.PROBLEM, false, 0); - +// fileToParse.deleteMarkers(IMarker.PROBLEM, false, 0); + PHPBuilder.removeProblemsAndTasksFor(fileToParse); try { InputStream iStream = fileToParse.getContents(); // int c = iStream.read(); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java index 63c79a4..833c8f8 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java @@ -1,16 +1,23 @@ package net.sourceforge.phpeclipse.phpeditor; +import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.ISourceRange; +import net.sourceforge.phpdt.core.ISourceReference; +import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.internal.compiler.parser.Scanner; import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference; import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher; import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager; import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI; import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI.ExitFlags; +import net.sourceforge.phpdt.ui.IWorkingCopyManager; import net.sourceforge.phpdt.ui.PreferenceConstants; import net.sourceforge.phpdt.ui.text.JavaTextTools; import net.sourceforge.phpeclipse.PHPCore; @@ -18,11 +25,18 @@ import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.phpeditor.php.IPHPPartitionScannerConstants; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Preferences; import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; import org.eclipse.jface.text.BadLocationException; @@ -39,9 +53,9 @@ import org.eclipse.jface.text.contentassist.IContentAssistant; import org.eclipse.jface.text.source.IOverviewRuler; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.IVerticalRuler; -import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.jface.text.source.SourceViewerConfiguration; import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.swt.custom.VerifyKeyListener; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.graphics.Color; @@ -53,8 +67,11 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.actions.ActionContext; +import org.eclipse.ui.actions.WorkspaceModifyOperation; +import org.eclipse.ui.dialogs.SaveAsDialog; import org.eclipse.ui.editors.text.IStorageDocumentProvider; import org.eclipse.ui.help.WorkbenchHelp; +import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.texteditor.IDocumentProvider; /********************************************************************** @@ -334,7 +351,7 @@ public class PHPUnitEditor extends PHPEditor { // // }; - class AdaptedSourceViewer extends SourceViewer { + class AdaptedSourceViewer extends JavaSourceViewer { private List fTextConverters; private boolean fIgnoreTextConverters = false; @@ -577,12 +594,12 @@ public class PHPUnitEditor extends PHPEditor { } - // private static class BracketLevel { - // int fOffset; - // int fLength; - // LinkedPositionManager fManager; - // LinkedPositionUI fEditor; - // }; + private static class BracketLevel { + int fOffset; + int fLength; + LinkedPositionManager fManager; + LinkedPositionUI fEditor; + }; private class BracketInserter implements VerifyKeyListener, LinkedPositionUI.ExitListener { @@ -807,6 +824,12 @@ public class PHPUnitEditor extends PHPEditor { } } + + /** The editor's save policy */ + protected ISavePolicy fSavePolicy; + /** Listener to annotation model changes that updates the error tick in the tab image */ + private JavaEditorErrorTickUpdater fJavaEditorErrorTickUpdater; + /** The editor's paint manager */ // private PaintManager fPaintManager; /** The editor's bracket painter */ @@ -826,6 +849,8 @@ public class PHPUnitEditor extends PHPEditor { /** The preference property change listener for php core. */ // private IPropertyChangeListener fPropertyChangeListener = new PropertyChangeListener(); + /** The remembered java element */ + private IJavaElement fRememberedElement; /** The remembered selection */ private ITextSelection fRememberedSelection; /** The remembered php element offset */ @@ -988,7 +1013,63 @@ public class PHPUnitEditor extends PHPEditor { setDocumentProvider(PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider()); setEditorContextMenuId("#PHPEditorContext"); //$NON-NLS-1$ setRulerContextMenuId("#PHPRulerContext"); //$NON-NLS-1$ + setOutlinerContextMenuId("#PHPOutlinerContext"); //$NON-NLS-1$ + // don't set help contextId, we install our own help context + fSavePolicy = null; + fJavaEditorErrorTickUpdater = new JavaEditorErrorTickUpdater(this); + } + + /* + * @see JavaEditor#getElementAt(int) + */ + protected IJavaElement getElementAt(int offset) { + return getElementAt(offset, true); + } + + /** + * Returns the most narrow element including the given offset. If reconcile + * is true the editor's input element is reconciled in advance. If it is + * false this method only returns a result if the editor's input element + * does not need to be reconciled. + * + * @param offset the offset included by the retrieved element + * @param reconcile true if working copy should be reconciled + */ + protected IJavaElement getElementAt(int offset, boolean reconcile) { + IWorkingCopyManager manager = PHPeclipsePlugin.getDefault().getWorkingCopyManager(); + ICompilationUnit unit = manager.getWorkingCopy(getEditorInput()); + + if (unit != null) { + try { + if (reconcile) { + synchronized (unit) { + unit.reconcile(); + } + return unit.getElementAt(offset); + } else if (unit.isConsistent()) + return unit.getElementAt(offset); + + } catch (JavaModelException x) { + PHPeclipsePlugin.log(x.getStatus()); + // nothing found, be tolerant and go on + } + } + + return null; + } + + /* + * @see JavaEditor#getCorrespondingElement(IJavaElement) + */ + protected IJavaElement getCorrespondingElement(IJavaElement element) { + try { + return EditorUtility.getWorkingCopy(element, true); + } catch (JavaModelException x) { + PHPeclipsePlugin.log(x.getStatus()); + // nothing found, be tolerant and go on + } + return null; } public void createPartControl(Composite parent) { @@ -1039,8 +1120,8 @@ public class PHPUnitEditor extends PHPEditor { ISourceViewer sourceViewer = getSourceViewer(); if (sourceViewer instanceof ITextViewerExtension) - ((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter); - + ((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter); + } private static char getPeerCharacter(char character) { @@ -1064,7 +1145,86 @@ public class PHPUnitEditor extends PHPEditor { throw new IllegalArgumentException(); } } + /** + * The compilation unit editor implementation of this AbstractTextEditor + * method asks the user for the workspace path of a file resource and saves the document + * there. See http://dev.eclipse.org/bugs/show_bug.cgi?id=6295 + */ + protected void performSaveAs(IProgressMonitor progressMonitor) { + + Shell shell = getSite().getShell(); + IEditorInput input = getEditorInput(); + + SaveAsDialog dialog = new SaveAsDialog(shell); + + IFile original = (input instanceof IFileEditorInput) ? ((IFileEditorInput) input).getFile() : null; + if (original != null) + dialog.setOriginalFile(original); + + dialog.create(); + IDocumentProvider provider = getDocumentProvider(); + if (provider == null) { + // editor has been programmatically closed while the dialog was open + return; + } + + if (provider.isDeleted(input) && original != null) { + String message = PHPEditorMessages.getFormattedString("CompilationUnitEditor.warning.save.delete", new Object[] { original.getName()}); //$NON-NLS-1$ + dialog.setErrorMessage(null); + dialog.setMessage(message, IMessageProvider.WARNING); + } + + if (dialog.open() == Dialog.CANCEL) { + if (progressMonitor != null) + progressMonitor.setCanceled(true); + return; + } + + IPath filePath = dialog.getResult(); + if (filePath == null) { + if (progressMonitor != null) + progressMonitor.setCanceled(true); + return; + } + + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IFile file = workspace.getRoot().getFile(filePath); + final IEditorInput newInput = new FileEditorInput(file); + + WorkspaceModifyOperation op = new WorkspaceModifyOperation() { + public void execute(final IProgressMonitor monitor) throws CoreException { + getDocumentProvider().saveDocument(monitor, newInput, getDocumentProvider().getDocument(getEditorInput()), true); + } + }; + + boolean success = false; + try { + + provider.aboutToChange(newInput); + new ProgressMonitorDialog(shell).run(false, true, op); + success = true; + + } catch (InterruptedException x) { + } catch (InvocationTargetException x) { + + Throwable t = x.getTargetException(); + if (t instanceof CoreException) { + CoreException cx = (CoreException) t; + ErrorDialog.openError(shell, PHPEditorMessages.getString("CompilationUnitEditor.error.saving.title2"), PHPEditorMessages.getString("CompilationUnitEditor.error.saving.message2"), cx.getStatus()); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + MessageDialog.openError(shell, PHPEditorMessages.getString("CompilationUnitEditor.error.saving.title3"), PHPEditorMessages.getString("CompilationUnitEditor.error.saving.message3") + t.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ + } + + } finally { + provider.changed(newInput); + if (success) + setInput(newInput); + } + + if (progressMonitor != null) + progressMonitor.setCanceled(!success); + } /* * @see AbstractTextEditor#doSetInput(IEditorInput) */ @@ -1303,11 +1463,11 @@ public class PHPUnitEditor extends PHPEditor { // fPropertyChangeListener = null; // } - // if (fJavaEditorErrorTickUpdater != null) { - // fJavaEditorErrorTickUpdater.dispose(); - // fJavaEditorErrorTickUpdater= null; - // } - // + if (fJavaEditorErrorTickUpdater != null) { + fJavaEditorErrorTickUpdater.dispose(); + fJavaEditorErrorTickUpdater = null; + } + // if (fSelectionHistory != null) // fSelectionHistory.dispose(); @@ -1429,13 +1589,13 @@ public class PHPUnitEditor extends PHPEditor { return; } - if (OVERVIEW_RULER.equals(p)) { - if (isOverviewRulerVisible()) - showOverviewRuler(); - else - hideOverviewRuler(); - return; - } + // if (OVERVIEW_RULER.equals(p)) { + // if (isOverviewRulerVisible()) + // showOverviewRuler(); + // else + // hideOverviewRuler(); + // return; + // } // AnnotationType type = getAnnotationType(p); // if (type != null) { @@ -1579,6 +1739,35 @@ public class PHPUnitEditor extends PHPEditor { } /* + * @see JavaEditor#setOutlinePageInput(JavaOutlinePage, IEditorInput) + */ + protected void setOutlinePageInput(JavaOutlinePage page, IEditorInput input) { + if (page != null) { + IWorkingCopyManager manager = PHPeclipsePlugin.getDefault().getWorkingCopyManager(); + page.setInput(manager.getWorkingCopy(input)); + } + } + + /* + * @see AbstractTextEditor#performSaveOperation(WorkspaceModifyOperation, IProgressMonitor) + */ + protected void performSaveOperation(WorkspaceModifyOperation operation, IProgressMonitor progressMonitor) { + IDocumentProvider p = getDocumentProvider(); + if (p instanceof PHPDocumentProvider) { + PHPDocumentProvider cp = (PHPDocumentProvider) p; + cp.setSavePolicy(fSavePolicy); + } + + try { + super.performSaveOperation(operation, progressMonitor); + } finally { + if (p instanceof PHPDocumentProvider) { + PHPDocumentProvider cp = (PHPDocumentProvider) p; + cp.setSavePolicy(null); + } + } + } + /* * @see AbstractTextEditor#doSaveAs */ public void doSaveAs() { @@ -1664,4 +1853,109 @@ public class PHPUnitEditor extends PHPEditor { } return true; } + /* + * @see IReconcilingParticipant#reconciled() + */ + public void reconciled() { + if (synchronizeOutlineOnCursorMove()) { + Shell shell = getSite().getShell(); + if (shell != null && !shell.isDisposed()) { + shell.getDisplay().asyncExec(new Runnable() { + public void run() { + synchronizeOutlinePageSelection(); + } + }); + } + } + } + + private boolean synchronizeOutlineOnCursorMove() { + return PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE); + } + protected void updateStateDependentActions() { + super.updateStateDependentActions(); + fGenerateActionGroup.editorStateChanged(); + } + + /** + * Returns the updated java element for the old java element. + */ + private IJavaElement findElement(IJavaElement element) { + + if (element == null) + return null; + + IWorkingCopyManager manager = PHPeclipsePlugin.getDefault().getWorkingCopyManager(); + ICompilationUnit unit = manager.getWorkingCopy(getEditorInput()); + + if (unit != null) { + try { + + synchronized (unit) { + unit.reconcile(); + } + IJavaElement[] findings = unit.findElements(element); + if (findings != null && findings.length > 0) + return findings[0]; + + } catch (JavaModelException x) { + PHPeclipsePlugin.log(x.getStatus()); + // nothing found, be tolerant and go on + } + } + + return null; + } + + /** + * Returns the offset of the given Java element. + */ + private int getOffset(IJavaElement element) { + if (element instanceof ISourceReference) { + ISourceReference sr = (ISourceReference) element; + try { + ISourceRange srcRange = sr.getSourceRange(); + if (srcRange != null) + return srcRange.getOffset(); + } catch (JavaModelException e) { + } + } + return -1; + } + + /* + * @see AbstractTextEditor#rememberSelection() + */ + protected void rememberSelection() { + ISelectionProvider sp = getSelectionProvider(); + fRememberedSelection = (sp == null ? null : (ITextSelection) sp.getSelection()); + if (fRememberedSelection != null) { + fRememberedElement = getElementAt(fRememberedSelection.getOffset(), true); + fRememberedElementOffset = getOffset(fRememberedElement); + } + } + + /* + * @see AbstractTextEditor#restoreSelection() + */ + protected void restoreSelection() { + + try { + + if (getSourceViewer() == null || fRememberedSelection == null) + return; + + IJavaElement newElement = findElement(fRememberedElement); + int newOffset = getOffset(newElement); + int delta = (newOffset > -1 && fRememberedElementOffset > -1) ? newOffset - fRememberedElementOffset : 0; + if (isValidSelection(delta + fRememberedSelection.getOffset(), fRememberedSelection.getLength())) + selectAndReveal(delta + fRememberedSelection.getOffset(), fRememberedSelection.getLength()); + + } finally { + fRememberedSelection = null; + fRememberedElement = null; + fRememberedElementOffset = -1; + } + } + } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/WorkingCopyManager.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/WorkingCopyManager.java new file mode 100644 index 0000000..38fc5c0 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/WorkingCopyManager.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package net.sourceforge.phpeclipse.phpeditor; + + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jface.text.Assert; + +import org.eclipse.ui.IEditorInput; + +import net.sourceforge.phpdt.core.ICompilationUnit; + +import net.sourceforge.phpdt.ui.IWorkingCopyManager; +import net.sourceforge.phpdt.ui.IWorkingCopyManagerExtension; + + +/** + * This working copy manager works together with a given compilation unit document provider and + * additionally offers to "overwrite" the working copy provided by this document provider. + */ +public class WorkingCopyManager implements IWorkingCopyManager, IWorkingCopyManagerExtension { + + private PHPDocumentProvider fDocumentProvider; + private Map fMap; + private boolean fIsShuttingDown; + + /** + * Creates a new working copy manager that co-operates with the given + * compilation unit document provider. + * + * @param provider the provider + */ + public WorkingCopyManager(PHPDocumentProvider provider) { + Assert.isNotNull(provider); + fDocumentProvider= provider; + } + + /* + * @see org.eclipse.jdt.ui.IWorkingCopyManager#connect(org.eclipse.ui.IEditorInput) + */ + public void connect(IEditorInput input) throws CoreException { + fDocumentProvider.connect(input); + } + + /* + * @see org.eclipse.jdt.ui.IWorkingCopyManager#disconnect(org.eclipse.ui.IEditorInput) + */ + public void disconnect(IEditorInput input) { + fDocumentProvider.disconnect(input); + } + + /* + * @see org.eclipse.jdt.ui.IWorkingCopyManager#shutdown() + */ + public void shutdown() { + if (!fIsShuttingDown) { + fIsShuttingDown= true; + try { + if (fMap != null) { + fMap.clear(); + fMap= null; + } + fDocumentProvider.shutdown(); + } finally { + fIsShuttingDown= false; + } + } + } + + /* + * @see org.eclipse.jdt.ui.IWorkingCopyManager#getWorkingCopy(org.eclipse.ui.IEditorInput) + */ + public ICompilationUnit getWorkingCopy(IEditorInput input) { + ICompilationUnit unit= fMap == null ? null : (ICompilationUnit) fMap.get(input); + return unit != null ? unit : fDocumentProvider.getWorkingCopy(input); + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.IWorkingCopyManagerExtension#setWorkingCopy(org.eclipse.ui.IEditorInput, org.eclipse.jdt.core.ICompilationUnit) + */ + public void setWorkingCopy(IEditorInput input, ICompilationUnit workingCopy) { + if (fDocumentProvider.isConnected(input)) { + if (fMap == null) + fMap= new HashMap(); + fMap.put(input, workingCopy); + } + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.IWorkingCopyManagerExtension#removeWorkingCopy(org.eclipse.ui.IEditorInput) + */ + public void removeWorkingCopy(IEditorInput input) { + fMap.remove(input); + if (fMap.isEmpty()) + fMap= null; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java index 4d4acc5..b0ba0b8 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java @@ -32,7 +32,7 @@ import net.sourceforge.phpdt.internal.ui.text.template.IdentifierEngine; import net.sourceforge.phpdt.internal.ui.text.template.TemplateEngine; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.builder.IdentifierIndexManager; -import net.sourceforge.phpeclipse.phpeditor.AbstractContentOutlinePage; +import net.sourceforge.phpeclipse.phpeditor.JavaOutlinePage; import net.sourceforge.phpeclipse.phpeditor.PHPContentOutlinePage; import net.sourceforge.phpeclipse.phpeditor.PHPEditor; import net.sourceforge.phpeclipse.phpeditor.PHPSyntaxRdr; @@ -246,17 +246,18 @@ public class PHPCompletionProcessor implements IContentAssistProcessor { if (offset > 0) { PHPEditor editor = null; - AbstractContentOutlinePage outlinePage = null; +// JavaOutlinePage outlinePage = null; IEditorPart targetEditor = PHPeclipsePlugin.getActiveWorkbenchWindow().getActivePage().getActiveEditor(); if (targetEditor != null && (targetEditor instanceof PHPEditor)) { editor = (PHPEditor) targetEditor; file = ((IFileEditorInput) editor.getEditorInput()).getFile(); project = file.getProject(); - outlinePage = editor.getfOutlinePage(); - if (outlinePage instanceof PHPContentOutlinePage) { - identifiers = ((PHPContentOutlinePage) outlinePage).getVariables(); - } +// outlinePage = editor.getfOutlinePage(); + // TODO: get the identifiers from the new model +// if (outlinePage instanceof PHPContentOutlinePage) { +// identifiers = ((PHPContentOutlinePage) outlinePage).getVariables(); +// } } } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/preferences/PHPProjectLibraryPage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/preferences/PHPProjectLibraryPage.java index 32749ce..4a69135 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/preferences/PHPProjectLibraryPage.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/preferences/PHPProjectLibraryPage.java @@ -5,8 +5,9 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; +import net.sourceforge.phpdt.internal.core.JavaProject; +import net.sourceforge.phpdt.internal.ui.preferences.PHPEditorPreferencePage; import net.sourceforge.phpeclipse.PHPeclipsePlugin; -import net.sourceforge.phpeclipse.resourcesview.PHPProject; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; @@ -30,9 +31,9 @@ import org.eclipse.ui.ISharedImages; import org.eclipse.ui.IWorkbench; public class PHPProjectLibraryPage { - protected PHPProject workingProject; + protected JavaProject workingProject; - protected PHPProjectLibraryPage(PHPProject theWorkingProject) { + protected PHPProjectLibraryPage(JavaProject theWorkingProject) { super(); workingProject = theWorkingProject; } @@ -48,7 +49,7 @@ public class PHPProjectLibraryPage { TableColumn tableColumn = new TableColumn(projectsTable, SWT.NONE); tableColumn.setWidth(200); - tableColumn.setText(PHPPreferencesMessages.getString("PHPProjectLibraryPage.project")); //$NON-NLS-1$ + tableColumn.setText(PHPPreferencesMessages.getString("PHPEditorPreferencePageLibraryPage.project")); //$NON-NLS-1$ CheckboxTableViewer projectsTableViewer = new CheckboxTableViewer(projectsTable); projectsTableViewer.addCheckStateListener(new ICheckStateListener() { @@ -74,7 +75,7 @@ public class PHPProjectLibraryPage { getWorkingProject().removeLoadPathEntry(checkEventProject); } - protected PHPProject getWorkingProject() { + protected JavaProject getWorkingProject() { return workingProject; } @@ -94,7 +95,7 @@ public class PHPProjectLibraryPage { if (element instanceof IProject) return ((IProject) element).getName(); - return PHPPreferencesMessages.getString("PHPProjectLibraryPage.elementNotIProject"); //$NON-NLS-1$ + return PHPPreferencesMessages.getString("PHPEditorPreferencePageLibraryPage.elementNotIProject"); //$NON-NLS-1$ } public void addListener(ILabelProviderListener listener) { @@ -116,17 +117,17 @@ public class PHPProjectLibraryPage { protected IContentProvider getContentProvider() { IStructuredContentProvider contentProvider = new IStructuredContentProvider() { - protected List phpProjects; + protected List PHPEditorPreferencePages; public Object[] getElements(Object inputElement) { - return phpProjects.toArray(); + return PHPEditorPreferencePages.toArray(); } public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - phpProjects = new ArrayList(); + PHPEditorPreferencePages = new ArrayList(); if (!(newInput instanceof List)) return; @@ -139,7 +140,7 @@ public class PHPProjectLibraryPage { if (project.getName() != workingProject.getProject().getName()) { try { if (project.hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) - phpProjects.add(project); + PHPEditorPreferencePages.add(project); } catch (CoreException e) { } } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/preferences/PHPProjectPropertyPage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/preferences/PHPProjectPropertyPage.java index 55e6f90..e336c0b 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/preferences/PHPProjectPropertyPage.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/preferences/PHPProjectPropertyPage.java @@ -1,7 +1,7 @@ package net.sourceforge.phpeclipse.preferences; +import net.sourceforge.phpdt.internal.core.JavaProject; import net.sourceforge.phpeclipse.PHPeclipsePlugin; -import net.sourceforge.phpeclipse.resourcesview.PHPProject; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; @@ -21,7 +21,7 @@ import org.eclipse.ui.dialogs.PropertyPage; public class PHPProjectPropertyPage extends PropertyPage implements IWorkbenchPropertyPage { protected PHPProjectLibraryPage projectsPage; - protected PHPProject workingProject; + protected JavaProject workingProject; public PHPProjectPropertyPage() { } @@ -36,19 +36,19 @@ public class PHPProjectPropertyPage extends PropertyPage implements IWorkbenchPr return createProjectPageContents(parent); } - protected PHPProject getPHPProject() { + protected JavaProject getPHPProject() { IAdaptable selectedElement = getElement(); if (selectedElement == null) return null; - if (selectedElement instanceof PHPProject) - return (PHPProject) selectedElement; + if (selectedElement instanceof JavaProject) + return (JavaProject) selectedElement; if (selectedElement instanceof IProject) { IProject simpleProject = (IProject) selectedElement; try { if (simpleProject.hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) { - PHPProject phpProject = new PHPProject(); + JavaProject phpProject = new JavaProject(); phpProject.setProject(simpleProject); return phpProject; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/resourcesview/PHPProject_DeleteIt.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/resourcesview/PHPProject_DeleteIt.java new file mode 100644 index 0000000..5477b46 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/resourcesview/PHPProject_DeleteIt.java @@ -0,0 +1,216 @@ +package net.sourceforge.phpeclipse.resourcesview; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.xml.parsers.SAXParserFactory; + +import net.sourceforge.phpeclipse.LoadPathEntry; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +import org.eclipse.core.resources.ICommand; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IProjectNature; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +public class PHPProject_DeleteIt implements IProjectNature, PHPElement { + protected IProject fProject; + // protected IndexFileReader fIndexManager; + protected List fLoadPathEntries; + protected boolean fScratched; + + public PHPProject_DeleteIt() { + } + + public void addLoadPathEntry(IProject anotherPHPProject) { + fScratched = true; + + LoadPathEntry newEntry = new LoadPathEntry(anotherPHPProject); + getLoadPathEntries().add(newEntry); + } + + public void configure() throws CoreException { + // get project description and then the associated build commands + IProjectDescription desc = fProject.getDescription(); + ICommand[] commands = desc.getBuildSpec(); + + // determine if builder already associated + boolean found = false; + for (int i = 0; i < commands.length; ++i) { + if (commands[i].getBuilderName().equals(PHPeclipsePlugin.BUILDER_PARSER_ID)) { + found = true; + break; + } + } + + // add builder if not already in project + if (!found) { + ICommand command = desc.newCommand(); + command.setBuilderName(PHPeclipsePlugin.BUILDER_PARSER_ID); + ICommand[] newCommands = new ICommand[commands.length + 1]; + + // Add it before other builders. + System.arraycopy(commands, 0, newCommands, 1, commands.length); + newCommands[0] = command; + desc.setBuildSpec(newCommands); + fProject.setDescription(desc, null); + } + } + + public void deconfigure() throws CoreException { + } + + public List getLoadPathEntries() { + if (fLoadPathEntries == null) { + loadLoadPathEntries(); + } + + return fLoadPathEntries; + } + + protected ContentHandler getLoadPathEntriesContentHandler() { + return new ContentHandler() { + public void characters(char[] arg0, int arg1, int arg2) throws SAXException { + } + + public void endDocument() throws SAXException { + } + + public void endElement(String arg0, String arg1, String arg2) throws SAXException { + } + + public void endPrefixMapping(String arg0) throws SAXException { + } + + public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException { + } + + public void processingInstruction(String arg0, String arg1) throws SAXException { + } + + public void setDocumentLocator(Locator arg0) { + } + + public void skippedEntity(String arg0) throws SAXException { + } + + public void startDocument() throws SAXException { + } + + public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { + if ("pathentry".equals(qName)) + if ("project".equals(atts.getValue("type"))) { + IPath referencedProjectPath = new Path(atts.getValue("path")); + IProject referencedProject = getProject(referencedProjectPath.lastSegment()); + fLoadPathEntries.add(new LoadPathEntry(referencedProject)); + } + } + + public void startPrefixMapping(String arg0, String arg1) throws SAXException { + } + }; + } + + protected IFile getLoadPathEntriesFile() { + return fProject.getFile(".loadpath"); + } + + protected String getLoadPathXML() { + StringBuffer buffer = new StringBuffer(); + buffer.append(""); + + Iterator pathEntriesIterator = fLoadPathEntries.iterator(); + + while (pathEntriesIterator.hasNext()) { + LoadPathEntry entry = (LoadPathEntry) pathEntriesIterator.next(); + buffer.append(entry.toXML()); + } + + buffer.append(""); + return buffer.toString(); + } + + public IProject getProject() { + return fProject; + } + + protected IProject getProject(String name) { + return PHPeclipsePlugin.getWorkspace().getRoot().getProject(name); + } + + public List getReferencedProjects() { + List referencedProjects = new ArrayList(); + + Iterator iterator = getLoadPathEntries().iterator(); + while (iterator.hasNext()) { + LoadPathEntry pathEntry = (LoadPathEntry) iterator.next(); + if (pathEntry.getType() == LoadPathEntry.TYPE_PROJECT) + referencedProjects.add(pathEntry.getProject()); + } + + return referencedProjects; + } + + public IResource getUnderlyingResource() { + return fProject; + } + + protected void loadLoadPathEntries() { + fLoadPathEntries = new ArrayList(); + + IFile loadPathsFile = getLoadPathEntriesFile(); + + XMLReader reader = null; + try { + reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + reader.setContentHandler(getLoadPathEntriesContentHandler()); + reader.parse(new InputSource(loadPathsFile.getContents())); + } catch (Exception e) { + //the file is nonextant or unreadable + } + } + + public void removeLoadPathEntry(IProject anotherPHPProject) { + Iterator entries = getLoadPathEntries().iterator(); + while (entries.hasNext()) { + LoadPathEntry entry = (LoadPathEntry) entries.next(); + if (entry.getType() == LoadPathEntry.TYPE_PROJECT && entry.getProject().getName().equals(anotherPHPProject.getName())) { + getLoadPathEntries().remove(entry); + fScratched = true; + break; + } + } + } + + public void save() throws CoreException { + if (fScratched) { + InputStream xmlPath = new ByteArrayInputStream(getLoadPathXML().getBytes()); + IFile loadPathsFile = getLoadPathEntriesFile(); + if (!loadPathsFile.exists()) + loadPathsFile.create(xmlPath, true, null); + else + loadPathsFile.setContents(xmlPath, true, false, null); + + fScratched = false; + } + } + + public void setProject(IProject aProject) { + fProject = aProject; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/resourcesview/ResourceAdapterFactory.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/resourcesview/ResourceAdapterFactory.java index 0e403f7..e288032 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/resourcesview/ResourceAdapterFactory.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/resourcesview/ResourceAdapterFactory.java @@ -1,5 +1,6 @@ package net.sourceforge.phpeclipse.resourcesview; +import net.sourceforge.phpdt.internal.core.JavaProject; import net.sourceforge.phpeclipse.PHPCore; import org.eclipse.core.resources.IFile; @@ -8,7 +9,7 @@ import org.eclipse.core.runtime.IAdapterFactory; public class ResourceAdapterFactory implements IAdapterFactory { - protected static Class[] ADAPTERS_I_CREATE = new Class[] { PHPElement.class, PHPFile.class, PHPProject.class }; + protected static Class[] ADAPTERS_I_CREATE = new Class[] { PHPElement.class, PHPFile.class, JavaProject.class }; public ResourceAdapterFactory() { super(); @@ -18,7 +19,7 @@ public class ResourceAdapterFactory implements IAdapterFactory { if (PHPFile.class.equals(adapterType)) return PHPCore.create((IFile) adaptableObject); - if (PHPProject.class.equals(adapterType)) + if (JavaProject.class.equals(adapterType)) return PHPCore.create((IProject) adaptableObject); if (PHPElement.class.equals(adapterType)) { diff --git a/net.sourceforge.phpeclipse/src/test/PHPParser.java b/net.sourceforge.phpeclipse/src/test/PHPParser.java index c4cc3b5..4030cca 100644 --- a/net.sourceforge.phpeclipse/src/test/PHPParser.java +++ b/net.sourceforge.phpeclipse/src/test/PHPParser.java @@ -1,25 +1,83 @@ /* Generated By:JavaCC: Do not edit this line. PHPParser.java */ package test; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.ui.texteditor.MarkerUtilities; -import org.eclipse.jface.preference.IPreferenceStore; - -import java.util.Hashtable; -import java.util.ArrayList; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.Reader; import java.io.StringReader; -import java.io.*; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Hashtable; -import net.sourceforge.phpeclipse.actions.PHPStartApacheAction; -import net.sourceforge.phpeclipse.PHPeclipsePlugin; -import net.sourceforge.phpdt.internal.compiler.ast.*; -import net.sourceforge.phpdt.internal.compiler.parser.OutlineableWithChildren; +import net.sourceforge.phpdt.core.IJavaModelMarker; +import net.sourceforge.phpdt.internal.compiler.ast.AbstractCase; +import net.sourceforge.phpdt.internal.compiler.ast.AbstractVariable; +import net.sourceforge.phpdt.internal.compiler.ast.ArrayDeclarator; +import net.sourceforge.phpdt.internal.compiler.ast.ArrayInitializer; +import net.sourceforge.phpdt.internal.compiler.ast.ArrayVariableDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.AstNode; +import net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression; +import net.sourceforge.phpdt.internal.compiler.ast.Block; +import net.sourceforge.phpdt.internal.compiler.ast.Break; +import net.sourceforge.phpdt.internal.compiler.ast.Case; +import net.sourceforge.phpdt.internal.compiler.ast.CastExpression; +import net.sourceforge.phpdt.internal.compiler.ast.ClassAccess; +import net.sourceforge.phpdt.internal.compiler.ast.ClassDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.ClassInstantiation; +import net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression; +import net.sourceforge.phpdt.internal.compiler.ast.ConstantIdentifier; +import net.sourceforge.phpdt.internal.compiler.ast.Continue; +import net.sourceforge.phpdt.internal.compiler.ast.DefaultCase; +import net.sourceforge.phpdt.internal.compiler.ast.Define; +import net.sourceforge.phpdt.internal.compiler.ast.DoStatement; +import net.sourceforge.phpdt.internal.compiler.ast.EchoStatement; +import net.sourceforge.phpdt.internal.compiler.ast.Else; +import net.sourceforge.phpdt.internal.compiler.ast.ElseIf; +import net.sourceforge.phpdt.internal.compiler.ast.EmptyStatement; +import net.sourceforge.phpdt.internal.compiler.ast.Expression; +import net.sourceforge.phpdt.internal.compiler.ast.FalseLiteral; +import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.ForStatement; +import net.sourceforge.phpdt.internal.compiler.ast.ForeachStatement; +import net.sourceforge.phpdt.internal.compiler.ast.FunctionCall; +import net.sourceforge.phpdt.internal.compiler.ast.GlobalStatement; +import net.sourceforge.phpdt.internal.compiler.ast.HTMLBlock; +import net.sourceforge.phpdt.internal.compiler.ast.HTMLCode; +import net.sourceforge.phpdt.internal.compiler.ast.IfStatement; +import net.sourceforge.phpdt.internal.compiler.ast.InclusionStatement; +import net.sourceforge.phpdt.internal.compiler.ast.LabeledStatement; +import net.sourceforge.phpdt.internal.compiler.ast.ListExpression; +import net.sourceforge.phpdt.internal.compiler.ast.Literal; +import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.NullLiteral; +import net.sourceforge.phpdt.internal.compiler.ast.NumberLiteral; +import net.sourceforge.phpdt.internal.compiler.ast.OperatorIds; +import net.sourceforge.phpdt.internal.compiler.ast.PHPDocument; +import net.sourceforge.phpdt.internal.compiler.ast.PHPEchoBlock; +import net.sourceforge.phpdt.internal.compiler.ast.PostfixedUnaryExpression; +import net.sourceforge.phpdt.internal.compiler.ast.PrefixedUnaryExpression; +import net.sourceforge.phpdt.internal.compiler.ast.PrintExpression; +import net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement; +import net.sourceforge.phpdt.internal.compiler.ast.Statement; +import net.sourceforge.phpdt.internal.compiler.ast.StaticStatement; +import net.sourceforge.phpdt.internal.compiler.ast.StringLiteral; +import net.sourceforge.phpdt.internal.compiler.ast.SwitchStatement; +import net.sourceforge.phpdt.internal.compiler.ast.TrueLiteral; +import net.sourceforge.phpdt.internal.compiler.ast.Variable; +import net.sourceforge.phpdt.internal.compiler.ast.VariableDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.WhileStatement; import net.sourceforge.phpdt.internal.compiler.parser.Outlineable; +import net.sourceforge.phpdt.internal.compiler.parser.OutlineableWithChildren; import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo; -import net.sourceforge.phpdt.internal.corext.Assert; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.actions.PHPStartApacheAction; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.ui.texteditor.MarkerUtilities; /** * A new php parser. @@ -28,7 +86,7 @@ import net.sourceforge.phpdt.internal.corext.Assert; * You can test the parser with the PHPParserTestCase2.java * @author Matthieu Casanova */ -public final class PHPParser extends PHPParserSuperclass implements PHPParserConstants { +public class PHPParser extends PHPParserSuperclass implements PHPParserConstants { //todo : fix the variables names bug //todo : handle tilde operator @@ -60,7 +118,7 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon //ast stack private final static int AstStackIncrement = 100; /** The stack of node. */ - private static AstNode[] nodes; + protected static AstNode[] nodes; /** The cursor in expression stack. */ private static int nodePtr; @@ -78,26 +136,24 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon PHPParser.fileToParse = fileToParse; } - public final void phpParserTester(final String strEval) throws ParseException { + public static final void phpParserTester(final String strEval) throws ParseException { final StringReader stream = new StringReader(strEval); if (jj_input_stream == null) { jj_input_stream = new SimpleCharStream(stream, 1, 1); - token_source = new PHPParserTokenManager(jj_input_stream); } ReInit(new StringReader(strEval)); init(); phpDocument = new PHPDocument(null,"_root".toCharArray()); currentSegment = phpDocument; outlineInfo = new PHPOutlineInfo(null, currentSegment); - token_source.SwitchTo(PHPParserTokenManager.PHPPARSING); + PHPParserTokenManager.SwitchTo(PHPParserTokenManager.PHPPARSING); phpTest(); } - public final void htmlParserTester(final File fileName) throws FileNotFoundException, ParseException { + public static final void htmlParserTester(final File fileName) throws FileNotFoundException, ParseException { final Reader stream = new FileReader(fileName); if (jj_input_stream == null) { jj_input_stream = new SimpleCharStream(stream, 1, 1); - token_source = new PHPParserTokenManager(jj_input_stream); } ReInit(stream); init(); @@ -107,11 +163,10 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon phpFile(); } - public final void htmlParserTester(final String strEval) throws ParseException { + public static final void htmlParserTester(final String strEval) throws ParseException { final StringReader stream = new StringReader(strEval); if (jj_input_stream == null) { jj_input_stream = new SimpleCharStream(stream, 1, 1); - token_source = new PHPParserTokenManager(jj_input_stream); } ReInit(stream); init(); @@ -124,7 +179,7 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon /** * Reinitialize the parser. */ - private static final void init() { + protected static final void init() { nodes = new AstNode[AstStackIncrement]; nodePtr = -1; htmlStart = 0; @@ -154,7 +209,6 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon final StringReader stream = new StringReader(s); if (jj_input_stream == null) { jj_input_stream = new SimpleCharStream(stream, 1, 1); - token_source = new PHPParserTokenManager(jj_input_stream); } ReInit(stream); init(); @@ -265,7 +319,8 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon else attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO)); MarkerUtilities.setLineNumber(attributes, lineNumber); - MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM); +// MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM); + MarkerUtilities.createMarker(file, attributes, IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); } } } @@ -274,7 +329,6 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon final StringReader stream = new StringReader(s); if (jj_input_stream == null) { jj_input_stream = new SimpleCharStream(stream, 1, 1); - token_source = new PHPParserTokenManager(jj_input_stream); } ReInit(stream); init(); @@ -310,51 +364,51 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon /** * Put a new html block in the stack. */ - public final void createNewHTMLCode() { + public static final void createNewHTMLCode() { final int currentPosition = token.sourceStart; if (currentPosition == htmlStart || currentPosition < htmlStart || - currentPosition > jj_input_stream.getCurrentBuffer().length()) { + currentPosition > SimpleCharStream.currentBuffer.length()) { return; } - final String html = jj_input_stream.getCurrentBuffer().substring(htmlStart, currentPosition); + final String html = SimpleCharStream.currentBuffer.substring(htmlStart, currentPosition); pushOnAstNodes(new HTMLCode(html, htmlStart,currentPosition)); } /** Create a new task. */ - public final void createNewTask(final int todoStart) { - final String todo = jj_input_stream.getCurrentBuffer().substring(todoStart, - jj_input_stream.getCurrentBuffer().indexOf("\n", + public static final void createNewTask(final int todoStart) { + final String todo = SimpleCharStream.currentBuffer.substring(todoStart, + SimpleCharStream.currentBuffer.indexOf("\n", todoStart)-1); if (!PARSER_DEBUG) { try { setMarker(fileToParse, todo, - jj_input_stream.getBeginLine(), + SimpleCharStream.getBeginLine(), TASK, - "Line "+jj_input_stream.getBeginLine()); + "Line "+SimpleCharStream.getBeginLine()); } catch (CoreException e) { PHPeclipsePlugin.log(e); } } } - private final void parse() throws ParseException { + protected static final void parse() throws ParseException { phpFile(); } - final public void todo() throws ParseException { + static final public void todo() throws ParseException { Token todoToken; todoToken = jj_consume_token(23); createNewTask(todoToken.sourceStart); } - final public void phpTest() throws ParseException { + static final public void phpTest() throws ParseException { Php(); jj_consume_token(0); } - final public void phpFile() throws ParseException { + static final public void phpFile() throws ParseException { try { label_1: while (true) { @@ -414,11 +468,11 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon } PhpBlock(); } - createNewHTMLCode(); + PHPParser.createNewHTMLCode(); } catch (TokenMgrError e) { PHPeclipsePlugin.log(e); - errorStart = jj_input_stream.getBeginOffset(); - errorEnd = jj_input_stream.getEndOffset(); + errorStart = SimpleCharStream.beginOffset; + errorEnd = SimpleCharStream.endOffset; errorMessage = e.getMessage(); errorLevel = ERROR; {if (true) throw generateParseException();} @@ -430,7 +484,7 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon * or * or */ - final public void PhpBlock() throws ParseException { + static final public void PhpBlock() throws ParseException { final PHPEchoBlock phpEchoBlock; final Token token,phpEnd; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -514,7 +568,7 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon jj_la1[2] = jj_gen; ; } - createNewHTMLCode(); + PHPParser.createNewHTMLCode(); Php(); try { phpEnd = jj_consume_token(PHPEND); @@ -534,12 +588,12 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon } } - final public PHPEchoBlock phpEchoBlock() throws ParseException { + static final public PHPEchoBlock phpEchoBlock() throws ParseException { final Expression expr; final PHPEchoBlock echoBlock; final Token token, token2; token = jj_consume_token(PHPECHOSTART); - createNewHTMLCode(); + PHPParser.createNewHTMLCode(); expr = Expression(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case SEMICOLON: @@ -558,7 +612,7 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon throw new Error("Missing return statement in function"); } - final public void Php() throws ParseException { + static final public void Php() throws ParseException { label_2: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -615,7 +669,7 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon } } - final public ClassDeclaration ClassDeclaration() throws ParseException { + static final public ClassDeclaration ClassDeclaration() throws ParseException { final ClassDeclaration classDeclaration; Token className = null; final Token superclassName, token, extendsToken; @@ -683,7 +737,7 @@ public final class PHPParser extends PHPParserSuperclass implements PHPParserCon throw new Error("Missing return statement in function"); } - final public int ClassBody(final ClassDeclaration classDeclaration) throws ParseException { + static final public int ClassBody(final ClassDeclaration classDeclaration) throws ParseException { Token token; try { jj_consume_token(LBRACE); @@ -716,7 +770,7 @@ Token token; errorStart = e.currentToken.sourceStart; errorEnd = e.currentToken.sourceEnd; processParseExceptionDebug(e); - {if (true) return this.token.sourceEnd;} + {if (true) return PHPParser.token.sourceEnd;} } throw new Error("Missing return statement in function"); } @@ -724,7 +778,7 @@ Token token; /** * A class can contain only methods and fields. */ - final public void ClassBodyDeclaration(final ClassDeclaration classDeclaration) throws ParseException { + static final public void ClassBodyDeclaration(final ClassDeclaration classDeclaration) throws ParseException { final MethodDeclaration method; final FieldDeclaration field; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -748,7 +802,7 @@ Token token; * A class field declaration : it's var VariableDeclarator() (, VariableDeclarator())*;. * it is only used by ClassBodyDeclaration() */ - final public FieldDeclaration FieldDeclaration() throws ParseException { + static final public FieldDeclaration FieldDeclaration() throws ParseException { VariableDeclaration variableDeclaration; final VariableDeclaration[] list; final ArrayList arrayList = new ArrayList(); @@ -803,7 +857,7 @@ Token token; * a strict variable declarator : there cannot be a suffix here. * It will be used by fields and formal parameters */ - final public VariableDeclaration VariableDeclaratorNoSuffix() throws ParseException { + static final public VariableDeclaration VariableDeclaratorNoSuffix() throws ParseException { final Token token, lbrace,rbrace; Expression expr, initializer = null; Token assignToken; @@ -859,7 +913,7 @@ Token token; /** * this will be used by static statement */ - final public VariableDeclaration VariableDeclarator() throws ParseException { + static final public VariableDeclaration VariableDeclarator() throws ParseException { final AbstractVariable variable; Expression initializer = null; final Token token; @@ -899,8 +953,9 @@ Token token; * A Variable name. * @return the variable name (with suffix) */ - final public AbstractVariable VariableDeclaratorId() throws ParseException { - AbstractVariable var; + static final public AbstractVariable VariableDeclaratorId() throws ParseException { + final Variable var; + AbstractVariable expression = null; try { var = Variable(); label_5: @@ -910,9 +965,12 @@ Token token; } else { break label_5; } - var = VariableSuffix(var); + expression = VariableSuffix(var); } - {if (true) return var;} + if (expression == null) { + {if (true) return var;} + } + {if (true) return expression;} } catch (ParseException e) { errorMessage = "'$' expected for variable identifier"; errorLevel = ERROR; @@ -923,7 +981,7 @@ Token token; throw new Error("Missing return statement in function"); } - final public Variable Variable() throws ParseException { + static final public Variable Variable() throws ParseException { Variable variable = null; final Token token; token = jj_consume_token(DOLLAR); @@ -932,7 +990,7 @@ Token token; throw new Error("Missing return statement in function"); } - final public Variable Var() throws ParseException { + static final public Variable Var() throws ParseException { Variable variable = null; final Token token,token2; ConstantIdentifier constant; @@ -964,7 +1022,7 @@ Token token; throw new Error("Missing return statement in function"); } - final public Expression VariableInitializer() throws ParseException { + static final public Expression VariableInitializer() throws ParseException { final Expression expr; final Token token, token2; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -1030,7 +1088,7 @@ Token token; throw new Error("Missing return statement in function"); } - final public ArrayVariableDeclaration ArrayVariable() throws ParseException { + static final public ArrayVariableDeclaration ArrayVariable() throws ParseException { final Expression expr,expr2; expr = Expression(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -1043,11 +1101,11 @@ final Expression expr,expr2; jj_la1[17] = jj_gen; ; } - {if (true) return new ArrayVariableDeclaration(expr,jj_input_stream.getPosition());} + {if (true) return new ArrayVariableDeclaration(expr,SimpleCharStream.getPosition());} throw new Error("Missing return statement in function"); } - final public ArrayVariableDeclaration[] ArrayInitializer() throws ParseException { + static final public ArrayVariableDeclaration[] ArrayInitializer() throws ParseException { ArrayVariableDeclaration expr; final ArrayList list = new ArrayList(); jj_consume_token(LPAREN); @@ -1112,7 +1170,7 @@ final Expression expr,expr2; * A Method Declaration. * function MetodDeclarator() Block() */ - final public MethodDeclaration MethodDeclaration() throws ParseException { + static final public MethodDeclaration MethodDeclaration() throws ParseException { final MethodDeclaration functionDeclaration; final Block block; final OutlineableWithChildren seg = currentSegment; @@ -1142,7 +1200,7 @@ final Expression expr,expr2; * [&] IDENTIFIER(parameters ...). * @return a function description for the outline */ - final public MethodDeclaration MethodDeclarator(final int start) throws ParseException { + static final public MethodDeclaration MethodDeclarator(final int start) throws ParseException { Token identifier = null; Token reference = null; final ArrayList formalParameters = new ArrayList(); @@ -1197,10 +1255,10 @@ final Expression expr,expr2; * FormalParameters follows method identifier. * (FormalParameter()) */ - final public int FormalParameters(final ArrayList parameters) throws ParseException { + static final public int FormalParameters(final ArrayList parameters) throws ParseException { VariableDeclaration var; final Token token; - Token tok = this.token; + Token tok = PHPParser.token; int end = tok.sourceEnd; try { tok = jj_consume_token(LPAREN); @@ -1254,7 +1312,7 @@ final Expression expr,expr2; * A formal parameter. * $varname[=value] (,$varname[=value]) */ - final public VariableDeclaration FormalParameter() throws ParseException { + static final public VariableDeclaration FormalParameter() throws ParseException { final VariableDeclaration variableDeclaration; Token token = null; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -1274,7 +1332,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public ConstantIdentifier Type() throws ParseException { + static final public ConstantIdentifier Type() throws ParseException { final Token token; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case STRING: @@ -1321,7 +1379,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression Expression() throws ParseException { + static final public Expression Expression() throws ParseException { final Expression expr; Expression initializer = null; int assignOperator = -1; @@ -1370,7 +1428,7 @@ final Expression expr,expr2; } errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected"; errorLevel = ERROR; - errorEnd = jj_input_stream.getPosition(); + errorEnd = SimpleCharStream.getPosition(); {if (true) throw e;} } break; @@ -1409,7 +1467,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression ExpressionWBang() throws ParseException { + static final public Expression ExpressionWBang() throws ParseException { final Expression expr; final Token token; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -1431,7 +1489,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression ExpressionNoBang() throws ParseException { + static final public Expression ExpressionNoBang() throws ParseException { Expression expr; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LIST: @@ -1454,7 +1512,7 @@ final Expression expr,expr2; * Any assignement operator. * @return the assignement operator id */ - final public int AssignmentOperator() throws ParseException { + static final public int AssignmentOperator() throws ParseException { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case ASSIGN: jj_consume_token(ASSIGN); @@ -1516,7 +1574,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression ConditionalExpression() throws ParseException { + static final public Expression ConditionalExpression() throws ParseException { final Expression expr; Expression expr2 = null; Expression expr3 = null; @@ -1539,7 +1597,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression ConditionalOrExpression() throws ParseException { + static final public Expression ConditionalOrExpression() throws ParseException { Expression expr,expr2; int operator; expr = ConditionalAndExpression(); @@ -1575,7 +1633,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression ConditionalAndExpression() throws ParseException { + static final public Expression ConditionalAndExpression() throws ParseException { Expression expr,expr2; int operator; expr = ConcatExpression(); @@ -1611,7 +1669,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression ConcatExpression() throws ParseException { + static final public Expression ConcatExpression() throws ParseException { Expression expr,expr2; expr = InclusiveOrExpression(); label_10: @@ -1632,7 +1690,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression InclusiveOrExpression() throws ParseException { + static final public Expression InclusiveOrExpression() throws ParseException { Expression expr,expr2; expr = ExclusiveOrExpression(); label_11: @@ -1653,7 +1711,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression ExclusiveOrExpression() throws ParseException { + static final public Expression ExclusiveOrExpression() throws ParseException { Expression expr,expr2; expr = AndExpression(); label_12: @@ -1674,7 +1732,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression AndExpression() throws ParseException { + static final public Expression AndExpression() throws ParseException { Expression expr,expr2; expr = EqualityExpression(); label_13: @@ -1695,7 +1753,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression EqualityExpression() throws ParseException { + static final public Expression EqualityExpression() throws ParseException { Expression expr,expr2; int operator; Token token; @@ -1759,7 +1817,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression RelationalExpression() throws ParseException { + static final public Expression RelationalExpression() throws ParseException { Expression expr,expr2; int operator; expr = ShiftExpression(); @@ -1805,7 +1863,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression ShiftExpression() throws ParseException { + static final public Expression ShiftExpression() throws ParseException { Expression expr,expr2; int operator; expr = AdditiveExpression(); @@ -1846,7 +1904,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression AdditiveExpression() throws ParseException { + static final public Expression AdditiveExpression() throws ParseException { Expression expr,expr2; int operator; expr = MultiplicativeExpression(); @@ -1882,7 +1940,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression MultiplicativeExpression() throws ParseException { + static final public Expression MultiplicativeExpression() throws ParseException { Expression expr,expr2; int operator; try { @@ -1891,8 +1949,8 @@ final Expression expr,expr2; if (errorMessage != null) {if (true) throw e;} errorMessage = "unexpected token '"+e.currentToken.next.image+'\''; errorLevel = ERROR; - errorStart = this.token.sourceStart; - errorEnd = this.token.sourceEnd; + errorStart = PHPParser.token.sourceStart; + errorEnd = PHPParser.token.sourceEnd; {if (true) throw e;} } label_18: @@ -1935,7 +1993,7 @@ final Expression expr,expr2; /** * An unary expression starting with @, & or nothing */ - final public Expression UnaryExpression() throws ParseException { + static final public Expression UnaryExpression() throws ParseException { final Expression expr; /* expr = UnaryExpressionNoPrefix() //why did I had that ? {return new PrefixedUnaryExpression(expr,OperatorIds.AND,pos);} @@ -1945,7 +2003,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression AtNotTildeUnaryExpression() throws ParseException { + static final public Expression AtNotTildeUnaryExpression() throws ParseException { final Expression expr; final Token token; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -1996,7 +2054,7 @@ final Expression expr,expr2; * An expression prefixed (or not) by one or more @ and !. * @return the expression */ - final public Expression AtNotUnaryExpression() throws ParseException { + static final public Expression AtNotUnaryExpression() throws ParseException { final Expression expr; final Token token; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -2038,7 +2096,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression UnaryExpressionNoPrefix() throws ParseException { + static final public Expression UnaryExpressionNoPrefix() throws ParseException { final Expression expr; final Token token; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -2085,7 +2143,7 @@ final Expression expr,expr2; throw new Error("Missing return statement in function"); } - final public Expression PreIncDecExpression() throws ParseException { + static final public Expression PreIncDecExpression() throws ParseException { final Expression expr; final int operator; final Token token; @@ -2108,7 +2166,7 @@ final Token token; throw new Error("Missing return statement in function"); } - final public Expression UnaryExpressionNotPlusMinus() throws ParseException { + static final public Expression UnaryExpressionNotPlusMinus() throws ParseException { final Expression expr; if (jj_2_3(2147483647)) { expr = CastExpression(); @@ -2156,7 +2214,7 @@ final Token token; throw new Error("Missing return statement in function"); } - final public CastExpression CastExpression() throws ParseException { + static final public CastExpression CastExpression() throws ParseException { final ConstantIdentifier type; final Expression expr; final Token token,token1; @@ -2188,7 +2246,7 @@ final Token token,token1; throw new Error("Missing return statement in function"); } - final public Expression PostfixExpression() throws ParseException { + static final public Expression PostfixExpression() throws ParseException { final Expression expr; int operator = -1; Token token = null; @@ -2222,7 +2280,7 @@ final Token token,token1; throw new Error("Missing return statement in function"); } - final public Expression PrimaryExpression() throws ParseException { + static final public Expression PrimaryExpression() throws ParseException { Expression expr; Token token = null; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -2253,7 +2311,7 @@ final Token token,token1; throw new Error("Missing return statement in function"); } - final public Expression refPrimaryExpression(final Token reference) throws ParseException { + static final public Expression refPrimaryExpression(final Token reference) throws ParseException { Expression expr; Expression expr2 = null; final Token identifier; @@ -2345,18 +2403,18 @@ final Token token,token1; * array(vars) * @return an array */ - final public ArrayInitializer ArrayDeclarator() throws ParseException { + static final public ArrayInitializer ArrayDeclarator() throws ParseException { final ArrayVariableDeclaration[] vars; final Token token; token = jj_consume_token(ARRAY); vars = ArrayInitializer(); {if (true) return new ArrayInitializer(vars, token.sourceStart, - this.token.sourceEnd);} + PHPParser.token.sourceEnd);} throw new Error("Missing return statement in function"); } - final public Expression ClassIdentifier() throws ParseException { + static final public Expression ClassIdentifier() throws ParseException { final Expression expr; final Token token; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -2391,7 +2449,7 @@ final Token token,token1; /** * Used by Variabledeclaratorid and primarysuffix */ - final public AbstractVariable VariableSuffix(final AbstractVariable prefix) throws ParseException { + static final public AbstractVariable VariableSuffix(final AbstractVariable prefix) throws ParseException { Expression expression = null; final Token classAccessToken,lbrace,rbrace; Token token; @@ -2630,7 +2688,7 @@ final Token token,token1; throw new Error("Missing return statement in function"); } - final public Literal Literal() throws ParseException { + static final public Literal Literal() throws ParseException { final Token token; StringLiteral literal; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -2670,7 +2728,7 @@ final Token token,token1; throw new Error("Missing return statement in function"); } - final public StringLiteral evaluableString() throws ParseException { + static final public StringLiteral evaluableString() throws ParseException { ArrayList list = new ArrayList(); Token start,end; Token token,lbrace,rbrace; @@ -2712,14 +2770,14 @@ final Token token,token1; end = jj_consume_token(DOUBLEQUOTE2); AbstractVariable[] vars = new AbstractVariable[list.size()]; list.toArray(vars); - {if (true) return new StringLiteral(jj_input_stream.getCurrentBuffer().substring(start.sourceEnd,end.sourceStart), + {if (true) return new StringLiteral(SimpleCharStream.currentBuffer.substring(start.sourceEnd,end.sourceStart), start.sourceStart, end.sourceEnd, vars);} throw new Error("Missing return statement in function"); } - final public FunctionCall Arguments(final Expression func) throws ParseException { + static final public FunctionCall Arguments(final Expression func) throws ParseException { Expression[] args = null; final Token token,lparen; lparen = jj_consume_token(LPAREN); @@ -2777,7 +2835,7 @@ final Token token,lparen; * argumentDeclaration() (, argumentDeclaration)* * @return an array of arguments */ - final public Expression[] ArgumentList() throws ParseException { + static final public Expression[] ArgumentList() throws ParseException { Expression arg; final ArrayList list = new ArrayList(); int pos; @@ -2818,7 +2876,7 @@ Token token; * A Statement without break. * @return a statement */ - final public Statement StatementNoBreak() throws ParseException { + static final public Statement StatementNoBreak() throws ParseException { final Statement statement; Token token = null; if (jj_2_4(2)) { @@ -2920,7 +2978,7 @@ Token token; * expression ; * @return an expression */ - final public Statement expressionStatement() throws ParseException { + static final public Statement expressionStatement() throws ParseException { final Statement statement; final Token token; statement = Expression(); @@ -2940,7 +2998,7 @@ Token token; throw new Error("Missing return statement in function"); } - final public Define defineStatement() throws ParseException { + static final public Define defineStatement() throws ParseException { Expression defineName,defineValue; final Token defineToken; Token token; @@ -3010,7 +3068,7 @@ Token token; /** * A Normal statement. */ - final public Statement Statement() throws ParseException { + static final public Statement Statement() throws ParseException { final Statement statement; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case IF: @@ -3071,7 +3129,7 @@ Token token; /** * An html block inside a php syntax. */ - final public HTMLBlock htmlBlock() throws ParseException { + static final public HTMLBlock htmlBlock() throws ParseException { final int startIndex = nodePtr; final AstNode[] blockNodes; final int nbNodes; @@ -3103,7 +3161,7 @@ Token token; jj_consume_token(-1); throw new ParseException(); } - createNewHTMLCode(); + PHPParser.createNewHTMLCode(); } catch (ParseException e) { errorMessage = "unexpected end of file , '= 100) return; if (pos == jj_endpos + 1) { jj_lasttokens[jj_endpos++] = kind; @@ -7462,7 +7542,7 @@ final ArrayList list = new ArrayList(); } } - public ParseException generateParseException() { + static public ParseException generateParseException() { jj_expentries.removeAllElements(); boolean[] la1tokens = new boolean[160]; for (int i = 0; i < 160; i++) { @@ -7510,13 +7590,13 @@ final ArrayList list = new ArrayList(); return new ParseException(token, exptokseq, tokenImage); } - final public void enable_tracing() { + static final public void enable_tracing() { } - final public void disable_tracing() { + static final public void disable_tracing() { } - final private void jj_rescan_token() { + static final private void jj_rescan_token() { jj_rescan = true; for (int i = 0; i < 5; i++) { JJCalls p = jj_2_rtns[i]; @@ -7537,7 +7617,7 @@ final ArrayList list = new ArrayList(); jj_rescan = false; } - final private void jj_save(int index, int xla) { + static final private void jj_save(int index, int xla) { JJCalls p = jj_2_rtns[index]; while (p.gen > jj_gen) { if (p.next == null) { p = p.next = new JJCalls(); break; } @@ -7553,4 +7633,5 @@ final ArrayList list = new ArrayList(); JJCalls next; } + } diff --git a/net.sourceforge.phpeclipse/src/test/PHPParserSuperclass.java b/net.sourceforge.phpeclipse/src/test/PHPParserSuperclass.java index bdb5fdf..f612a6c 100644 --- a/net.sourceforge.phpeclipse/src/test/PHPParserSuperclass.java +++ b/net.sourceforge.phpeclipse/src/test/PHPParserSuperclass.java @@ -3,10 +3,12 @@ package test; import java.text.MessageFormat; import java.util.Hashtable; +import net.sourceforge.phpdt.core.IJavaModelMarker; import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo; import net.sourceforge.phpdt.internal.ui.util.StringUtil; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.actions.PHPStartApacheAction; +import net.sourceforge.phpeclipse.builder.PHPBuilder; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; @@ -60,7 +62,8 @@ public abstract class PHPParserSuperclass { */ protected static void createMarkers(final String output, final IFile file) throws CoreException { // delete all markers - file.deleteMarkers(IMarker.PROBLEM, false, 0); +// file.deleteMarkers(IMarker.PROBLEM, false, 0); + PHPBuilder.removeProblemsAndTasksFor(file); int indx = 0; int brIndx; @@ -114,7 +117,8 @@ public abstract class PHPParserSuperclass { else attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO)); MarkerUtilities.setLineNumber(attributes, lineNumber); - MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM); +// MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM); + MarkerUtilities.createMarker(file, attributes, IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); } } } @@ -176,7 +180,8 @@ public abstract class PHPParserSuperclass { } MarkerUtilities.setCharStart(attributes, charStart); MarkerUtilities.setCharEnd(attributes, charEnd); - MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM); +// MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM); + MarkerUtilities.createMarker(file, attributes, IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); } } @@ -196,7 +201,8 @@ public abstract class PHPParserSuperclass { final String location) throws CoreException { if (file != null) { - String markerKind = IMarker.PROBLEM; +// String markerKind = IMarker.PROBLEM; + String markerKind = IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER; final Hashtable attributes = new Hashtable(); MarkerUtilities.setMessage(attributes, message); switch (errorLevel) { @@ -211,7 +217,8 @@ public abstract class PHPParserSuperclass { break; case TASK: attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO)); - markerKind = IMarker.TASK; +// markerKind = IMarker.TASK; + markerKind = IJavaModelMarker.TASK_MARKER; break; } attributes.put(IMarker.LOCATION, location); @@ -278,7 +285,8 @@ public abstract class PHPParserSuperclass { attributes.put(IMarker.LOCATION, location); MarkerUtilities.setCharStart(attributes, charStart); MarkerUtilities.setCharEnd(attributes, charEnd); - MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM); +// MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM); + MarkerUtilities.createMarker(file, attributes, IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); } } }