From 0d24fabd8465ec38211180897106f3e7e5976f7c Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Thu, 23 Oct 2014 02:24:48 +0200 Subject: [PATCH 001/132] Update pydevd. --- python/helpers/pydev/_pydev_imports_tipper.py | 7 +++++-- python/helpers/pydev/_pydev_threading.py | 5 ++++- python/helpers/pydev/pydev_runfiles.py | 8 ++++++-- python/helpers/pydev/pydevd.py | 7 ++++--- python/helpers/pydev/pydevd_plugin_utils.py | 2 +- python/helpers/pydev/pydevd_resolver.py | 10 +++++----- python/helpers/pydev/runfiles.py | 2 ++ 7 files changed, 27 insertions(+), 14 deletions(-) diff --git a/python/helpers/pydev/_pydev_imports_tipper.py b/python/helpers/pydev/_pydev_imports_tipper.py index 76cf2cdc473f..35c4867533a8 100644 --- a/python/helpers/pydev/_pydev_imports_tipper.py +++ b/python/helpers/pydev/_pydev_imports_tipper.py @@ -178,8 +178,11 @@ def GenerateImportsTipForModule(obj_to_complete, dirComps=None, getattr=getattr, args = '' try: - obj = getattr(obj_to_complete, d) - except: #just ignore and get it without aditional info + try: + obj = getattr(obj_to_complete.__class__, d) + except: + obj = getattr(obj_to_complete, d) + except: #just ignore and get it without additional info ret.append((d, '', args, TYPE_BUILTIN)) else: diff --git a/python/helpers/pydev/_pydev_threading.py b/python/helpers/pydev/_pydev_threading.py index 62b300b86cd0..940dce5edcf3 100644 --- a/python/helpers/pydev/_pydev_threading.py +++ b/python/helpers/pydev/_pydev_threading.py @@ -1,4 +1,7 @@ -from threading import enumerate, currentThread, Condition, Event, Timer, Thread +from threading import * # Make up for things we may forget @UnusedWildImport + +# Force what we know we need +from threading import enumerate, currentThread, Condition, Event, Timer, Thread, Lock try: from threading import settrace except: diff --git a/python/helpers/pydev/pydev_runfiles.py b/python/helpers/pydev/pydev_runfiles.py index bb704db3f240..b20927584088 100644 --- a/python/helpers/pydev/pydev_runfiles.py +++ b/python/helpers/pydev/pydev_runfiles.py @@ -3,11 +3,9 @@ from __future__ import nested_scopes import fnmatch import os.path from pydev_runfiles_coverage import StartCoverageSupport -import pydev_runfiles_unittest from pydevd_constants import * #@UnusedWildImport import re import time -import unittest #======================================================================================================================= @@ -558,6 +556,7 @@ class PydevTestRunner(object): def _decorate_test_suite(self, suite, pyfile, module_name): + import unittest if isinstance(suite, unittest.TestSuite): add = False suite.__pydev_pyfile__ = pyfile @@ -582,6 +581,8 @@ class PydevTestRunner(object): def find_tests_from_modules(self, file_and_modules_and_module_name): """ returns the unittests given a list of modules """ #Use our own suite! + import pydev_runfiles_unittest + import unittest unittest.TestLoader.suiteClass = pydev_runfiles_unittest.PydevTestSuite loader = unittest.TestLoader() @@ -628,6 +629,7 @@ class PydevTestRunner(object): def filter_tests(self, test_objs, internal_call=False): """ based on a filter name, only return those tests that have the test case names that match """ + import unittest if not internal_call: if not self.configuration.include_tests and not self.tests and not self.configuration.exclude_tests: #No need to filter if we have nothing to filter! @@ -692,6 +694,7 @@ class PydevTestRunner(object): def iter_tests(self, test_objs): #Note: not using yield because of Jython 2.1. + import unittest tests = [] for test_obj in test_objs: if isinstance(test_obj, unittest.TestSuite): @@ -762,6 +765,7 @@ class PydevTestRunner(object): all_tests = self.find_tests_from_modules(file_and_modules_and_module_name) all_tests = self.filter_tests(all_tests) + import pydev_runfiles_unittest test_suite = pydev_runfiles_unittest.PydevTestSuite(all_tests) import pydev_runfiles_xml_rpc pydev_runfiles_xml_rpc.notifyTestsCollected(test_suite.countTestCases()) diff --git a/python/helpers/pydev/pydevd.py b/python/helpers/pydev/pydevd.py index cd6a034e5aba..dfac7691dc79 100644 --- a/python/helpers/pydev/pydevd.py +++ b/python/helpers/pydev/pydevd.py @@ -116,9 +116,10 @@ DONT_TRACE = { 'threading.py':1, # thirs party libs that we don't want to trace - 'pluginbase.py':1, - 'pkgutil_old.py':1, - 'uuid_old.py':1, + '_pydev_pluginbase.py':1, + '_pydev_pkgutil_old.py':1, + '_pydev_uuid_old.py':1, + #things from pydev that we don't want to trace '_pydev_execfile.py':1, diff --git a/python/helpers/pydev/pydevd_plugin_utils.py b/python/helpers/pydev/pydevd_plugin_utils.py index f50bdf8425e8..4ccdfb44e3df 100644 --- a/python/helpers/pydev/pydevd_plugin_utils.py +++ b/python/helpers/pydev/pydevd_plugin_utils.py @@ -2,7 +2,7 @@ import types import pydev_log import pydevd_trace_api -from third_party.pluginbase import PluginBase +from _pydev_imps._pydev_pluginbase import PluginBase from pydevd_constants import * # @UnusedWildImport def load_plugins(package): diff --git a/python/helpers/pydev/pydevd_resolver.py b/python/helpers/pydev/pydevd_resolver.py index cc67cd043cec..a1c7a1dfe40e 100644 --- a/python/helpers/pydev/pydevd_resolver.py +++ b/python/helpers/pydev/pydevd_resolver.py @@ -18,7 +18,7 @@ from pydevd_constants import DictIterItems, xrange # Note: 300 is already a lot to see in the outline (after that the user should really use the shell to get things) # and this also means we'll pass less information to the client side (which makes debugging faster). -MAX_ITEMS_TO_HANDLE = 300 +MAX_ITEMS_TO_HANDLE = 300 TOO_LARGE_MSG = 'Too large to show contents. Max items to show: ' + str(MAX_ITEMS_TO_HANDLE) TOO_LARGE_ATTR = 'Unable to handle:' @@ -284,11 +284,11 @@ class TupleResolver: #to enumerate tuples and lists for item in var: d[format_str % i] = item i += 1 - + if i > MAX_ITEMS_TO_HANDLE: d[TOO_LARGE_ATTR] = TOO_LARGE_MSG break - + d['__len__'] = len(var) return d @@ -319,12 +319,12 @@ class SetResolver: for item in var: i+= 1 d[id(item)] = item - + if i > MAX_ITEMS_TO_HANDLE: d[TOO_LARGE_ATTR] = TOO_LARGE_MSG break - + d['__len__'] = len(var) return d diff --git a/python/helpers/pydev/runfiles.py b/python/helpers/pydev/runfiles.py index c2db611055c4..3e6c0d656b3a 100644 --- a/python/helpers/pydev/runfiles.py +++ b/python/helpers/pydev/runfiles.py @@ -190,6 +190,8 @@ def main(): argv.append('-p') argv.append('pydev_runfiles_pytest2') + if 'unittest' in sys.modules or 'unittest2' in sys.modules: + sys.stderr.write('pydev test runner error: imported unittest before running pytest.main\n') return pytest.main(argv) else: From f611621f547a474056bc5c2670cf728c0387683d Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Thu, 23 Oct 2014 02:30:22 +0200 Subject: [PATCH 002/132] Matplotlib support in console. --- python/helpers/pydev/import_hook.py | 43 ++++++ .../pydev/pydev_ipython/matplotlibtools.py | 133 ++++++++++++++++++ python/helpers/pydev/pydevconsole.py | 9 ++ 3 files changed, 185 insertions(+) create mode 100644 python/helpers/pydev/import_hook.py create mode 100644 python/helpers/pydev/pydev_ipython/matplotlibtools.py diff --git a/python/helpers/pydev/import_hook.py b/python/helpers/pydev/import_hook.py new file mode 100644 index 000000000000..64bc623c22fe --- /dev/null +++ b/python/helpers/pydev/import_hook.py @@ -0,0 +1,43 @@ + +import sys +from pydevd_constants import IS_PY24, IS_PY3K +from pydevd_constants import DictContains +from types import ModuleType + + +class ImportHookManager(ModuleType): + def __init__(self, name, system_import): + ModuleType.__init__(self, name) + self._system_import = system_import + self._modules_to_patch = {} + + def add_module_name(self, module_name, activate_function): + self._modules_to_patch[module_name] = activate_function + + def do_import(self, name, globals=None, locals=None, fromlist=None, level=-2): + if level == -2: + # fake impossible value; default value depends on version + if IS_PY24: + # the level parameter was added in version 2.5 + return self._system_import(name, globals, locals, fromlist) + elif IS_PY3K: + # default value for level parameter in python 3 + level = 0 + else: + # default value for level parameter in other versions + level = -1 + module = self._system_import(name, globals, locals, fromlist, level) + if DictContains(self._modules_to_patch, name): + self._modules_to_patch[name]() #call activate function + self._modules_to_patch.pop(name) + return module + +try: + import __builtin__ as builtins +except ImportError: + import builtins + +import_hook_manager = ImportHookManager(__name__ + '.import_hook', builtins.__import__) +builtins.__import__ = import_hook_manager.do_import +sys.modules[import_hook_manager.__name__] = import_hook_manager +del builtins \ No newline at end of file diff --git a/python/helpers/pydev/pydev_ipython/matplotlibtools.py b/python/helpers/pydev/pydev_ipython/matplotlibtools.py new file mode 100644 index 000000000000..2b9f1e72209e --- /dev/null +++ b/python/helpers/pydev/pydev_ipython/matplotlibtools.py @@ -0,0 +1,133 @@ + +import sys +from import_hook import import_hook_manager + +backends = {'tk': 'TkAgg', + 'gtk': 'GTKAgg', + 'wx': 'WXAgg', + 'qt': 'Qt4Agg', # qt3 not supported + 'qt4': 'Qt4Agg', + 'osx': 'MacOSX'} + +# We also need a reverse backends2guis mapping that will properly choose which +# GUI support to activate based on the desired matplotlib backend. For the +# most part it's just a reverse of the above dict, but we also need to add a +# few others that map to the same GUI manually: +backend2gui = dict(zip(backends.values(), backends.keys())) +backend2gui['Qt4Agg'] = 'qt' +# In the reverse mapping, there are a few extra valid matplotlib backends that +# map to the same GUI support +backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk' +backend2gui['WX'] = 'wx' +backend2gui['CocoaAgg'] = 'osx' + + +def find_gui_and_backend(): + """Return the gui and mpl backend.""" + matplotlib = sys.modules['matplotlib'] + # WARNING: this assumes matplotlib 1.1 or newer!! + backend = matplotlib.rcParams['backend'] + # In this case, we need to find what the appropriate gui selection call + # should be for IPython, so we can activate inputhook accordingly + gui = backend2gui.get(backend, None) + return gui, backend + + +def is_interactive_backend(backend): + """ Check if backend is interactive """ + matplotlib = sys.modules['matplotlib'] + from matplotlib.rcsetup import interactive_bk, non_interactive_bk + if backend in interactive_bk: + return True + elif backend in non_interactive_bk: + return False + else: + return matplotlib.is_interactive() + + +def patch_use(interpreter): + """ Patch matplotlib function 'use' """ + matplotlib = sys.modules['matplotlib'] + def patched_use(*args, **kwargs): + print "patched use!" + matplotlib.real_use(*args, **kwargs) + gui, backend = find_gui_and_backend() + interpreter.enableGui(gui) + + setattr(matplotlib, "real_use", getattr(matplotlib, "use")) + setattr(matplotlib, "use", patched_use) + + +def activate_matplotlib(interpreter): + """Set interactive to True for interactive backends.""" + def activate_matplotlib_inner(): + matplotlib = sys.modules['matplotlib'] + gui, backend = find_gui_and_backend() + is_interactive = is_interactive_backend(backend) + if is_interactive: + interpreter.enableGui(gui) + if not matplotlib.is_interactive(): + sys.stdout.write("Backend %s is interactive backend. Turning interactive mode on.\n" % backend) + matplotlib.interactive(True) + else: + if matplotlib.is_interactive(): + sys.stdout.write("Backend %s is non-interactive backend. Turning interactive mode off.\n" % backend) + matplotlib.interactive(False) + patch_use(interpreter) + return activate_matplotlib_inner + + +def init_matplotlib(interpreter): + import_hook_manager.add_module_name("matplotlib", activate_matplotlib(interpreter)) + + +def flag_calls(func): + """Wrap a function to detect and flag when it gets called. + + This is a decorator which takes a function and wraps it in a function with + a 'called' attribute. wrapper.called is initialized to False. + + The wrapper.called attribute is set to False right before each call to the + wrapped function, so if the call fails it remains False. After the call + completes, wrapper.called is set to True and the output is returned. + + Testing for truth in wrapper.called allows you to determine if a call to + func() was attempted and succeeded.""" + + # don't wrap twice + if hasattr(func, 'called'): + return func + + def wrapper(*args,**kw): + wrapper.called = False + out = func(*args,**kw) + wrapper.called = True + return out + + wrapper.called = False + wrapper.__doc__ = func.__doc__ + return wrapper + + +def activate_pylab(): + pylab = sys.modules['pylab'] + pylab.show._needmain = False + # We need to detect at runtime whether show() is called by the user. + # For this, we wrap it into a decorator which adds a 'called' flag. + pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive) + + +def init_pylab(): + import_hook_manager.add_module_name("pylab", activate_pylab) + + +def activate_pyplot(): + pyplot = sys.modules['matplotlib.pyplot'] + pyplot.show._needmain = False + # We need to detect at runtime whether show() is called by the user. + # For this, we wrap it into a decorator which adds a 'called' flag. + pyplot.draw_if_interactive = flag_calls(pyplot.draw_if_interactive) + + +def init_pyplot(): + import_hook_manager.add_module_name("pyplot", activate_pyplot) \ No newline at end of file diff --git a/python/helpers/pydev/pydevconsole.py b/python/helpers/pydev/pydevconsole.py index 9b4e2a89efba..b38847a82925 100644 --- a/python/helpers/pydev/pydevconsole.py +++ b/python/helpers/pydev/pydevconsole.py @@ -171,6 +171,11 @@ def process_exec_queue(interpreter): set_return_control_callback(return_control) + from pydev_ipython.matplotlibtools import init_matplotlib, init_pylab, init_pyplot + init_matplotlib(interpreter) + init_pylab() + init_pyplot() + while 1: # Running the request may have changed the inputhook in use inputhook = get_inputhook() @@ -322,6 +327,10 @@ def get_interpreter(): try: interpreterInterface = getattr(__builtin__, 'interpreter') except AttributeError: + # fake return_controll_callback function just to prevent exception in PyCharm bebug console + from pydev_ipython.inputhook import set_return_control_callback + set_return_control_callback(lambda x: True) + interpreterInterface = InterpreterInterface(None, None, threading.currentThread()) setattr(__builtin__, 'interpreter', interpreterInterface) From 557ca2cec0e89fb953e0acd2e6e30b24474c427e Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Fri, 24 Oct 2014 00:46:12 +0200 Subject: [PATCH 003/132] Attach to Process on Mac --- .../add_code_to_python_process.py | 99 +++++++++++++++++- .../pydevd_attach_to_process/attach_x86.dylib | Bin 0 -> 18000 bytes .../attach_x86_64.dylib | Bin 0 -> 18092 bytes .../pydevd_attach_to_process/linux/Makefile | 64 +++++++++++ .../linux/attach_linux.c | 45 ++++---- .../linux/lldb_threads_settrace.py | 22 ++++ .../pydevd_attach_to_process/linux/python.h | 3 +- 7 files changed, 209 insertions(+), 24 deletions(-) create mode 100755 python/helpers/pydev/pydevd_attach_to_process/attach_x86.dylib create mode 100755 python/helpers/pydev/pydevd_attach_to_process/attach_x86_64.dylib create mode 100644 python/helpers/pydev/pydevd_attach_to_process/linux/Makefile create mode 100644 python/helpers/pydev/pydevd_attach_to_process/linux/lldb_threads_settrace.py diff --git a/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py b/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py index 6a64f4e7ed41..9ca7b3903881 100644 --- a/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py +++ b/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py @@ -263,6 +263,10 @@ def resolve_label(process, label): def is_python_64bit(): return (struct.calcsize('P') == 8) +def is_mac(): + import platform + return platform.system() == 'Darwin' + def run_python_code_windows(pid, python_code, connect_debugger_tracing=False, show_debug_info=0): assert '\'' not in python_code, 'Having a single quote messes with our command.' from winappdbg import compat @@ -395,11 +399,11 @@ def run_python_code_windows(pid, python_code, connect_debugger_tracing=False, sh def run_python_code_linux(pid, python_code, connect_debugger_tracing=False, show_debug_info=0): assert '\'' not in python_code, 'Having a single quote messes with our command.' filedir = os.path.dirname(__file__) - + # Valid arguments for arch are i386, i386:x86-64, i386:x64-32, i8086, # i386:intel, i386:x86-64:intel, i386:x64-32:intel, i386:nacl, # i386:x86-64:nacl, i386:x64-32:nacl, auto. - + if is_python_64bit(): suffix = 'amd64' arch = 'i386:x86-64' @@ -408,7 +412,7 @@ def run_python_code_linux(pid, python_code, connect_debugger_tracing=False, show arch = 'i386' print('Attaching with arch: %s'% (arch,)) - + target_dll = os.path.join(filedir, 'attach_linux_%s.so' % suffix) target_dll = os.path.normpath(target_dll) if not os.path.exists(target_dll): @@ -443,7 +447,7 @@ def run_python_code_linux(pid, python_code, connect_debugger_tracing=False, show "--eval-command='call DoAttach(%s, \"%s\", %s)'" % ( is_debug, python_code, show_debug_info) ]) - + if connect_debugger_tracing: cmd.extend([ @@ -472,8 +476,95 @@ def run_python_code_linux(pid, python_code, connect_debugger_tracing=False, show return out, err +def run_python_code_mac(pid, python_code, connect_debugger_tracing=False, show_debug_info=0): + assert '\'' not in python_code, 'Having a single quote messes with our command.' + filedir = os.path.dirname(__file__) + + # Valid arguments for arch are i386, i386:x86-64, i386:x64-32, i8086, + # i386:intel, i386:x86-64:intel, i386:x64-32:intel, i386:nacl, + # i386:x86-64:nacl, i386:x64-32:nacl, auto. + + if is_python_64bit(): + suffix = 'x86_64.dylib' + arch = 'i386:x86-64' + else: + suffix = 'x86.dylib' + arch = 'i386' + + print('Attaching with arch: %s'% (arch,)) + + target_dll = os.path.join(filedir, 'attach_%s' % suffix) + target_dll = os.path.normpath(target_dll) + if not os.path.exists(target_dll): + raise RuntimeError('Could not find dll file to inject: %s' % target_dll) + + lldb_threads_settrace_file = os.path.join(filedir, 'linux', 'lldb_threads_settrace.py') + lldb_threads_settrace_file = os.path.normpath(lldb_threads_settrace_file) + if not os.path.exists(lldb_threads_settrace_file): + raise RuntimeError('Could not find file to settrace: %s' % lldb_threads_settrace_file) + + # Note: we currently don't support debug builds + is_debug = 0 + # Note that the space in the beginning of each line in the multi-line is important! + cmd = [ + 'lldb', + '--no-lldbinit', # Do not automatically parse any '.lldbinit' files. + # '--attach-pid', + # str(pid), + # '--arch', + # arch, + '--script-language', + 'Python' + # '--batch-silent', + ] + + + cmd.extend([ + "-o 'process attach --pid %d'"%pid, + "-o 'expr (void*)dlopen(\"%s\", 2);'" % target_dll, + "-o 'expr (int)hello();'", + "-o 'expr (int)DoAttach(%s, \"%s\", %s);'" % ( + is_debug, python_code, show_debug_info), + ]) + + + if connect_debugger_tracing: + cmd.extend([ + # "-o 'expr (int) SetSysTraceFunc(0, 0);'", + "-o 'command script import %s'" % (lldb_threads_settrace_file,), + ]) + + cmd.extend([ + "-o 'process continue'", + "-o 'script import os; os._exit(1)'", + ]) + + #print ' '.join(cmd) + + env = os.environ.copy() + # Remove the PYTHONPATH (if gdb has a builtin Python it could fail if we + # have the PYTHONPATH for a different python version or some forced encoding). + env.pop('PYTHONIOENCODING', None) + env.pop('PYTHONPATH', None) + print('Running: %s' % (' '.join(cmd))) + p = subprocess.Popen( + ' '.join(cmd), + shell=False, + env=env, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + print('Running lldb in target process.') + out, err = p.communicate() + print('stdout: %s' % (out,)) + print('stderr: %s' % (err,)) + return out, err + + if sys.platform == 'win32': run_python_code = run_python_code_windows +elif is_mac(): + run_python_code = run_python_code_mac else: run_python_code = run_python_code_linux diff --git a/python/helpers/pydev/pydevd_attach_to_process/attach_x86.dylib b/python/helpers/pydev/pydevd_attach_to_process/attach_x86.dylib new file mode 100755 index 0000000000000000000000000000000000000000..ffa9f1d9db2f6ecfe18ebb8f682a1730a008e4e9 GIT binary patch literal 18000 zcmeHPVQ^DdcD^zqQNSCCENMwggOW9kNmAPoLQESb0{j*`SgZmF2u*mA?FaU*EGd%A z+F9JSVr$mVFKSJPWZ0zbu+wJRPGN^;yA0bh)B#UnQcu^}(ygb%bR9}SYP=a29Pln| z-0z(Cu8?Fo-OThyXR0^8_nv$1Ip>~p?z#6pA3f=xe*V)>?-oMLL%9pZi85&yBH6P@ z*Z?ms6GBzDE4#L%lY7-z9kj$hAB9@FR5h-3#!cAl=kvQ43-KKkYBANF%Px9kM^$58 z?M>mJ8jE){0a>WSnMxt*fv1-Al$T?^DT8c*3^1#$S}>wTxu35``3fPn0#7Z>ymMJH z2%)O`nwwRvvssJ8)p($(P>+|u>xKf<=E=At4KkWz@n~CUpM@)w(etPfZ^IGP=3cq- zRJ9}Y^|nxp+7{Xy22r7m<<&wQ0-oBrE>+c9)xFU`yJk`p$`}G~ErzJ2cqn#}ukEN* zwQl|P^*Iz24=xm|l`$pdsA>pnX)b9b9xcjWPU66yYd5VUX5kozMt){lf?k(u-u%6fU%@(aNjN z0|Io0(YheK3^2{pw?T*p(7Nkj7my19`%vg|QI$gEslck|Y{<#7;k}2+4z=cAa`-HRBP>q-L;VTeo7Vl8(`Ua(GfbooF8wu9b_)7Q^}mau z9QFI^k#(8zPs8*?_asf_?5hFFfGa-GZD|AK>nI!MeDwhn?L6(Vt*atT@@|O{>sB!$ zgc_V6DbwHW%{-+m8FTh6&%-^bD;JzeN_8;ZIpy|zI3x4d zKmfjr;I~cqZi2r}guSSEHnHvrfX-yQM0m=2hek;QyRMAt-Vx`wygW2vct?#x{l}oU z?aa(2NT!ToW-|r>+X#Nfgv$sfsld-8_z@Gf6HM77Ru0n=#W) zlxCDL$~RD)%RJ_KmK#d>fY;IUfvw+r3#*jqo+5T<9~MpAP;S|reU#_H;?1X=7s4=u z^c?lgi0mCMN02y|)micJzb$XcfKqOF9lG~+g{@z?HK5!w2y~tprJ!v@&^|dcGn1=0 zG$Hj2N8(+K%;=89&w#b!q7X#|z!Tg0U{xPdj(?PDIQdHQ;p_{_=r#$7v9Wzo%W;^P#Q3{kra-;MMtP z)H&kKPk@>NT6ib;<`G6G&?wz5WJ*rbW>3v)6rq_YL)_?Y=Gz-%Yx z`@w7|Fn2wK8~$+_Jzrw7(M0#?oDx@9532Yexl;!x+2<36G9hmWf6NlHr@s}ZH?v`i$!rv! zSl3P_J#|i*#)^u}UvW@O=7nh<--8yPhxtx|kHa(uzVxF%qcDX=9*+HVjz$Zayl~^> zN#12izJlbsu3+O#bC}XC3L6LeFws3uE|I$~kNJSb{Fls(-80Q$dJ*)70&{7b82$+v zrU#hpVxpS}ic5UclDLyev1_I|Ob4XIlNisD_$ZSV?!!DC|Iv~-pGmQmra4S&A#uik z5&Lk!dvm~l1L1)fNuUU%|$)d3te zn=qs+6N&B#5-*qGdN!&KrTTwFOo*z7nY17KhCX@9eCHlo28@4GY*M~1p%57tg*-}XN@oG zAEf+a`XW6UBuzS5M5`3R^4~P&KWjHqG@vgqUMJd_AL+@KEFpuIj`YA}>i94qmT^q# zxQQotN%CbtK#GwMrDCsP(GfR>_fYEKPl)e|zQeBHmA;EvUy!Uul0ckv*^{`)yf@^$ zKg0}ra+hQ-Ht%B0JD^-Myyx{xsg5yyRey3P&5-h;PVZp>jZ#3NXJ~*tL$u_XdPzv@ zN*%r4G4MLcbDp@?d&Q2St|vR0n}jwo&k_!z)2Xe z8S`chI0*w*vm&b{zmX(xZUY*m0gp3ZjpWNU;3;TZV8Ff70A8(=v|80*)l-$I)5l@4 zo~)3vc(wMJ6Hy$~0Ie3$(rURSAsI^@HkRb&7<(MX?t$E_vBzQTCZ1@i67)c_-*_RZ# zG}K}LlBgX29)W*91!LB~N8sP9Knm09$I{hA&M^9dq0tz*x0n(6YNy9NoNGnAhUImhu zvkHf?3Z0OfU4_F~g#b@!fEF} zth>?=&{Q9?#Z$PuXAM8avX0W-X^2*21Txb9hGo)|=cPD0F-g0#j2^y&Hd55l>+Qzt zM6A2cdFTd%fFv;#kVBH#c|y5HH)PzN?FOTf;&AbH0v2RJc5 zsoPpm@^A*5MP!iP!JR(krOUi~n2_!}Rn>|GXG@>HrI6lIZd8^^@>adH_^| z*^Bd6OAN(@=S;)z(EYdh(UP(r$d(LvZyEk6V8Bk#vdD)a)#gZFh7A6XeGvRULvfgS z4+BVhk^F!oOF`;p^YiW1yckLxP^OK{IXUV({c_ zI0k%nJZj_d(s|-NPJWDijHf$FRG9gM-U;MiirWX{bd200o9peIwi%pRPVZ{XEMLs^ z60VnW?dH0I>q@R4=emaL)m+zd{WNMJTJ7AScZ>#G36c3vgncW8PG+2-3W9!2&`N?v z2%?iJbA})}nA?Uk+px0Y(zS<+^9YlB{7lMW5i-6lG|4N7i_A>3;e?coY;BZT$ zeFLqiM)3bGNP1}#`~hx#33UDgt+*c>vkq+=ZO||(I+l0gNyYXCI&aAldSIs!=J~4C zVQD>9$Krxpx` z-Cqw!gDnp&5WcQW4UOC4fw-nBp;$*$6I=X^jSIxiaP(_hi@S1fxFgi!o<+3+tjk-# ztv19OLT&N3K(Ortv60x=C!W*ID00ms&kkh-m{JrdNmnXj7qx(ZQw z9NV-wUa#984K!jSa%@i?5suelaS7jQPTN5av#YBt_*OGi-K65bFDH-C*BJm+AZlt@>Lw!cM&1az%ld6?72cps9jqRJe497LCDOd{iyPVMT{{1qvNql~x}OT{e2@ zm|keFN5_LgFQ(JQ{ogQO5T^saTzmoJ1PR*_2=vSowo!E5c45cAU-R7eh_b;i0*7Si zBw80_)+`pb2-@YM?78`PRTiyzdgA?j5`@e4%2r`J;IO&M=iB=+Nb1sMd&SqtBX_?A zC4@_k^I(x`@)049qYOfQ7m5#M$qKxGjPf|j8Wa!8vnbn9N>|APB@dK5Q1U>@10@fX zJW%pL$pa-1lsr)KK*<9o5B%Tvz@mp-FWl!Iey(R>S!7|vXV-yg8!d;Y<&s8)B2)pcPc=kOJ3(Nk8C=oCr3ka`43jd`oqBEuuo zW4 zS&e{^j1m#hpyBKmrI_fm2Es4Q`8qbbVxC1O`6ZnLbo>?U92z*AGiH)zmMog!Ud%R$ zWEOpJ@Sv@Sb5Qh2DZ!MJdeMR@C$-;#YXJYg1yi2t&n>@QBe83{BHcp!S2SDYdGZNt>KWB6WvevEh|^cJyIVI;;h)XQpw#n#Yk$m zhkacnNGUF&ZY2+>&A~uuA9i^#h+h-24uYa{)~%XD(#BPJ%52)WG3R$Yf?BOmv&V#5 zcuGL?&v8D0`iakbC=kytaV&sr&Fm9_u(Qtu`lS<`fQ3gfi1SZV9OZ@QXz|ls9^Yu` Q;Fd?WJgjHkDG*=(4WJJSCIA2c literal 0 HcmV?d00001 diff --git a/python/helpers/pydev/pydevd_attach_to_process/attach_x86_64.dylib b/python/helpers/pydev/pydevd_attach_to_process/attach_x86_64.dylib new file mode 100755 index 0000000000000000000000000000000000000000..60e07417295ac9a771cf952c3395a3af136c8c5c GIT binary patch literal 18092 zcmeHPYj7LabzV@EMaham*=nN1b_99Mn35X4B+85vr;x<8mNhBEl4#3n)fEV?NH!n< z0iZ&<X6J7%23 zrXDf+o%_IJL8|qSX7U3&+`adld(L;yJ@?$Zz`-tmdgZ@ASfwbA6^f$VfYXU{Vx^+Q zW9v{;l#k;atWXqPKcF5wz*xnXhGJ3?G%yvwC{)s+>rrDc%Ilmi#tZ!(ZyUOWmqb_Q z#fgX&lDZy=4s=CwEW3Sg)$%4yND%GFNh?Z~z@stK!SVE7!yhujj4rls`(`GlJj4ry zXt*VRl-Sqf^XbN*&j>~JsJF{*-(v#LC5$4v2rrM!YP#-=M8kc79>KTco!r73{zf=W z(h|mwt?L7UFZKnx^}fK-AcX9A57u){zW|W5#Iu*WZuII$!`^;_x7hKf1zw9#B${Gw zxr5@a1-{Ys)}04-7D&l>s}?*PP4Py!5?j{;emyeO-xc)hp=fwnJPAkfD|M*{ijTEa z5r?k#1Pj8r1g~1yQzhhyw&UF-!BFbD-+Mj#HVC{ULWk%=JQ}Z4v{6BRqnOwA_O`wE ztF3Kv&AP#)qna0ro0liW0wA2i_3;tVB(lNAudAyMM(X>$zF=gqez0YSzGHj6HyZW& zdUa0Kbr1Rbx|BNGH4rJQ?^iW_tc*h=-;|T8}X>0KU&kgNttcfd-~YlU7GR#diGB6m}^$A0q`1ymJ_2< z(m^pm_LDBz>TrC&k~~&F5DC{~z;x~(ibRe6x?RErkm7m`D5V~DQ&7cvzO7s98imrQ z&`SNzBIZelwh5vwu?Dsl&`+RVKFS^_d!X!rvIoi@D0`snfwBk69w>XD?18ce${r|t z;CIghotpWkHu|&wV^YR^kcpQGf0slII;BX+9!qY%DA&e#EDak-Dbx{vvbZlrlKK( zQ%R~9N39*EdciqXQ^adF)mdkp@+VC0CH2}$_%?GI4AgI+`bl12MfC|19LI%s2Me}= zaK^(qmR2!(X4ae;%~WE1GiJwm=U;fJF}0Fg*)gN})+aQ_+3XwWfUbSpG} z?!@Aqj)eNYW)4`G28&dkW4Gh_p8CGSIfi+sQCiwc$}C|piy2C-F%}Cob@A{y=f)U# z|1WqH|Lz2$WSHAI4pWl@s5?(BTA#&0U{ZnMG}X+uWR*5@2F++k?J}9?jFbBqKnH^I zSQQ7kkAuw9Txv;o1FfFyED!OcbksRFj*&ha-*xTz-UoJj*yrbwxoE8W4Az6m8VDKiEotMVF#nQA5p ztR-f}uaT#Q6*CB-nPmV!$pK%1q^UkZ5lw*Gm=!b7ordo8GP*Z#-LEj+FGCmkR3-C1 zF0f-GB9j>r;zpbX5Ut#$M)ewG;fi(!lm^gB0{Q_5x+sC};y{xCnp_6x90yv#fF1)7 z<;F7x2YNvQ{S2vb4DAGfPAmg-k^?;hNmETopxYpw?L2L&Pio1I6Byk>_7&77lfzG% z>R9#_THPb(W01lEx5Z}&>jlxo!-qoW%6sb7d^8;59k#I!pU%e|+up5Dk;SRz)jX>B z-o1g3qTp6S3#kb7E%*U`{S{K*raFmHun?nY!4_W>Vg;7G%9WmHN++SjLhJzwvF}`F zAx09WdI{sVtiOU7d^rbS&Y}C<>=pq2m;(kF;0XY-5c>ea+0HrW&O&!~8Qt%4-6p2{ zBy?GborN^q@ho|OjQ9vQq9o1>j2PrV8T=Z-R~rklAr3TzMh0{q%}WJ+0niZ+G{Jyq z1+oxpV56Ba)n~^$u8wzJ!8FI-z;1ZidFow@eu*&E)9p!hIywC8&g^VbMGRfz_ks{Y zrF1_VdAk~J=OJSYhJpyPZX$bA&3BXi@}5pVxPT~#3+kW81wJ@H{@#!AF5r!&0j&H-fp`hl2bcuJSejvZ3b1bGSPqHR%drX~r3C9;j@8Pr z+Bp{8*D^2SiaWua^Hj$b*#Aq&nJEnd@FgopUw3G!VQg4aZZOT4HS?_XuVg@yF|0FG zH{&g6%m5I4R@cNL=m3j*h$a#}OrVFx>BO1DjCBgCW_-KU%wRl<`3k%;ZFW4H`8X_t z_aKAfG+SSba3#BKF@xf@(6n~){#_CUlXeJQz&v8X8j`~O&5Uozi6mKFnn)i$xQTag z6F;3d@fK#{da0R#02xKDlScWNQNtEGrp?6qck-wiuaY`2f$A7m!Tws(XGOlxZv()L zS4#b*`g{jVV_dyLJ0wj`BEEw4kXpnI*{bITETGPGVVFkCI5|Zum_t&`BbF2yX8_Jq zGkmruFwM!YP^)EObOL2~!n#0XHRJPA4`5W6p6q~IiYEI3^eZO&AE9c-FG@|@WZ#GZ z!LJCKElU1hp?#wQX>8u)Nx}lBxS}Kg7olI zFWQ-tNx*s&qZdwQE!N9mK)Y9JW2{tP*3UQO$9E2@X1rT!+Wefxoe6$MsOS9L0~X)% zSl{UOAlY<3H^C!;Fb)5-nk1))1%pV6MUj>hNye!ztt^>^uR~wV!tKn;R;ejx0b5kg zuAgE<&h0?Vv_yP2!JDZT6xLG|A7;EkV!*&H+(2T%K$2nx)=H6a29TSCgK`o`z&Zjv zW`~xVq86)-ci@uRfTX${-XpM;Z$+O&4I9WJc11C~&qLLW-zGIPpMXT}z9aFk!tt3) zY{b{-#w54<9}`@XM|Em=0%NQu`{)}C>Qxd{!u&PoE0T|BJjy^s39@ao@6Na z00WH0--wOdc}l%9I`6=w63cwidhHjYrRa8bFh8yN_coXa!rNY|H6cG1@;vg%g&lBWxZf$rLDg&WqsSuny?-#Wew$6}zwU zMPHd0EE;$I3v%)IV|-C3c`dn0eB3Pg{#;F8=1Io-KF6u13_@$}`*pSTJn@lTuqIJi zUSAubMGMK{1?L#DTC_1NXvvmwtqLDqou__bJ@XENYVt$F85pRZ-egxBm<7 zB|GG+6>ibXqo4zMxP=wPgAX%YLv-=CExh^ zmtx9_$1%N%(t(*}2URFApCkrl&whmRag@sYxcmo7+9;LRa5(~zdWv;7%!+~d8cO8_ z7`+GOZCFD}4K5T(zg&%{kUSv1DqAYSp%$jIQ4kERSrAO;eh~QMozf?MB3R2YK``6K z3R}J=2sVVL3R`{%Vgmr!LAyKtINAl&>O}*dm!d;6{QjWpi@~tJd(#@lGqk6zeSg#& zHFPx)83-H7-p=;+HOj-m@E443SMAZ@K%m=IBDEQ+HQmtG+ahg&zG$D<-}k6d%5VjO zQ5VCgqrQrzU11|S5DuW5qh5c+U=nSCs1XjK!3cA!G{Z}9SD1U#(e_;pDPme zhNDI|vu#%p4_4k64)(VP@ocJRsE95?@eDoC^{0j}s%zfJ&S(@)Vvn;f&9-T_^@oDt zsLqRyVE2IE*c;sC5Bk194qmpg2qiSsZ5;2`qZkG~Mq5m}`WdJzFyQxNTzW9v*V7m9 z;?Yq9refgB$oG09=)_ejzsUv5#DMo0(WM4l#J-NHb*1RcP6RR^geYud0Q??*u*>Uj zHM$0Rdhk>;m#!;mkfY8SyxZ&d(@aPEf&q+SXSgSlAI%btOBi3;OYP?Tsu6Bxp4Gei zA|Y?o*SoBJ&=h{glcwRmu7RlGDpt+8VySNHie-zffM#SUQYWXmb~zu_ZnnW}ri}<2 zO&vU=!=(=y;RxKtwkpc>(U#>BCEW|yrVche5KIrZw}M9>+vJ1lM9(5ePY;6A=Drq> z&%1=ykt(Gkgda~9ZiYU6G~maBC@3dGhvU(Gies?aQN4CmRT_Ph33NCf^|Z5=Ro|!q zSuNXH<8>~sTHZK+7cZv;?G|NBl&vtAj=iEhD9SET`bBwMlrd3qt@5?(fwBk69w>XD z?18ce${r|tpzMLN2g)8Od!X!rvIl+}9$2?&!yi*W>)d#6x0}6GuXo|SaHNYKJf@^? zcI$ZKd2mq2Tk(+~5@LPPA^muR601sc>yEkCL8OzvOTN#D4B!Ruv~o-Xx7!~K83Cd^ zjKW*kL>vSWLh3Jil&B-1@M6243-(ffhxSK5gCuG{@^4Y&I0=QA8NNZU-en*yr~6pC zh+E*$ktnIed;9*NQm-FUwzme6Y{UD=O02?`xK!eJ_;O(j@+(cBLB>X=yF5V{V}$nx zS)!~B@56U_T4bZrw@nG`Q2rT@aLytfUD0q|#ilM#W0Pm-z);BGxj*G4N2Bg}q*Z;W zRaXZM-@|>;Udqn0j4Cpq$SihsDdVtf0(qf|R>QZ?IGXRhOL@=H7O?ZK!kC2yWQk%; zxXjXJ;%=&a7Ac}F6OQQ>9#7ignXR0xOs{vlTrRhwT>05r`eEP+oRnRngR)YTrE14X z*{Kj@P$-nyAwKQmEUTp@ctPpZiU&>WMj=joUAoIUsQ3p4nw`%(31PA?2`AJ7i zk$ES2#D-{>$TuApw9G>t7xWR){+EJ|3HomZJuT>;fWE1cr`b?dF5+~ee-9pPrsL;0 ziJrKXkqSMJNc8N-I8Dzj6YUbeT0A0XO5M>B6Ld(le^t=z#eB4%ldu^m-djzmXQogCv?wJ_QN|O*Kx+Gm^tZ zys01~DSy0iQ&#fB>bme>3J$e5?qEwQ+8Ydr9O`l6?`_;J*Ps^kV?Wy6s1~lvr9@f| z1U*9pq%IB7+Q=GopWhqk!7k$W= 3 && version[1] == '.') { From 54e9434f67056fcfc45e6f820f8e82ac3880877d Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 24 Oct 2014 12:08:08 +0200 Subject: [PATCH 004/132] IDEA-76479 (tests) --- .../intellij/openapi/util/io/IoTestUtil.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java b/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java index 5dbe2dd1ae76..1669c5eca11a 100644 --- a/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java +++ b/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java @@ -18,6 +18,8 @@ package com.intellij.openapi.util.io; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Function; +import com.intellij.util.ObjectUtils; +import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -236,6 +238,34 @@ public class IoTestUtil { return jarFile; } + @NotNull + public static File createTestJar(@NotNull File jarFile, @NotNull final File root) throws IOException { + final ZipOutputStream stream = new ZipOutputStream(new FileOutputStream(jarFile)); + try { + FileUtil.visitFiles(root, new Processor() { + @Override + public boolean process(File file) { + if (file.isFile()) { + String path = FileUtil.toSystemIndependentName(ObjectUtils.assertNotNull(FileUtil.getRelativePath(root, file))); + try { + stream.putNextEntry(new ZipEntry(path)); + stream.write(FileUtil.loadFileBytes(file)); + stream.closeEntry(); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + return true; + } + }); + } + finally { + stream.close(); + } + return jarFile; + } + @NotNull public static File createTestDir(@NotNull String name) { return createTestDir(new File(FileUtil.getTempDirectory()), name); From f4843241cca061000dbeab4ac6c50ae01e0d770f Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Fri, 24 Oct 2014 12:31:43 +0200 Subject: [PATCH 005/132] Run lldb in shell and inherit parent std handles. --- .../pydevd_attach_to_process/add_code_to_python_process.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py b/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py index 9ca7b3903881..05a3d7957fcb 100644 --- a/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py +++ b/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py @@ -549,10 +549,10 @@ def run_python_code_mac(pid, python_code, connect_debugger_tracing=False, show_d print('Running: %s' % (' '.join(cmd))) p = subprocess.Popen( ' '.join(cmd), - shell=False, + shell=True, env=env, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + stdout=None, + stderr=None, ) print('Running lldb in target process.') out, err = p.communicate() From af9927e8acc0cb38010843ce1a012690d4bda552 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Fri, 24 Oct 2014 14:39:40 +0200 Subject: [PATCH 006/132] New lines. --- .../pydev/pydevd_attach_to_process/linux/attach_linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/helpers/pydev/pydevd_attach_to_process/linux/attach_linux.c b/python/helpers/pydev/pydevd_attach_to_process/linux/attach_linux.c index 93302ee75460..46b170f90404 100644 --- a/python/helpers/pydev/pydevd_attach_to_process/linux/attach_linux.c +++ b/python/helpers/pydev/pydevd_attach_to_process/linux/attach_linux.c @@ -239,7 +239,7 @@ int _PYDEVD_ExecWithGILSetSysStrace(bool showDebugInfo, bool isDebug){ if(!pyHasAttrFunc(pydevdTracingMod.ToPython(), "_original_settrace")){ if(showDebugInfo){ - printf("pydevd_tracing module has no _original_settrace! "); + printf("pydevd_tracing module has no _original_settrace!\n"); } return 8; } @@ -277,7 +277,7 @@ int _PYDEVD_ExecWithGILSetSysStrace(bool showDebugInfo, bool isDebug){ DecRef(call(settrace.ToPython(), traceFunc.ToPython(), NULL), isDebug); if(showDebugInfo){ - printf("sys.settrace(pydevd.GetGlobalDebugger().trace_dispatch) worked."); + printf("sys.settrace(pydevd.GetGlobalDebugger().trace_dispatch) worked.\n"); } return 0; From bd7af104e054f8458234d00c0e4c5206acc5f435 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 24 Oct 2014 16:47:34 +0200 Subject: [PATCH 007/132] IDEA-76479 (group inter-type declarations and targets for compilation) --- .../jps/builders/java/dependencyView/Mappings.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java index add3dfca0fbb..3274a7ef896c 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java @@ -2347,6 +2347,13 @@ public class Mappings { } } + @Nullable + public Collection getClassSources(int className) { + synchronized (myLock) { + return myClassToSourceFile.get(className); + } + } + public void close() { synchronized (myLock) { myClassToSubclasses.close(); From 82b625a88a3eed0f69ab0513504b3d44e5fe00f6 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 24 Oct 2014 14:28:43 +0200 Subject: [PATCH 008/132] use ArrayList instead of LinkedList --- .../org/intellij/lang/regexp/_RegExLexer.java | 17 +++++++++-------- .../org/intellij/lang/regexp/regexp-lexer.flex | 14 ++++++++------ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java b/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java index b751ab59ba48..c8d3b4c482cf 100644 --- a/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java +++ b/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java @@ -1,20 +1,21 @@ -/* The following code was generated by JFlex 1.4.3 on 10/24/14 12:41 PM */ +/* The following code was generated by JFlex 1.4.3 on 10/24/14 2:25 PM */ /* It's an automatically generated code. Do not modify it. */ package org.intellij.lang.regexp; import com.intellij.lexer.FlexLexer; -import com.intellij.psi.tree.IElementType; -import java.util.LinkedList; -import java.util.EnumSet; import com.intellij.psi.StringEscapesTokenTypes; +import com.intellij.psi.tree.IElementType; + +import java.util.ArrayList; +import java.util.EnumSet; @SuppressWarnings("ALL") /** * This class is a scanner generated by * JFlex 1.4.3 - * on 10/24/14 12:41 PM from the specification file + * on 10/24/14 2:25 PM from the specification file * /Users/bas/Projects/IntelliJ IDEA Ultimate/tools/lexer/../../community/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex */ class _RegExLexer implements FlexLexer { @@ -404,7 +405,7 @@ class _RegExLexer implements FlexLexer { /* user code: */ // This adds support for nested states. I'm no JFlex pro, so maybe this is overkill, but it works quite well. - private final LinkedList states = new LinkedList(); + private final ArrayList states = new ArrayList(); // This was an idea to use the regex implementation for XML schema regexes (which use a slightly different syntax) // as well, but is currently unfinished as it requires to tweak more places than just the lexer. @@ -433,11 +434,11 @@ class _RegExLexer implements FlexLexer { } private void yypushstate(int state) { - states.addFirst(yystate()); + states.add(yystate()); yybegin(state); } private void yypopstate() { - final int state = states.removeFirst(); + final int state = states.remove(states.size() - 1); yybegin(state); } diff --git a/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex b/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex index a40cd5a6291d..e6547a56a939 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex +++ b/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex @@ -2,10 +2,11 @@ package org.intellij.lang.regexp; import com.intellij.lexer.FlexLexer; -import com.intellij.psi.tree.IElementType; -import java.util.LinkedList; -import java.util.EnumSet; import com.intellij.psi.StringEscapesTokenTypes; +import com.intellij.psi.tree.IElementType; + +import java.util.ArrayList; +import java.util.EnumSet; @SuppressWarnings("ALL") %% @@ -20,7 +21,7 @@ import com.intellij.psi.StringEscapesTokenTypes; %{ // This adds support for nested states. I'm no JFlex pro, so maybe this is overkill, but it works quite well. - private final LinkedList states = new LinkedList(); + private final ArrayList states = new ArrayList(); // This was an idea to use the regex implementation for XML schema regexes (which use a slightly different syntax) // as well, but is currently unfinished as it requires to tweak more places than just the lexer. @@ -49,11 +50,12 @@ import com.intellij.psi.StringEscapesTokenTypes; } private void yypushstate(int state) { - states.addFirst(yystate()); + states.add(yystate()); yybegin(state); } + private void yypopstate() { - final int state = states.removeFirst(); + final int state = states.remove(states.size() - 1); yybegin(state); } From fb488021e879019c11ab973776df081315f823d3 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 24 Oct 2014 16:42:39 +0200 Subject: [PATCH 009/132] IDEA-27062 (Incorrect "Unresolved Backreference" error in regex String literal) --- .../org/intellij/lang/regexp/_RegExLexer.java | 160 ++++++++++-------- .../intellij/lang/regexp/regexp-lexer.flex | 19 ++- RegExpSupport/testData/RETest.xml | 8 + 3 files changed, 106 insertions(+), 81 deletions(-) diff --git a/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java b/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java index c8d3b4c482cf..531087761da2 100644 --- a/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java +++ b/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.3 on 10/24/14 2:25 PM */ +/* The following code was generated by JFlex 1.4.3 on 10/24/14 4:28 PM */ /* It's an automatically generated code. Do not modify it. */ package org.intellij.lang.regexp; @@ -15,7 +15,7 @@ import java.util.EnumSet; /** * This class is a scanner generated by * JFlex 1.4.3 - * on 10/24/14 2:25 PM from the specification file + * on 10/24/14 4:28 PM from the specification file * /Users/bas/Projects/IntelliJ IDEA Ultimate/tools/lexer/../../community/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex */ class _RegExLexer implements FlexLexer { @@ -411,6 +411,7 @@ class _RegExLexer implements FlexLexer { // as well, but is currently unfinished as it requires to tweak more places than just the lexer. private boolean xmlSchemaMode; + private int capturingGroupCount = 0; private boolean allowDanglingMetacharacters; private boolean allowNestedCharacterClasses; @@ -437,6 +438,7 @@ class _RegExLexer implements FlexLexer { states.add(yystate()); yybegin(state); } + private void yypopstate() { final int state = states.remove(states.size() - 1); yybegin(state); @@ -748,94 +750,85 @@ class _RegExLexer implements FlexLexer { { yybegin(YYINITIAL); return RegExpTT.GROUP_END; } case 88: break; - case 5: - { return RegExpTT.GROUP_BEGIN; - } - case 89: break; case 37: { yybegin(YYINITIAL); return RegExpTT.COLON; } - case 90: break; + case 89: break; case 6: { return RegExpTT.GROUP_END; } - case 91: break; + case 90: break; case 25: { assert false : yytext(); } - case 92: break; + case 91: break; case 18: { return commentMode ? com.intellij.psi.TokenType.WHITE_SPACE : RegExpTT.CHARACTER; } - case 93: break; + case 92: break; case 46: { return commentMode ? RegExpTT.CHARACTER : RegExpTT.REDUNDANT_ESCAPE; } - case 94: break; + case 93: break; case 23: { return RegExpTT.NAME; } - case 95: break; - case 74: - { if (allowOctalNoLeadingZero) return RegExpTT.OCT_CHAR; - return yystate() != CLASS2 ? RegExpTT.BACKREF : RegExpTT.ESC_CHARACTER; - } - case 96: break; + case 94: break; case 29: { yypopstate(); return RegExpTT.CLASS_END; } - case 97: break; + case 95: break; case 34: { yybegin(YYINITIAL); return RegExpTT.BAD_CHARACTER; } - case 98: break; + case 96: break; case 52: { yypushstate(QUOTED); return RegExpTT.QUOTE_BEGIN; } - case 99: break; + case 97: break; case 21: { return RegExpTT.NUMBER; } - case 100: break; + case 98: break; case 4: { return RegExpTT.DOT; } - case 101: break; + case 99: break; case 72: { return RegExpTT.NEG_LOOKBEHIND; } - case 102: break; + case 100: break; case 33: { yypopstate(); if (allowCategoryShorthand) return RegExpTT.CATEGORY_SHORT_HAND; else yypushback(1); } - case 103: break; + case 101: break; case 44: { return (allowOctalNoLeadingZero ? RegExpTT.OCT_CHAR : RegExpTT.BAD_OCT_VALUE); } - case 104: break; + case 102: break; case 41: // lookahead expression with fixed base length zzMarkedPos = zzStartRead + 1; { yypushstate(CLASS1); return RegExpTT.CLASS_BEGIN; } - case 105: break; + case 103: break; case 63: { return RegExpTT.NEG_LOOKAHEAD; } - case 106: break; + case 104: break; case 10: { return commentMode ? com.intellij.psi.TokenType.WHITE_SPACE : RegExpTT.CTRL_CHARACTER; } - case 107: break; + case 105: break; case 61: { return RegExpTT.NON_CAPT_GROUP; } - case 108: break; + case 106: break; case 65: { yybegin(QUOTED_NAMED_GROUP); return RegExpTT.RUBY_QUOTED_NAMED_GROUP; } - case 109: break; + case 107: break; case 66: // lookahead expression with fixed base length zzMarkedPos = zzStartRead + 1; @@ -847,7 +840,7 @@ class _RegExLexer implements FlexLexer { } return RegExpTT.CLASS_BEGIN; } - case 110: break; + case 108: break; case 28: { if (allowNestedCharacterClasses) { yypushstate(CLASS2); @@ -855,72 +848,80 @@ class _RegExLexer implements FlexLexer { } return RegExpTT.CHARACTER; } - case 111: break; + case 109: break; case 19: { if (commentMode) { yypushstate(COMMENT); return RegExpTT.COMMENT; } else return RegExpTT.CHARACTER; } - case 112: break; + case 110: break; case 51: { yypushstate(PROP); return RegExpTT.PROPERTY; } - case 113: break; + case 111: break; case 8: { yypushstate(CLASS2); return RegExpTT.CLASS_BEGIN; } - case 114: break; + case 112: break; case 71: { return RegExpTT.POS_LOOKBEHIND; } - case 115: break; - case 43: - { return yystate() != CLASS2 ? RegExpTT.BACKREF : RegExpTT.ESC_CHARACTER; - } - case 116: break; + case 113: break; case 73: { return RegExpTT.HEX_CHAR; } - case 117: break; + case 114: break; case 1: { handleOptions(); return RegExpTT.OPTIONS_ON; } - case 118: break; + case 115: break; + case 43: + { if (yystate() == CLASS2) return RegExpTT.ESC_CHARACTER; + while (yylength() > 2 && Integer.parseInt(yytext().toString().substring(1)) > capturingGroupCount) { + yypushback(1); + } + return RegExpTT.BACKREF; + } + case 116: break; case 59: { return allowNestedCharacterClasses ? RegExpTT.ANDAND : RegExpTT.CHARACTER; } - case 119: break; + case 117: break; case 2: { yypopstate(); return RegExpTT.COMMENT; } - case 120: break; + case 118: break; case 17: { return RegExpTT.MINUS; } - case 121: break; + case 119: break; case 47: { return RegExpTT.ESC_CTRL_CHARACTER; } - case 122: break; + case 120: break; case 32: { yypopstate(); yypushstate(EMBRACED); return RegExpTT.LBRACE; } - case 123: break; + case 121: break; case 13: { return RegExpTT.QUEST; } - case 124: break; + case 122: break; + case 5: + { capturingGroupCount++; return RegExpTT.GROUP_BEGIN; + } + case 123: break; case 15: { return RegExpTT.PLUS; } - case 125: break; + case 124: break; case 67: { return RegExpTT.OCT_CHAR; } - case 126: break; + case 125: break; case 39: { yybegin(YYINITIAL); return RegExpTT.QUOTE; } - case 127: break; + case 126: break; case 20: { if (allowDanglingMetacharacters) { yypopstate(); yypushback(1); @@ -928,15 +929,15 @@ class _RegExLexer implements FlexLexer { return RegExpTT.BAD_CHARACTER; } } - case 128: break; + case 127: break; case 31: { yypopstate(); yypushback(1); } - case 129: break; + case 128: break; case 27: { yybegin(CLASS1); return RegExpTT.CARET; } - case 130: break; + case 129: break; case 57: // lookahead expression with fixed base length zzMarkedPos = zzStartRead + 1; @@ -946,91 +947,100 @@ class _RegExLexer implements FlexLexer { } return RegExpTT.CHARACTER; } - case 131: break; + case 130: break; case 58: { if (!allowNestedCharacterClasses) return RegExpTT.CHARACTER; return RegExpTT.REDUNDANT_ESCAPE; } - case 132: break; + case 131: break; case 38: { yybegin(YYINITIAL); return RegExpTT.GT; } - case 133: break; + case 132: break; case 69: { yybegin(PY_NAMED_GROUP_REF); return RegExpTT.PYTHON_NAMED_GROUP_REF; } - case 134: break; + case 133: break; case 16: { return RegExpTT.UNION; } - case 135: break; + case 134: break; case 3: { return RegExpTT.CHARACTER; } - case 136: break; + case 135: break; case 64: { yybegin(NAMED_GROUP); return RegExpTT.RUBY_NAMED_GROUP; } - case 137: break; + case 136: break; case 40: { yybegin(OPTIONS); return RegExpTT.SET_OPTIONS; } - case 138: break; + case 137: break; case 26: { yybegin(CLASS2); return RegExpTT.CHARACTER; } - case 139: break; + case 138: break; case 68: { if (xmlSchemaMode) { yypushback(1); return RegExpTT.CHAR_CLASS; } else return RegExpTT.CTRL; } - case 140: break; + case 139: break; case 30: { return commentMode ? com.intellij.psi.TokenType.WHITE_SPACE : RegExpTT.ESC_CHARACTER; } - case 141: break; + case 140: break; case 12: { return RegExpTT.DOLLAR; } - case 142: break; + case 141: break; case 50: { if (xmlSchemaMode) return RegExpTT.CHAR_CLASS; else return StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN; } - case 143: break; + case 142: break; case 42: { return RegExpTT.REDUNDANT_ESCAPE; } - case 144: break; + case 143: break; case 55: { return (allowHexDigitClass || allowHorizontalWhitespaceClass ? RegExpTT.CHAR_CLASS : StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN); } - case 145: break; + case 144: break; case 48: { return yystate() != CLASS2 ? RegExpTT.BOUNDARY : RegExpTT.ESC_CHARACTER; } - case 146: break; + case 145: break; case 22: { yypopstate(); return RegExpTT.RBRACE; } - case 147: break; + case 146: break; case 54: { return StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN; } - case 148: break; + case 147: break; case 53: { return RegExpTT.BAD_HEX_VALUE; } - case 149: break; + case 148: break; case 9: { return StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN; } - case 150: break; + case 149: break; case 11: { return RegExpTT.CARET; } - case 151: break; + case 150: break; case 45: { return RegExpTT.ESC_CHARACTER; } + case 151: break; + case 74: + { if (allowOctalNoLeadingZero) return RegExpTT.OCT_CHAR; + if (yystate() == CLASS2) return RegExpTT.ESC_CHARACTER; + while (yylength() > 2 && Integer.parseInt(yytext().toString().substring(1)) > capturingGroupCount) { + yypushback(1); + } + return RegExpTT.BACKREF; + } case 152: break; default: if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { diff --git a/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex b/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex index e6547a56a939..d429bd24c6ac 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex +++ b/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex @@ -27,6 +27,7 @@ import java.util.EnumSet; // as well, but is currently unfinished as it requires to tweak more places than just the lexer. private boolean xmlSchemaMode; + private int capturingGroupCount = 0; private boolean allowDanglingMetacharacters; private boolean allowNestedCharacterClasses; @@ -146,15 +147,21 @@ HEX_CHAR=[0-9a-fA-F] subexpressions exist at that point in the regular expression, otherwise the parser will drop digits until the number is smaller or equal to the existing number of groups or it is one digit." - - So, for 100% compatibility, backrefs > 9 should be resolved by the parser, but - I'm not sure if it's worth the effort - at least not atm. */ {ESCAPE} [0-7]{3} { if (allowOctalNoLeadingZero) return RegExpTT.OCT_CHAR; - return yystate() != CLASS2 ? RegExpTT.BACKREF : RegExpTT.ESC_CHARACTER; + if (yystate() == CLASS2) return RegExpTT.ESC_CHARACTER; + while (yylength() > 2 && Integer.parseInt(yytext().toString().substring(1)) > capturingGroupCount) { + yypushback(1); + } + return RegExpTT.BACKREF; } -{ESCAPE} {DIGITS} { return yystate() != CLASS2 ? RegExpTT.BACKREF : RegExpTT.ESC_CHARACTER; } +{ESCAPE} {DIGITS} { if (yystate() == CLASS2) return RegExpTT.ESC_CHARACTER; + while (yylength() > 2 && Integer.parseInt(yytext().toString().substring(1)) > capturingGroupCount) { + yypushback(1); + } + return RegExpTT.BACKREF; + } {ESCAPE} "-" { return RegExpTT.ESC_CHARACTER; } {ESCAPE} {META} { return RegExpTT.ESC_CHARACTER; } @@ -258,7 +265,7 @@ HEX_CHAR=[0-9a-fA-F] { - {LPAREN} { return RegExpTT.GROUP_BEGIN; } + {LPAREN} { capturingGroupCount++; return RegExpTT.GROUP_BEGIN; } {RPAREN} { return RegExpTT.GROUP_END; } "|" { return RegExpTT.UNION; } diff --git a/RegExpSupport/testData/RETest.xml b/RegExpSupport/testData/RETest.xml index 88ace1f83294..f42b9af45c51 100644 --- a/RegExpSupport/testData/RETest.xml +++ b/RegExpSupport/testData/RETest.xml @@ -730,6 +730,14 @@ ([ab]+)=\1 OK + + (a)(b)(c)(d)(e)(f)(g)(h)(i)(j)\105 + OK + + + (.)\11 + OK + ([ab]+)=\2 ERR From 5103ffcb76d73f0feb8d21a4b7a49e31c4edb1ce Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Fri, 24 Oct 2014 19:06:18 +0400 Subject: [PATCH 010/132] IDEA-131878 Settings: texts and layout in Updates --- .../impl/UpdatesSettingsPanel.form | 20 ++++++------------- .../src/messages/IdeBundle.properties | 10 ++++------ 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdatesSettingsPanel.form b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdatesSettingsPanel.form index 35f47c9eb6de..dd37637ea671 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdatesSettingsPanel.form +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdatesSettingsPanel.form @@ -1,6 +1,6 @@
- + @@ -8,18 +8,10 @@ - - - - - - - - - + @@ -83,7 +75,7 @@ - + @@ -91,7 +83,7 @@ - + @@ -99,12 +91,12 @@ - + - + diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 8dbf428793f1..ee5f49e1fb53 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -923,13 +923,11 @@ updates.version.info={0} (build {1}) updates.write.protected={0} does not have write access to {1}. Please run it by a privileged user to update. updates.settings.title=Updates updates.last.check.never=Never -updates.settings.caption.1=$FULLNAME$ can automatically check for new and updated versions of itself, \ - using your internet connection (when active). updates.settings.check.now.button=&Check Now -updates.settings.checkbox=Check for updates in channel -updates.settings.build.number= Build number: -updates.settings.current.version=Current version\: -updates.settings.last.check=Last checked for updates: +updates.settings.checkbox=Automatically check updates for +updates.settings.build.number=Build number: +updates.settings.current.version=Current version: +updates.settings.last.check=Last checked: hierarchy.method.next.occurence.name=Go to next method hierarchy.method.prev.occurence.name=Go to previous method From 14cf17c63b776dde7ee294922acc0119ad45bdab Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Fri, 24 Oct 2014 17:38:08 +0200 Subject: [PATCH 011/132] Correct detach. --- .../pydevd_attach_to_process/add_code_to_python_process.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py b/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py index 05a3d7957fcb..51264ceea75e 100644 --- a/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py +++ b/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py @@ -536,7 +536,8 @@ def run_python_code_mac(pid, python_code, connect_debugger_tracing=False, show_d cmd.extend([ "-o 'process continue'", - "-o 'script import os; os._exit(1)'", + "-o 'process detach'", + # "-o 'script import os; os._exit(1)'", ]) #print ' '.join(cmd) From bf66372b2b5b49ba4a93d8ac4f573ceb7857f5b8 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Fri, 24 Oct 2014 17:38:36 +0200 Subject: [PATCH 012/132] Fix attach in case of multiple threads. --- .../linux/lldb_threads_settrace.py | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/python/helpers/pydev/pydevd_attach_to_process/linux/lldb_threads_settrace.py b/python/helpers/pydev/pydevd_attach_to_process/linux/lldb_threads_settrace.py index f08330cfaf1a..b457e1547cd2 100644 --- a/python/helpers/pydev/pydevd_attach_to_process/linux/lldb_threads_settrace.py +++ b/python/helpers/pydev/pydevd_attach_to_process/linux/lldb_threads_settrace.py @@ -3,20 +3,34 @@ def __lldb_init_module(debugger, internal_dict): # Command Initialization code goes here print('Startup LLDB in Python!') + import lldb try: - show_debug_info = 0 + show_debug_info = 1 is_debug = 0 target = debugger.GetSelectedTarget() if target: process = target.GetProcess() if process: - for t in process: + for thread in process: # Get the first frame - frame = t.GetFrameAtIndex (t.GetNumFrames()-1) - if frame: - print('Will settrace in: %s' % (frame,)) - frame.EvaluateExpression("expr (int) SetSysTraceFunc(%s, %s);" % ( - show_debug_info, is_debug)) + print('Thread %s, suspended %s\n'%(thread, thread.IsStopped())) + + process.SetSelectedThread(thread) + + if not thread.IsStopped(): + error = process.Stop() + print(error) + + if thread: + frame = thread.GetSelectedFrame() + if frame: + print('Will settrace in: %s' % (frame,)) + res = frame.EvaluateExpression("(int) SetSysTraceFunc(%s, %s)" % ( + show_debug_info, is_debug), lldb.eDynamicCanRunTarget) + error = res.GetError() + if error: + print(error) + thread.Resume() except: import traceback;traceback.print_exc() From c877877cf18091125c09a542482ccc2d3e563229 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 24 Oct 2014 19:41:55 +0400 Subject: [PATCH 013/132] [vcs] Fix VcsRootScanner initialization Don't start in the post-startup activity: mappings are already initialized at that time => VcsRootScanner will never be "ready" to scheduleScan. Instead register the vcs initialization request with the least priority: at that time both the Project and mappings are initialized, and scan can be performed right away. --- .../vcs/impl/ProjectLevelVcsManagerImpl.java | 6 ++++ .../openapi/vcs/roots/VcsRootScanner.java | 35 +++---------------- 2 files changed, 10 insertions(+), 31 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java index 84ca76e1d89f..45f550271825 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java @@ -243,6 +243,12 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme else { myContentManager = ContentFactory.SERVICE.getInstance().createContentManager(true, myProject); } + } + }); + + addInitializationRequest(VcsInitObject.AFTER_COMMON, new Runnable() { + @Override + public void run() { if (!ApplicationManager.getApplication().isUnitTestMode()) { VcsRootChecker[] checkers = Extensions.getExtensions(VcsRootChecker.EXTENSION_POINT_NAME); if (checkers.length != 0) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootScanner.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootScanner.java index 8ee2f551fd80..b052d0bd78ff 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootScanner.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootScanner.java @@ -16,11 +16,9 @@ package com.intellij.openapi.vcs.roots; import com.intellij.ProjectTopics; -import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootEvent; import com.intellij.openapi.roots.ModuleRootListener; -import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsListener; import com.intellij.openapi.vcs.VcsRootChecker; @@ -34,36 +32,22 @@ import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.concurrent.TimeUnit; -/** - * @author Nadya Zabrodina - */ public class VcsRootScanner implements BulkFileListener, ModuleRootListener, VcsListener { @NotNull private final VcsRootProblemNotifier myRootProblemNotifier; @NotNull private final VcsRootChecker[] myCheckers; - private volatile boolean myProjectIsInitialized; - private volatile boolean myMappingsAreReady; - @NotNull private final Alarm myAlarm; private static final long WAIT_BEFORE_SCAN = TimeUnit.SECONDS.toMillis(1); public static void start(@NotNull Project project, @NotNull VcsRootChecker[] checkers) { - new VcsRootScanner(project, checkers); + new VcsRootScanner(project, checkers).scheduleScan(); } private VcsRootScanner(@NotNull Project project, @NotNull VcsRootChecker[] checkers) { myRootProblemNotifier = VcsRootProblemNotifier.getInstance(project); myCheckers = checkers; - StartupManager.getInstance(project).runWhenProjectIsInitialized(new DumbAwareRunnable() { - @Override - public void run() { - myProjectIsInitialized = true; - scanIfReady(); - } - }); - final MessageBus messageBus = project.getMessageBus(); messageBus.connect().subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this); messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, this); @@ -82,7 +66,7 @@ public class VcsRootScanner implements BulkFileListener, ModuleRootListener, Vcs String filePath = event.getPath(); for (VcsRootChecker checker : myCheckers) { if (checker.isVcsDir(filePath)) { - scanIfReady(); + scheduleScan(); break; } } @@ -95,23 +79,12 @@ public class VcsRootScanner implements BulkFileListener, ModuleRootListener, Vcs @Override public void rootsChanged(ModuleRootEvent event) { - scanIfReady(); + scheduleScan(); } @Override public void directoryMappingChanged() { - myMappingsAreReady = true; - scanIfReady(); - } - - private void scanIfReady() { - if (readyToScan()) { - scheduleScan(); - } - } - - private boolean readyToScan() { - return myMappingsAreReady && myProjectIsInitialized; + scheduleScan(); } private void scheduleScan() { From f316d3bb46dcdbbbcafb5d97e36642e5f088fd12 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 24 Oct 2014 19:43:01 +0400 Subject: [PATCH 014/132] [vcs] IDEA-95947 Don't notify about the same unregistered root twice --- .../openapi/vcs/roots/VcsRootProblemNotifier.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java index fcafc513fcb8..3b8100978094 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java @@ -28,12 +28,14 @@ import com.intellij.openapi.vcs.VcsDirectoryMapping; import com.intellij.openapi.vcs.VcsNotifier; import com.intellij.openapi.vcs.VcsRootError; import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.event.HyperlinkEvent; import java.util.ArrayList; import java.util.Collection; +import java.util.Set; import static com.intellij.openapi.util.text.StringUtil.pluralize; @@ -46,6 +48,7 @@ public class VcsRootProblemNotifier { private final @NotNull Project myProject; private final @NotNull VcsConfiguration mySettings; + @NotNull private final Set myReportedUnregisteredRoots = ContainerUtil.newHashSet(); private @Nullable Notification myNotification; private final @NotNull Object NOTIFICATION_LOCK = new Object(); @@ -78,6 +81,11 @@ public class VcsRootProblemNotifier { String title = makeTitle(unregisteredRoots, invalidRoots); String description = makeDescription(unregisteredRoots, invalidRoots); + if (myReportedUnregisteredRoots.containsAll(unregisteredRoots) && invalidRoots.isEmpty()) { + return; + } + myReportedUnregisteredRoots.addAll(unregisteredRoots); + synchronized (NOTIFICATION_LOCK) { expireNotification(); NotificationListener listener = new MyNotificationListener(myProject, mySettings); From d0ecb2efd295bf6a3168c6fafbf6a1d0b768bf0d Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Fri, 24 Oct 2014 19:48:50 +0400 Subject: [PATCH 015/132] Fix the layout of the Usage Statistics configurable --- .../configurable/StatisticsConfigurable.java | 3 ++- .../StatisticsConfigurationComponent.form | 22 +++++-------------- .../StatisticsConfigurationComponent.java | 5 ++--- .../src/messages/StatisticsBundle.properties | 7 ++++-- 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java index 0a70d05c708f..94a12bb944fd 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java @@ -16,6 +16,7 @@ package com.intellij.internal.statistic.configurable; import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; +import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.SearchableConfigurable; import org.jetbrains.annotations.Nls; @@ -25,7 +26,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; -public class StatisticsConfigurable implements SearchableConfigurable { +public class StatisticsConfigurable implements SearchableConfigurable, Configurable.NoScroll { private boolean modifiedByDefault; diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form index 5a20875acb0f..6015b65620e0 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form +++ b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form @@ -3,7 +3,7 @@ - + @@ -38,8 +38,8 @@ - - + + @@ -75,22 +75,12 @@ - - + - + - - - - - - - - - - + diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java index 6aa0329a831e..15d3e63727f0 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java @@ -21,7 +21,7 @@ import com.intellij.internal.statistic.connect.StatisticsService; import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; import com.intellij.openapi.application.ApplicationInfo; import com.intellij.openapi.application.ApplicationNamesInfo; -import com.intellij.util.ui.UIUtil; +import com.intellij.ui.RelativeFont; import javax.swing.*; import java.awt.event.ActionEvent; @@ -37,14 +37,13 @@ public class StatisticsConfigurationComponent { private JRadioButton myMonthlyRadioButton; private JRadioButton myWeeklyRadioButton; private JLabel myLabel; - private JPanel myRadioButtonPanel; public StatisticsConfigurationComponent() { String product = ApplicationNamesInfo.getInstance().getFullProductName(); String company = ApplicationInfo.getInstance().getCompanyName(); myTitle.setText(StatisticsBundle.message("stats.title", product, company)); myLabel.setText(StatisticsBundle.message("stats.config.details", company)); - myLabel.setFont(UIUtil.getLabelFont(UIUtil.FontSize.SMALL)); + RelativeFont.SMALL.install(myLabel); myAllowToSendUsagesCheckBox.setText(StatisticsBundle.message("stats.config.allow.send.stats.text", company)); myAllowToSendUsagesCheckBox.addActionListener(new ActionListener() { diff --git a/platform/platform-resources-en/src/messages/StatisticsBundle.properties b/platform/platform-resources-en/src/messages/StatisticsBundle.properties index e7705d703990..3f37e06b648d 100644 --- a/platform/platform-resources-en/src/messages/StatisticsBundle.properties +++ b/platform/platform-resources-en/src/messages/StatisticsBundle.properties @@ -1,4 +1,7 @@ -stats.title=Help improve {0} by sending anonymous usage statistics to {1} +stats.title=Help improve {0} by sending anonymous usage statistics to {1} stats.config.allow.send.stats.text=Allow sending usage statistics to {0} -stats.config.details=We are asking your permission to send information about your plugins configuration (what is enabled
and what is not) and feature usage statistics (e.g. how frequently you are using code completion).
This data is anonymous, does not contain any personal information, collected for use only by {0}
and will never be transmitted to any third party. \ No newline at end of file +stats.config.details=We are asking your permission to send information about your plugins configuration \ + (what is enabled and what is not) and feature usage statistics (e.g. how frequently you are using code completion). \ + This data is anonymous, does not contain any personal information, \ + collected for use only by {0} and will never be transmitted to any third party. \ No newline at end of file From 4c725a50cd3cbdddb0c113656556542816c59047 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Fri, 24 Oct 2014 20:16:33 +0400 Subject: [PATCH 016/132] Fix usage of the Parent.hasOwnContent method --- .../openapi/options/newEditor/SettingsFilter.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java index fdd4fa96aaee..0818cb6d176f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java @@ -20,6 +20,7 @@ import com.intellij.ide.ui.search.SearchableOptionsRegistrar; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurableGroup; import com.intellij.openapi.options.SearchableConfigurable; +import com.intellij.openapi.options.ex.ConfigurableWrapper; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.wm.IdeFocusManager; @@ -208,10 +209,7 @@ abstract class SettingsFilter extends ElementFilter.Active.Impl { } private static boolean isEmptyParent(Configurable configurable) { - if (configurable instanceof SearchableConfigurable.Parent) { - SearchableConfigurable.Parent parent = (SearchableConfigurable.Parent)configurable; - return !parent.hasOwnContent(); - } - return false; + SearchableConfigurable.Parent parent = ConfigurableWrapper.cast(SearchableConfigurable.Parent.class, configurable); + return parent != null && !parent.hasOwnContent(); } } From 11dd3e927a08b9424b23667cc44cc927aef404d6 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 24 Oct 2014 14:26:25 +0200 Subject: [PATCH 017/132] SE gear icon (cherry picked from commit e74f1ce) --- .../icons/src/general/searchEverywhereGear.png | Bin 0 -> 14657 bytes .../src/general/searchEverywhereGear@2x.png | Bin 0 -> 14747 bytes .../general/searchEverywhereGear@2x_dark.png | Bin 0 -> 14747 bytes .../src/general/searchEverywhereGear_dark.png | Bin 0 -> 14657 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 platform/icons/src/general/searchEverywhereGear.png create mode 100644 platform/icons/src/general/searchEverywhereGear@2x.png create mode 100644 platform/icons/src/general/searchEverywhereGear@2x_dark.png create mode 100644 platform/icons/src/general/searchEverywhereGear_dark.png diff --git a/platform/icons/src/general/searchEverywhereGear.png b/platform/icons/src/general/searchEverywhereGear.png new file mode 100644 index 0000000000000000000000000000000000000000..8500a59800e70eb9991c712b80713712508038f9 GIT binary patch literal 14657 zcmeI3Ux*t;9LMJ@_RqCf3l>`ML6N{LeN?xn8clv(4Rc&C$CT?cVO>vRty8 z+uby|6QNd1EBGK5L`1McA5^pmf(Ra3q*YOT(1Q36Uu+-R7eVo%4_aq;bIC8cq+_Lz z6G--VGvDuTW!L_)TGAm%k-z}GD%Rzj>6T;CBv5MY2M2#lh|z*c+QhJ z3u%7H9gv&JO>)Dgg}G=j8c;MYfB2vhMn9D)?n$%fSt-2efky^XM)WE(b^@OF9Lry6HjXV209imH`HA9W+ zHYv>|P_m?Oy<_YMUTkk&?I`Kqaa2((8@rn=&9CmZ=K0k;o?MT&X=O!q53-Ev?ggx+ zgtpe!w3^O_P5-|O=;sIa-ec5?*tp$>@>6-L-brk;;M5cg56zRBplowLVY{OTz9jTtT~A}C8Ps4>GuMFa&57oj3(}y* z3>Os<6fj(n1~q25sED9|;es@%F~dbg1O*Hiq(O}tE-E4@V7MR+YJ6K<{jC@NutDDP ztC83Ft`594O$bmBRLZr&o->j+gvgl-%|NPZQe9p=kVT|PjxZ;oY$ z^7WrCo!z_jGjUt?nUgacPle)NoZh(MG`i)YhR&|+IkUO=?6;9u2J^q&bNu4; z<;^dhANh6Qho?{c@u9Z=(6yTrsPD`pD-R@|_+V4``~55LK3~6Z>Z91_i(l{DJG6EA p#=33SrgvQbd-|WB&6WGmske8Qu>aV}e*p_% literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/searchEverywhereGear@2x.png b/platform/icons/src/general/searchEverywhereGear@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..bbc8c4eaf04be55ac2aa915fa724e82850a8835c GIT binary patch literal 14747 zcmeI3U5pb|6vywP0V!Zq3=(wXFe^c$?acIpwv%be(k^s^U7OvmEHP1Lr?=h7ww-Zi zO1t%C#b^)%2|~oIChmhVN>HNFgbxEN2@h)Efd_&-@MIJWMnib;E9#wTx4rGQTroV} zCheTP_kYg0^E>C>otJq%HMC`gYmEy4uwpO~A4XTk{@$|~{hHP4O>|kRC$^gaEL&-R zd%(=Qs{shDQPX4ASn_F6(Fz_pqm4sPrJy4<0Mf>aE-RDJV#Z-kEk@X1PM&5NH4|aC z1(JMHkHHBwQ8nO5bttV=CzWu9-57OA6%hp}KucySg?!NzD-qU-Dpa32s>d}y2x?ma@kY%c{C%(3E^;<qZK2&i9=H{ zRNYdwB4fvu$F-6bVOcv-<5Rz{g5F3}H0$gTMXn<2oZ#WPPEHx6;iH#~ytA~7!ofT& zz@lX$KcS)x6;???kzRjEKW-#d#3B!VMXoYX3x~zoK~n+NJ952#tbN1nvvGDe6-eOsdwX2(@ZU%yJ*@98jihj4iyS@Ij;1l_vDEOY_QBU$%keaeBMpDbD z*{KCF{HT{je@hHZ*&YLJos4YB|0xQt#o}ZXF{>E`*@~(KIR`ntn3K5XAf{|Ilo-?U znt_%Dqdtl2G>myUO(qT&O-n8+a4;T410Ge)h)On~z^r%N9ms|QZhycZa)*Kn?+*Hd zKE)ptvc7EAftXCAYFy_S8-Xvjj?PcyRp&U;Wy6H_W{a@%yRC74HI66S$Jw-^tk?%xRI&F0%t&0z zXmeQ&&$^rXe+yWPkGXfxQJ#RsTWzRXC`Z*jh^b|*vTVTq9O?)9tR? zZ|#atx4SkyM~kWz_13es4P##Rd0RUXM$n@HjBW@7d;y7TA8z+ZsTG(Xi>qksns!6_ zP$tKxeWIh|_HK^YMBTAgD(s)QQ_0#WdPG1^CtTz4q_xP6J#dGO<{jPPz<4;C1gAl? zDJ~)+TtIQ*G>A6EMMQ)PC@!1^(WbbFh;RYLh0`F~6c-T@E}*z@8bq7oA|k>C6cCg`-jhc_nd2X4@jFm(xJt_O}SQaXGVKt*9NQu&&N;9 zjUG7;*1fa;2XJZE&zJNOJ-Pg`9}~ZB9cMnhz)E}NyH7C35e6_gFckk}(~e#L0#maJ00000 literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/searchEverywhereGear@2x_dark.png b/platform/icons/src/general/searchEverywhereGear@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..a3658d816448e254e1111f1c291a46e98d7a9c56 GIT binary patch literal 14747 zcmeI3U2GIp6vuBZ_)(}@jFk`{CJP#j?9R-7(C)Cid~|`ej? zH`$%jd;jO0JHK=8?YzwX?#&yUo0c>ogqpiL<2~fcx!(uxC%^XC*bKQmWOi<|5nAw= z`)xqSPAo>KeTmjL;0z=-Ns5v2$*PgWzFfv6YJ?)IbEd2eV~0!PK~0Z(e*NTvhtt%k zXKN@SB+L#xq;-y2xOZ%GpE5SAgjLV#SW_e?kpLO&$XqUy)@>;l_2lD9#CC^y50{rX z!%@##Hz7BW=;k^M3v(e~$g2oqkZTM3#E=+l7gun8K@9LhfENQ^(Ju*MNepqtk0;hd ztcaziq@MVOVmk6y)HCEbro{8vY}S_z_zY{17sKH&FZg-C-%Au;dsKJioL9G(7J|&i ziDO%_G}F-xopa;LNn^x`dOU8T(x-S|8MBl~w~OouMLs8+yyz47T287`@-auObbe{7 z!s9f~VBN8apIFn+95Nik9y02rEKS!nxs|20?%vT-<>FLCa%bwU9p|()%ral0q^FmqCM zYBp)jQP8raar4JmFWyx-Iy;fp^2d=WTQ+t#ThueV+e+tG>3DK|@|#wY755;EDehjt zYJ{&CEibF&S#;C>ZvhMOfqVTN*&(doX+sr4@%?kl5J*p!| zc=yatYn3%9j8>K=zvD@>&MjrcJ<24~24qQc9={mj=Zuvz7xV*eInyI~eVbn(A6|5S zi>`3G+I8EVUEy@KYuU43*PNKYn5}9Uc)90o;Y8>qj|MolG877gB7F65wMVy>!|8#z zMz*f)He`Tg%KKDL)O6fd&k;-%9Sfxb|HSi^ER2#z1oCvkmmW_li(J|R_t+@k(LD|f z!?7fg2GwS`sED9|;es@%Hp4|l1O*Hiq(QYAE-E4@V7MR+s?Bgw5kUdN1!+)ihKq^_ z3K%X(gK9HeR76m~a6uYWo8h7&f&zvM(xBQ57Zni{FkFxZ)n>S;h@gPsf;6Z$!$m~| z1q>IYLA4n!Dk3OgxF8Lx&2Ui>K>@=BX;5v3i;4&e7%oVIYBO9^L{PwRK^jz>;i4jf z0)`9HpxO)<6%iCLT#yFUX1J(`pn&0mG^jSiMMVS!3>Tz9wHYodA}Cu@fQb2trR7hjx6v zfoT8gim&au*)y&43 z-+X%Vr4LVj*MIHBkKX;};WH9K=YN0s?5)hANi?+(HJ>_s-+=WC3aYEn`%6(M+I#NG z#1Ce}rbj0m7NY|b)5h!PF3!L8X5&=+$z3zI|9twrHBC1kKe2t^UbORI>yIsy&m-Z` zBP-XOH2+3Z4eb-s+1sC8KQiy&AF0f;{>+!xdQktoQ^yuepASxc)q5t_a{9*N=lHje z&v-7+Kb^cZfBE+Zf)7l#roVXg`1o*=3vV3Xv8ZwX8?A3OZ-3#Z&MW)Ao=UxTd9>ly f>USAbzwj4iiNs?#|49B|GeH8?#9h?4~hIX(FPT%-m$h?9NPQ zCf!X$EUk!r=u1lN2fkRUUz$d+?%B<5u9ZIC zh21&1_kYg0^E>C>%*z}b8Q#66eMdV&Xv@%Gc9dMVdEbo>kl)AuxTBEECTnoQLFmDU zyl)#i`|e{1_3Y5c#@+GU9$7VuVMQ~iaJXEwh#H~P&a$Pbv)JXP@QiMx`QI*H<~dzU z^9SNNF=zGRygs;K<9!RmW9q`Jn$-B6nf6p!CIO1rRk(7oU^sF)&HHg>Vtc~^&-oH} zHqG~X3Aypy2-j!Yn2U$wAyt%OTz4`o#idw}^eh(0yE*&=0ix@BTglU%NvyXkt1#ipqpxBn19P(j+%(;1t$urP`p zbIw+A{~>ZKoz3pv)u(I4sf*;zv|Kwb>n+^8nZV6&g`h$ya<6iqjTP6l$4s-33A$`# z6(QHx$31;OH#D>4Jd+X{)wNRB0^zLU;tXlUSV$5>k=U3NmBnsZigt;lCq)n>P&UNK znVLR5za~bE^s*f5hB1J$F$UQ>n&K+|DGJnrIGQR?n|4ugGkQ^(!GdMXq=ecaP*xjC z?lTLfO_qf-(Uj0^7aJtcT zVtrRQ-RN5L+;8Y^CQ`}PFburB^ENmU_K`;eoJqvv(RfN|9B%X&(aX3np4G|Lb-ad@ z5*44uiKdPdtsKEb#W5%q_$TgHG8iR~2;}KRs6L+57rD9z?y*t3qk9|}hGR(}4XVv> zQ4v7_!v$$jZH9}A2nrZ3NP}uKTvS9*z;HntRGZj3(}z43>Os<6fj(n2GwS` zsED9|;es@%Hp4|l1O*Hiq(QYAE-E4@V7MR+s?Bgw5kUdN1!+)ihKq^_3K%X(gK9He zR76m~a6uYWo8h7&f&zvM(xBQ57Zni{FkFxZ)n>S;h@gPsf;6Z$!$m~|1q>IYLA4n! zDk3OgxF8Lx&2Ui>K>@=BX;5v3i;4&e7%oVIYBO9^L{PwRK^jzhU0m(87yht8-tsGv z*ZHE~ow-0>1?1Gh(HuexPa<^qC_;bTA=g_7&4~!zolzT>L6IqMu5*mx2P|71H}=(z9Khrc-7|IsJgpXj>z!B3r!e0t`FaQ()n Date: Fri, 24 Oct 2014 14:26:50 +0200 Subject: [PATCH 018/132] + SE settings icon (cherry picked from commit 958ecc3) --- platform/util/src/com/intellij/icons/AllIcons.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java index cdf7fda9c9c0..43dd68c2c370 100644 --- a/platform/util/src/com/intellij/icons/AllIcons.java +++ b/platform/util/src/com/intellij/icons/AllIcons.java @@ -482,6 +482,7 @@ public class AllIcons { public static final Icon Reset = IconLoader.getIcon("/general/reset.png"); // 16x16 public static final Icon Run = IconLoader.getIcon("/general/run.png"); // 7x10 public static final Icon RunWithCoverage = IconLoader.getIcon("/general/runWithCoverage.png"); // 16x16 + public static final Icon SearchEverywhereGear = IconLoader.getIcon("/general/searchEverywhereGear.png"); // 12x12 public static final Icon SecondaryGroup = IconLoader.getIcon("/general/secondaryGroup.png"); // 16x16 public static final Icon SeparatorH = IconLoader.getIcon("/general/separatorH.png"); // 17x11 public static final Icon Settings = IconLoader.getIcon("/general/settings.png"); // 16x16 From dbd9dadac53b8dbb01280c57087c90dee7aae70f Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 24 Oct 2014 14:27:59 +0200 Subject: [PATCH 019/132] SE settings icon style: hamburger -> gear (cherry picked from commit 86cab06) --- .../src/com/intellij/ide/actions/SearchEverywhereAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java index 93a33c6ce5ee..c5a1db15c2e4 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java @@ -716,7 +716,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA topPanel.add(title, BorderLayout.WEST); final JPanel controls = new JPanel(new BorderLayout()); controls.setOpaque(false); - final JLabel settings = new JLabel(AllIcons.General.WebSettings); + final JLabel settings = new JLabel(AllIcons.General.SearchEverywhereGear); new ClickListener(){ @Override public boolean onClick(@NotNull MouseEvent event, int clickCount) { From c6ba77b7029d6df5604c7a85eeb408af5ffe0dc7 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 24 Oct 2014 16:16:35 +0200 Subject: [PATCH 020/132] introduce new static method isEnabled (cherry picked from commit 4d32ab9) --- .../impl/welcomeScreen/FlatWelcomeFrameProvider.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrameProvider.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrameProvider.java index 0679762b3f46..6bf6c07a4e2b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrameProvider.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrameProvider.java @@ -26,10 +26,11 @@ import com.intellij.util.PlatformUtils; public class FlatWelcomeFrameProvider implements WelcomeFrameProvider { @Override public IdeFrame createFrame() { - if (Registry.is("ide.new.welcome.screen") - && (PlatformUtils.isIntelliJ() || PlatformUtils.isCidr())) { - return new FlatWelcomeFrame(); - } - return null; + return isAvailable() ? new FlatWelcomeFrame() : null; + } + + public static boolean isAvailable() { + return Registry.is("ide.new.welcome.screen") + && (PlatformUtils.isIntelliJ() || PlatformUtils.isCidr()); } } From e3c397416ad34977e32152c36d8a5ecba6d06870 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 24 Oct 2014 16:17:39 +0200 Subject: [PATCH 021/132] add "Check for Update" action to the new welcome screen (cherry picked from commit f3aaf92) --- .../updateSettings/impl/CheckForUpdateAction.java | 10 ++++++++-- .../wm/impl/welcomeScreen/FlatWelcomeFrame.java | 3 +-- .../platform-resources/src/idea/PlatformActions.xml | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java index 81b51cab9cb2..bfa477159ef1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,17 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.wm.impl.welcomeScreen.FlatWelcomeFrameProvider; public class CheckForUpdateAction extends AnAction implements DumbAware { @Override public void update(AnActionEvent e) { - e.getPresentation().setVisible(!SystemInfo.isMacSystemMenu || !ActionPlaces.MAIN_MENU.equals(e.getPlace())); + final String place = e.getPlace(); + if (ActionPlaces.WELCOME_SCREEN.equals(place) && FlatWelcomeFrameProvider.isAvailable()) { + e.getPresentation().setEnabledAndVisible(true); + } else { + e.getPresentation().setVisible(!SystemInfo.isMacSystemMenu || !ActionPlaces.MAIN_MENU.equals(place)); + } } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java index 564206931b40..076a161d26f0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java @@ -294,8 +294,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { public void actionPerformed(@NotNull AnActionEvent e) { ActionGroup configureGroup = (ActionGroup)ActionManager.getInstance().getAction(groupId); final PopupFactoryImpl.ActionGroupPopup popup = (PopupFactoryImpl.ActionGroupPopup)JBPopupFactory.getInstance() - .createActionGroupPopup(null, new IconsFreeActionGroup(configureGroup), e.getDataContext(), false, false, false, null, - 10, null); + .createActionGroupPopup(null, new IconsFreeActionGroup(configureGroup), e.getDataContext(), JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false, ActionPlaces.WELCOME_SCREEN); popup.showUnderneathOfLabel(ref.get()); } }; diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 26448ea7337f..f989604a8c65 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -533,6 +533,7 @@ + From b3e9b2b9f20856007d664f90a535af1b5388ff03 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 24 Oct 2014 17:30:43 +0200 Subject: [PATCH 022/132] WelcomeScreen respect "isPopup" for ActionGroups (cherry picked from commit a60f53b) --- .../openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java index 076a161d26f0..5760c32c67b6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java @@ -508,9 +508,15 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { private final ActionGroup myGroup; public IconsFreeActionGroup(ActionGroup group) { + super(group.getTemplatePresentation().getText(), group.getTemplatePresentation().getDescription(), null); myGroup = group; } + @Override + public boolean isPopup() { + return myGroup.isPopup(); + } + @NotNull @Override public AnAction[] getChildren(@Nullable AnActionEvent e) { From 41a5a1f90f510a4c938a57413648a58000373222 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 24 Oct 2014 17:53:22 +0200 Subject: [PATCH 023/132] TemplateProjectStructureAction shows Project structure dialog with gaps (cherry picked from commit d933e31) --- .../ide/actions/TemplateProjectStructureAction.java | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/java/idea-ui/src/com/intellij/ide/actions/TemplateProjectStructureAction.java b/java/idea-ui/src/com/intellij/ide/actions/TemplateProjectStructureAction.java index ed439c6c2b70..2b38f1a281f6 100644 --- a/java/idea-ui/src/com/intellij/ide/actions/TemplateProjectStructureAction.java +++ b/java/idea-ui/src/com/intellij/ide/actions/TemplateProjectStructureAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,14 +15,5 @@ */ package com.intellij.ide.actions; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.project.ex.ProjectManagerEx; - -public class TemplateProjectStructureAction extends AnAction implements DumbAware { - @Override - public void actionPerformed(final AnActionEvent e) { - ShowStructureSettingsAction.showDialog(ProjectManagerEx.getInstanceEx().getDefaultProject()); - } +public class TemplateProjectStructureAction extends ShowStructureSettingsAction { } \ No newline at end of file From fac6c2f86ca4cd0ad54d74e628153866444d9ac2 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 24 Oct 2014 17:57:15 +0200 Subject: [PATCH 024/132] move right actions panel for 10px (cherry picked from commit 88b7198) --- .../intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java index 5760c32c67b6..b93a024a1660 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java @@ -311,6 +311,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { private JComponent createActionPanel() { JPanel actions = new NonOpaquePanel(); + actions.setBorder(new EmptyBorder(0, 10, 0, 0)); actions.setLayout(new BoxLayout(actions, BoxLayout.Y_AXIS)); ActionManager actionManager = ActionManager.getInstance(); ActionGroup quickStart = (ActionGroup)actionManager.getAction(IdeActions.GROUP_WELCOME_SCREEN_QUICKSTART); From b9dea53bfe3576d328844c864914173466c1aa38 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 24 Oct 2014 18:10:59 +0200 Subject: [PATCH 025/132] fix spacing between project name and path on welcome screen (cherry picked from commit 7d24e36) --- .../wm/impl/welcomeScreen/NewRecentProjectPanel.java | 9 +++++++++ .../wm/impl/welcomeScreen/RecentProjectPanel.java | 9 +++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewRecentProjectPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewRecentProjectPanel.java index 0d7fccb29982..fb1fc55c32ae 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewRecentProjectPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewRecentProjectPanel.java @@ -94,6 +94,15 @@ public class NewRecentProjectPanel extends RecentProjectPanel { protected Color getListForeground(boolean isSelected, boolean hasFocus) { return UIUtil.getListForeground(isSelected && hasFocus); } + + @Override + protected void layoutComponents() { + setLayout(new BorderLayout()); + myName.setBorder(new EmptyBorder(6, 5, 1, 5)); + myPath.setBorder(new EmptyBorder(1, 5, 6, 5)); + add(myName, BorderLayout.NORTH); + add(myPath, BorderLayout.SOUTH); + } }; } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/RecentProjectPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/RecentProjectPanel.java index f47c53330771..df299567505b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/RecentProjectPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/RecentProjectPanel.java @@ -28,6 +28,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CustomShortcutSet; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.UniqueNameBuilder; import com.intellij.openapi.util.text.StringUtil; @@ -239,12 +240,16 @@ public class RecentProjectPanel extends JPanel { protected RecentProjectItemRenderer(UniqueNameBuilder pathShortener) { super(new VerticalFlowLayout()); myShortener = pathShortener; + myPath.setFont(myPath.getFont().deriveFont(SystemInfo.isMac ? 10f : 11f)); setFocusable(true); - myPath.setFont(myPath.getFont().deriveFont((float)10)); + layoutComponents(); + } + + protected void layoutComponents() { add(myName); add(myPath); } - + protected Color getListBackground(boolean isSelected, boolean hasFocus) { return UIUtil.getListBackground(isSelected); } From a9bb3f412278a560428ffd2e8c8d7ed26c4d2f83 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 24 Oct 2014 10:36:19 +0200 Subject: [PATCH 026/132] make test more predictable --- .../plugins/javaFX/fxml/JavaFXQuickfixTest.java | 9 ++++++++- .../intentions/JavaFxInjectPageLanguageIntention.java | 10 +++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXQuickfixTest.java b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXQuickfixTest.java index b95b12497e7b..a99c0e4da48e 100644 --- a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXQuickfixTest.java +++ b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXQuickfixTest.java @@ -20,12 +20,16 @@ import com.intellij.openapi.application.PluginPathManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.psi.xml.XmlFile; import com.intellij.testFramework.LightProjectDescriptor; import com.intellij.testFramework.PsiTestUtil; import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.javaFX.fxml.codeInsight.inspections.JavaFxUnresolvedFxIdReferenceInspection; +import org.jetbrains.plugins.javaFX.fxml.codeInsight.intentions.JavaFxInjectPageLanguageIntention; + +import java.util.Set; public class JavaFXQuickfixTest extends LightCodeInsightFixtureTestCase { public static final DefaultLightProjectDescriptor JAVA_FX_WITH_GROOVY_DESCRIPTOR = new DefaultLightProjectDescriptor() { @@ -66,7 +70,10 @@ public class JavaFXQuickfixTest extends LightCodeInsightFixtureTestCase { myFixture.configureByFile(getTestName(true) + ".fxml"); final IntentionAction intention = myFixture.findSingleIntention("Specify page language"); assertNotNull(intention); - myFixture.launchAction(intention); + Set languages = JavaFxInjectPageLanguageIntention.getAvailableLanguages(); + assertContainsElements(languages, "groovy"); + JavaFxInjectPageLanguageIntention languageIntention = (JavaFxInjectPageLanguageIntention)intention; + languageIntention.registerPageLanguage(getProject(), (XmlFile)myFixture.getFile(), "groovy"); myFixture.checkResultByFile(getTestName(true) + ".fxml", getTestName(true) + "_after.fxml", true); } diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java index 0cbd61f765a9..dc62783d23fb 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java @@ -52,7 +52,7 @@ import java.util.TreeSet; public class JavaFxInjectPageLanguageIntention extends PsiElementBaseIntentionAction { public static final Logger LOG = Logger.getInstance("#" + JavaFxInjectPageLanguageIntention.class.getName()); - private static Set getAvailableLanguages(Project project) { + public static Set getAvailableLanguages() { final List engineFactories = new ScriptEngineManager().getEngineFactories(); final Set availableNames = new TreeSet(); @@ -68,8 +68,8 @@ public class JavaFxInjectPageLanguageIntention extends PsiElementBaseIntentionAc if (!FileModificationService.getInstance().preparePsiElementsForWrite(element)) return; final XmlFile containingFile = (XmlFile)element.getContainingFile(); - final Set availableLanguages = getAvailableLanguages(project); - if (availableLanguages.size() == 1 || ApplicationManager.getApplication().isUnitTestMode()) { + final Set availableLanguages = getAvailableLanguages(); + if (availableLanguages.size() == 1) { registerPageLanguage(project, containingFile, availableLanguages.iterator().next()); } else { final JBList list = new JBList(availableLanguages); @@ -83,7 +83,7 @@ public class JavaFxInjectPageLanguageIntention extends PsiElementBaseIntentionAc } } - private void registerPageLanguage(final Project project, final XmlFile containingFile, final String languageName) { + public void registerPageLanguage(final Project project, final XmlFile containingFile, final String languageName) { new WriteCommandAction.Simple(project, getFamilyName()) { @Override protected void run() { @@ -110,7 +110,7 @@ public class JavaFxInjectPageLanguageIntention extends PsiElementBaseIntentionAc @Override public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { - if (ContainerUtil.isEmpty(getAvailableLanguages(project))) { + if (ContainerUtil.isEmpty(getAvailableLanguages())) { return false; } setText(getFamilyName()); From 5136167d8bc84323751d04313b1c2130cbf90e45 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 24 Oct 2014 17:21:37 +0200 Subject: [PATCH 027/132] new inference: use site substitution inside one level of inference only so calls with different site substitutions are possible in one expression (IDEA-131723; IDEA-131562) --- .../src/com/intellij/psi/GenericsUtil.java | 70 +++++++++++-------- .../graphInference/InferenceSession.java | 29 ++++++-- .../ExpressionCompatibilityConstraint.java | 14 ++-- ...teSubstitutionInExpressionConstraints.java | 49 +++++++++++++ .../lambda/methodRef/ReturnTypeSpecific.java | 4 +- .../GraphInferenceHighlightingTest.java | 4 ++ 6 files changed, 125 insertions(+), 45 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SiteSubstitutionInExpressionConstraints.java diff --git a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java index 0818ea4e41a0..c49580e97c85 100644 --- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java @@ -255,41 +255,55 @@ public class GenericsUtil { final PsiSubstitutor substitutor, final PsiElement context, final boolean allowUncheckedConversion) { - nextTypeParam: for (PsiTypeParameter typeParameter : typeParams) { - PsiType substituted = substitutor.substitute(typeParameter); - if (substituted == null) return null; - if (context != null) { - substituted = PsiUtil.captureToplevelWildcards(substituted, context); + PsiType boundError = findTypeParameterBoundError(typeParameter, typeParameter.getExtendsListTypes(), + substitutor, context, allowUncheckedConversion); + if (boundError != null) { + return Pair.create(typeParameter, boundError); } + } + return null; + } - PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes(); - for (PsiClassType type : extendsTypes) { - PsiType extendsType = substitutor.substitute(type); - if (substituted instanceof PsiWildcardType) { - if (((PsiWildcardType)substituted).isSuper()) { - continue; - } - final PsiType extendsBound = ((PsiWildcardType)substituted).getExtendsBound(); - if (acceptExtendsBound(extendsType, extendsBound)) { - continue nextTypeParam; - } + public static PsiType findTypeParameterBoundError(PsiTypeParameter typeParameter, + PsiType[] extendsTypes, + PsiSubstitutor substitutor, + PsiElement context, + boolean allowUncheckedConversion) { + PsiType substituted = substitutor.substitute(typeParameter); + if (substituted == null) return null; + if (context != null) { + substituted = PsiUtil.captureToplevelWildcards(substituted, context); + } + + if (substituted instanceof PsiWildcardType) { + if (((PsiWildcardType)substituted).isSuper()) { + return null; + } + } + + for (PsiType type : extendsTypes) { + PsiType extendsType = substitutor.substitute(type); + if (substituted instanceof PsiWildcardType) { + final PsiType extendsBound = ((PsiWildcardType)substituted).getExtendsBound(); + if (acceptExtendsBound(extendsType, extendsBound)) { + return null; } - else if (substituted instanceof PsiIntersectionType) { - for (PsiType extendsBound : ((PsiIntersectionType)substituted).getConjuncts()) { - if (acceptExtendsBound(extendsType, extendsBound)) continue nextTypeParam; - } + } + else if (substituted instanceof PsiIntersectionType) { + for (PsiType extendsBound : ((PsiIntersectionType)substituted).getConjuncts()) { + if (acceptExtendsBound(extendsType, extendsBound)) return null; } - else if (substituted instanceof PsiCapturedWildcardType) { - final PsiType extendsBound = ((PsiCapturedWildcardType)substituted).getUpperBound(); - if (acceptExtendsBound(extendsType, extendsBound)) { - continue nextTypeParam; - } - } - if (extendsType != null && !TypeConversionUtil.isAssignable(extendsType, substituted, allowUncheckedConversion)) { - return Pair.create(typeParameter, extendsType); + } + else if (substituted instanceof PsiCapturedWildcardType) { + final PsiType extendsBound = ((PsiCapturedWildcardType)substituted).getUpperBound(); + if (acceptExtendsBound(extendsType, extendsBound)) { + return null; } } + if (extendsType != null && !TypeConversionUtil.isAssignable(extendsType, substituted, allowUncheckedConversion)) { + return extendsType; + } } return null; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index 51350e124dd3..22beb02e68b8 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -254,12 +254,12 @@ public class InferenceSession { } } - final PsiSubstitutor substitutor = resolveBounds(myInferenceVariables, mySiteSubstitutor); + final PsiSubstitutor substitutor = resolveBounds(myInferenceVariables, PsiSubstitutor.EMPTY); if (substitutor != null) { if (myContext != null) { myContext.putUserData(ERASED, myErased); } - mySiteSubstitutor = substitutor; + mySiteSubstitutor = mySiteSubstitutor.putAll(substitutor); for (InferenceVariable variable : myInferenceVariables) { variable.setInstantiation(substitutor.substitute(variable.getParameter())); } @@ -403,7 +403,7 @@ public class InferenceSession { } public PsiSubstitutor retrieveNonPrimitiveEqualsBounds(Collection variables) { - PsiSubstitutor substitutor = mySiteSubstitutor; + PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; for (InferenceVariable variable : variables) { final PsiType equalsBound = getEqualsBound(variable, substitutor); if (!(equalsBound instanceof PsiPrimitiveType)) { @@ -751,6 +751,22 @@ public class InferenceSession { return isProperType(bound) ? bound : substitutor.substitute(bound); } + private static boolean hasBoundProblems(final List typeParams, + final PsiSubstitutor substitutor, + final PsiElement context) { + for (InferenceVariable typeParameter : typeParams) { + if (typeParameter.getCallContext() != context) { + continue; + } + final List extendsTypes = typeParameter.getBounds(InferenceBound.UPPER); + final PsiType[] bounds = extendsTypes.toArray(new PsiType[extendsTypes.size()]); + if (GenericsUtil.findTypeParameterBoundError(typeParameter, bounds, substitutor, context, true) != null) { + return true; + } + } + return false; + } + private PsiSubstitutor resolveBounds(final Collection inferenceVariables, PsiSubstitutor substitutor) { final Collection allVars = new ArrayList(inferenceVariables); @@ -759,8 +775,7 @@ public class InferenceSession { if (!myIncorporationPhase.hasCaptureConstraints(vars)) { PsiSubstitutor firstSubstitutor = resolveSubset(vars, substitutor); if (firstSubstitutor != null) { - final Set parameters = firstSubstitutor.getSubstitutionMap().keySet(); - if (GenericsUtil.findTypeParameterWithBoundError(parameters.toArray(new PsiTypeParameter[parameters.size()]), firstSubstitutor, myContext, true) != null) { + if (hasBoundProblems(vars, firstSubstitutor, myContext)) { firstSubstitutor = null; } } @@ -837,7 +852,7 @@ public class InferenceSession { for (InferenceVariable var : vars) { LOG.assertTrue(var.getInstantiation() == PsiType.NULL); final PsiTypeParameter typeParameter = var.getParameter(); - if (substitutor.getSubstitutionMap().containsKey(typeParameter) && var.getCallContext() != myContext) { + if (substitutor.putAll(mySiteSubstitutor).getSubstitutionMap().containsKey(typeParameter) && var.getCallContext() != myContext) { continue;//todo } @@ -849,7 +864,7 @@ public class InferenceSession { type = PsiType.getJavaLangRuntimeException(myManager, GlobalSearchScope.allScope(myManager.getProject())); } else { - if (substitutor.getSubstitutionMap().get(typeParameter) != null) continue; + if (substitutor.putAll(mySiteSubstitutor).getSubstitutionMap().get(typeParameter) != null) continue; type = myErased ? null : getUpperBound(var, substitutor); } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java index b59cf70bdb69..f7b73ba5eee2 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java @@ -90,13 +90,9 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm if (method != null && !method.isConstructor()) { returnType = method.getReturnType(); if (returnType != null) { - List params = new ArrayList(); - for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(method)) { - params.add(parameter); - } - typeParams = params.toArray(new PsiTypeParameter[params.size()]); + typeParams = method.getTypeParameters(); } - } else if (myExpression instanceof PsiNewExpression) { //default constructor + } else if (myExpression instanceof PsiNewExpression) { final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)myExpression).getClassOrAnonymousClassReference(); if (classReference != null) { final PsiElement psiClass = classReference.resolve(); @@ -108,7 +104,9 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm } if (typeParams != null) { - final InferenceSession callSession = new InferenceSession(typeParams, PsiSubstitutor.EMPTY, myExpression.getManager(), myExpression); + PsiSubstitutor siteSubstitutor = + resolveResult instanceof MethodCandidateInfo && method != null && !method.isConstructor() ? ((MethodCandidateInfo)resolveResult).getSiteSubstitutor() : PsiSubstitutor.EMPTY; + final InferenceSession callSession = new InferenceSession(typeParams, siteSubstitutor, myExpression.getManager(), myExpression); callSession.propagateVariables(session.getInferenceVariables()); if (method != null) { final PsiExpression[] args = argumentList.getExpressions(); @@ -120,7 +118,7 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm if (!accepted) { return false; } - callSession.registerReturnTypeConstraints(returnType, myT); + callSession.registerReturnTypeConstraints(siteSubstitutor.substitute(returnType), myT); if (callSession.repeatInferencePhases(true)) { session.registerNestedSession(callSession); } else { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SiteSubstitutionInExpressionConstraints.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SiteSubstitutionInExpressionConstraints.java new file mode 100644 index 000000000000..927dc965042d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SiteSubstitutionInExpressionConstraints.java @@ -0,0 +1,49 @@ +import java.util.Map; +import java.util.List; + +//expected type parameter +class Sample { + + public Map test() { + return null; + } + + public void fun(T t, V v) { + } + + M bar() { + return null; + } + + void run(Sample sample) { + fun(test(), bar()); + sample.fun(test(), sample.bar()); + sample.fun(test(), bar()); + fun(test(), sample.bar()); + + fun(sample.test(), bar()); + fun(sample.test(), sample.bar()); + sample.fun(sample.test(), bar()); + sample.fun(sample.test(), sample.bar()); + } +} + +//expected generic type +class Sample1 { + public List reverse() { + return null; + } + + public void foo(Sample1 t) + { + newTreeSet(t.reverse()); + newTreeSet(reverse()); + + t.newTreeSet(t.reverse()); + t.newTreeSet(reverse()); + } + + + public void newTreeSet(List comparator) {} +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java index 0696aadf6179..6b4de4e565a8 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java @@ -67,7 +67,7 @@ class MyTest1 { } public static void main(String[] args) { - m(Foo::new); + m(Foo::new); } } class MyTest2 { @@ -104,6 +104,6 @@ class MyTest2 { } public static void main(String[] args) { - m(Foo::new); + m(Foo::new); } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java index 538b833b5e3b..122e776fda9d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java @@ -172,6 +172,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase doTest(); } + public void testSiteSubstitutionInExpressionConstraints() throws Exception { + doTest(); + } + public void testIncorporationWithEqualsBoundsSubstitution() throws Exception { doTest(); } From 04d5460d0342725990d1903afbbfce0ac5669003 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 24 Oct 2014 17:42:58 +0200 Subject: [PATCH 028/132] inspections ui: avoid NPE when non-existing scope is used --- .../src/com/intellij/codeInspection/ex/Descriptor.java | 7 +++++++ .../com/intellij/codeInspection/ex/VisibleTreeState.java | 8 +++----- .../codeInspection/ui/SingleInspectionProfilePanel.java | 5 ++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/Descriptor.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/Descriptor.java index b27befd36b00..322a273830e5 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/Descriptor.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/Descriptor.java @@ -45,6 +45,7 @@ public class Descriptor { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.Descriptor"); private final ScopeToolState myState; private final InspectionProfileImpl myInspectionProfile; + private final String myScopeName; public Descriptor(@NotNull ScopeToolState state, @NotNull InspectionProfileImpl inspectionProfile, @NotNull Project project) { myState = state; @@ -54,6 +55,7 @@ public class Descriptor { final String[] groupPath = tool.getGroupPath(); myGroup = groupPath.length == 0 ? new String[]{InspectionProfileEntry.GENERAL_GROUP_NAME} : groupPath; myKey = HighlightDisplayKey.find(tool.getShortName()); + myScopeName = state.getScopeName(); myScope = state.getScope(project); myLevel = inspectionProfile.getErrorLevel(myKey, myScope, project); myEnabled = inspectionProfile.isToolEnabled(myKey, myScope, project); @@ -137,6 +139,11 @@ public class Descriptor { return myGroup; } + @NotNull + public String getScopeName() { + return myScopeName; + } + @Nullable public NamedScope getScope() { return myScope; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/VisibleTreeState.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/VisibleTreeState.java index d81fbf692812..1dc2f40f5432 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/VisibleTreeState.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/VisibleTreeState.java @@ -176,11 +176,9 @@ public class VisibleTreeState{ final State other = (State)o; if (myKey.equals(other.myKey)) { if (myDescriptor != null && other.myDescriptor != null) { - final NamedScope scope1 = myDescriptor.getScope(); - final NamedScope scope2 = other.myDescriptor.getScope(); - if (scope1 != null && scope2 != null) { - return scope1.getName().compareTo(scope2.getName()); - } + final String scope1 = myDescriptor.getScopeName(); + final String scope2 = other.myDescriptor.getScopeName(); + return scope1.compareTo(scope2); } } return myKey.compareTo(other.myKey); diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java index 28118dd382d9..5c5f8c745c73 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java @@ -241,9 +241,8 @@ public class SingleInspectionProfilePanel extends JPanel { } else { for (ScopeToolState candidate : mySelectedProfile .getNonDefaultTools(descriptor.getKey().toString(), myProjectProfileManager.getProject())) { - final NamedScope scope = descriptor.getScope(); - LOG.assertTrue(scope != null); - if (Comparing.equal(candidate.getScopeName(), scope.getName())) { + final String scope = descriptor.getScopeName(); + if (Comparing.equal(candidate.getScopeName(), scope)) { state = candidate; break; } From a56e52d8689fe3fb807debacd5e33f8c7836f010 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 24 Oct 2014 18:20:24 +0200 Subject: [PATCH 029/132] put new variable inside lambda body: check lambda-related types only after lambda body is fixed (EA-62133 - IOE: PsiJavaParserFacadeImpl.createStatementFromText) --- .../refactoring/util/RefactoringUtil.java | 24 +++++++++---------- .../PutInLambdaBody.after.java | 20 ++++++++++++++++ .../introduceVariable/PutInLambdaBody.java | 17 +++++++++++++ .../refactoring/IntroduceVariableTest.java | 4 ++++ 4 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBody.after.java create mode 100644 java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBody.java diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java index a411917b5255..004599135fee 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java @@ -880,22 +880,22 @@ public class RefactoringUtil { LOG.assertTrue(newBody != null); newBody.add(declaration); - final PsiStatement lastBodyStatement; - if (LambdaUtil.getFunctionalInterfaceReturnType(lambdaExpression) == PsiType.VOID) { - lastBodyStatement = elementFactory.createStatementFromText("a;", lambdaExpression); - ((PsiExpressionStatement)lastBodyStatement).getExpression().replace(lambdaExpressionBody); - } - else { - lastBodyStatement = elementFactory.createStatementFromText("return a;", lambdaExpression); - final PsiExpression returnValue = ((PsiReturnStatement)lastBodyStatement).getReturnValue(); - LOG.assertTrue(returnValue != null); - returnValue.replace(lambdaExpressionBody); - } + PsiStatement lastBodyStatement = elementFactory.createStatementFromText("a;", lambdaExpression); + ((PsiExpressionStatement)lastBodyStatement).getExpression().replace(lambdaExpressionBody); newBody.add(lastBodyStatement); - final PsiLambdaExpression copy = (PsiLambdaExpression)lambdaExpression.replace(expressionFromText); + PsiLambdaExpression copy = (PsiLambdaExpression)lambdaExpression.replace(expressionFromText); newBody = (PsiCodeBlock)copy.getBody(); LOG.assertTrue(newBody != null); + + if (LambdaUtil.getFunctionalInterfaceReturnType(copy) != PsiType.VOID) { + PsiExpressionStatement lastStatement = (PsiExpressionStatement)newBody.getStatements()[1]; + PsiReturnStatement returnStatement = (PsiReturnStatement)elementFactory.createStatementFromText("return a;", copy); + final PsiExpression returnValue = returnStatement.getReturnValue(); + LOG.assertTrue(returnValue != null); + returnValue.replace(lastStatement.getExpression()); + lastStatement.replace(returnStatement); + } declaration = newBody.getStatements()[0]; declaration = (PsiStatement)JavaCodeStyleManager.getInstance(declaration.getProject()).shortenClassReferences(declaration); } diff --git a/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBody.after.java b/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBody.after.java new file mode 100644 index 000000000000..afdfb96db8e2 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBody.after.java @@ -0,0 +1,20 @@ +class Foo { + interface I { + T m(Object op); + } + + interface J { + int m(T o); + } + + + void f(J r) {} + void f(I r) {} + + { + f((Object a) -> { + int c = 1; + return c; + }); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBody.java b/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBody.java new file mode 100644 index 000000000000..3d54e3b88646 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBody.java @@ -0,0 +1,17 @@ +class Foo { + interface I { + T m(Object op); + } + + interface J { + int m(T o); + } + + + void f(J r) {} + void f(I r) {} + + { + f((Object a) -> 1); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java index 4e993aac90aa..29f792330bbf 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java @@ -437,6 +437,10 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { doTest(new MockIntroduceVariableHandler("c", false, false, false, "int")); } + public void testPutInLambdaBody() { + doTest(new MockIntroduceVariableHandler("c", false, false, false, "int")); + } + public void testNormalizeDeclarations() { doTest(new MockIntroduceVariableHandler("i3", false, false, false, "int")); } From d47dabbb0b6d8fe52ac1d967aba7991d8e3e745f Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 24 Oct 2014 18:31:01 +0200 Subject: [PATCH 030/132] constant & conditions: do not try to annotate lambda as @Nullable (IDEA-131865) --- .../codeInspection/dataFlow/DataFlowInspectionBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java index 6572fd309b78..d9358980c78f 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java @@ -470,7 +470,7 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { ? InspectionsBundle.message("dataflow.message.return.null.from.notnullable", presentableNullable) : InspectionsBundle.message("dataflow.message.return.nullable.from.notnullable", presentableNullable); final LocalQuickFix[] fixes = - PsiTreeUtil.skipParentsOfType(expr, PsiCodeBlock.class, PsiReturnStatement.class) instanceof PsiLambdaExpression + PsiTreeUtil.getParentOfType(expr, PsiMethod.class, PsiLambdaExpression.class) instanceof PsiLambdaExpression ? LocalQuickFix.EMPTY_ARRAY : new LocalQuickFix[]{ new AnnotateMethodFix(defaultNullable, ArrayUtil.toStringArray(manager.getNotNulls())) { @Override From eeb0e9c796d6ca1ea0b6128e61c643acd1da2d0a Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Fri, 24 Oct 2014 20:41:22 +0400 Subject: [PATCH 031/132] push dialog: do not repaint tree path when loading icon is not visible. --- .../dvcs-impl/src/com/intellij/dvcs/push/ui/LoadingIcon.java | 1 + .../dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java | 1 + 2 files changed, 2 insertions(+) diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/LoadingIcon.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/LoadingIcon.java index 0105032eba97..b983e8f46024 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/LoadingIcon.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/LoadingIcon.java @@ -69,6 +69,7 @@ class LoadingIcon extends JBImageIcon { } public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h) { + if (myNode instanceof RepositoryNode && !((RepositoryNode)myNode).isLoading()) return false; if ((flags & (FRAMEBITS | ALLBITS)) != 0) { TreeNode[] pathToRoot = myModel.getPathToRoot(myNode); if (pathToRoot != null) { diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java index 12236ed4aefe..6a31c1a123b7 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java @@ -155,6 +155,7 @@ public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode, public void stopLoading() { myLoading.set(false); + myLoadingIcon.setImageObserver(null); } public boolean isLoading() { From 65ec268a0cdb295e0184521f9e8cc69be58eeca7 Mon Sep 17 00:00:00 2001 From: "liana.bakradze" Date: Fri, 24 Oct 2014 21:17:03 +0400 Subject: [PATCH 032/132] EDU-235 Create sample lesson and task in course --- .../coursecreator/CCProjectGenerator.java | 7 ++-- .../coursecreator/actions/CCCreateLesson.java | 25 +++++++++---- .../coursecreator/actions/CCCreateTask.java | 35 ++++++++++++------- 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectGenerator.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectGenerator.java index 73e5bc7edf93..b40c6c5f913d 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectGenerator.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectGenerator.java @@ -20,6 +20,8 @@ import icons.CourseCreatorIcons; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.coursecreator.actions.CCCreateLesson; +import org.jetbrains.plugins.coursecreator.actions.CCCreateTask; import org.jetbrains.plugins.coursecreator.format.Course; import org.jetbrains.plugins.coursecreator.ui.CCNewProjectPanel; @@ -69,9 +71,10 @@ public class CCProjectGenerator extends PythonProjectGenerator implements Direct catch (Exception ignored) { } DirectoryUtil.createSubdirectories("hints", projectDir, "\\/"); + final PsiDirectory lessonDir = CCCreateLesson.createLesson(projectDir, 1, null, null, course); + CCCreateTask.createTask(null, project, lessonDir, false); } }.execute(); - } @NotNull @@ -81,7 +84,7 @@ public class CCProjectGenerator extends PythonProjectGenerator implements Direct message = mySettingsPanel.getDescription().equals("") ? "Enter description" : message; message = mySettingsPanel.getAuthor().equals("") ? "Enter author name" : message; message = mySettingsPanel.getName().equals("") ? "Enter course name" : message; - return message.equals("")? ValidationResult.OK : new ValidationResult(message) ; + return message.equals("") ? ValidationResult.OK : new ValidationResult(message); } @Nullable diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateLesson.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateLesson.java index bd7cb83ecc99..58b950b5a637 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateLesson.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateLesson.java @@ -14,6 +14,7 @@ import com.intellij.openapi.ui.Messages; import com.intellij.psi.PsiDirectory; import com.intellij.util.PlatformIcons; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.coursecreator.CCProjectService; import org.jetbrains.plugins.coursecreator.format.Course; import org.jetbrains.plugins.coursecreator.format.Lesson; @@ -43,17 +44,27 @@ public class CCCreateLesson extends DumbAwareAction { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { - final PsiDirectory lessonDirectory = DirectoryUtil.createSubdirectories("lesson" + (size+1), directory, "\\/"); - if (lessonDirectory != null) { - view.selectElement(lessonDirectory); - final Lesson lesson = new Lesson(lessonName); - lesson.setIndex(size + 1); - course.addLesson(lesson, lessonDirectory); - } + createLesson(directory, size + 1, lessonName, view, course); } }); } + @Nullable + public static PsiDirectory createLesson(@NotNull final PsiDirectory projectDir, int index, String name, final IdeView view, + @NotNull final Course course) { + String lessonFolderName = "lesson" + index; + final PsiDirectory lessonDirectory = DirectoryUtil.createSubdirectories("lesson" + index, projectDir, "\\/"); + if (lessonDirectory != null) { + if (view != null) { + view.selectElement(lessonDirectory); + } + final Lesson lesson = new Lesson(name != null ? name : lessonFolderName); + lesson.setIndex(index); + course.addLesson(lesson, lessonDirectory); + } + return lessonDirectory; + } + @Override public void update(@NotNull AnActionEvent event) { if (!CCProjectService.setCCActionAvailable(event)) { diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateTask.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateTask.java index fed406ec8df0..a0a16687bf23 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateTask.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateTask.java @@ -36,24 +36,35 @@ public class CCCreateTask extends DumbAwareAction { final IdeView view = e.getData(LangDataKeys.IDE_VIEW); final Project project = e.getData(CommonDataKeys.PROJECT); - if (view == null || project == null) { + if (project == null) { return; } final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view); if (directory == null) return; + createTask(view, project, directory, true); + } + + public static void createTask(final IdeView view, final Project project, final PsiDirectory lessonDir, boolean showDialog) { final CCProjectService service = CCProjectService.getInstance(project); final Course course = service.getCourse(); - final Lesson lesson = course.getLesson(directory.getName()); + final Lesson lesson = course.getLesson(lessonDir.getName()); final int size = lesson.getTaskList().size(); + final String taskName; + if (showDialog) { + taskName = Messages.showInputDialog("Name:", "Task Name", null, "task" + (size + 1), null); + } + else { + taskName = "task" + (size + 1); + } - final String taskName = Messages.showInputDialog("Name:", "Task Name", null, "task" + (size + 1), null); - if (taskName == null) return; - + if (taskName == null) { + return; + } ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { - final PsiDirectory taskDirectory = DirectoryUtil.createSubdirectories("task" + (size + 1), directory, "\\/"); + final PsiDirectory taskDirectory = DirectoryUtil.createSubdirectories("task" + (size + 1), lessonDir, "\\/"); if (taskDirectory != null) { final FileTemplate template = FileTemplateManager.getInstance().getInternalTemplate("task.html"); final FileTemplate testsTemplate = FileTemplateManager.getInstance().getInternalTemplate("tests"); @@ -74,16 +85,17 @@ public class CCCreateTask extends DumbAwareAction { for (VirtualFile virtualFile : fileEditorManager.getOpenFiles()) { fileEditorManager.closeFile(virtualFile); } - EditorHelper.openInEditor(testsFile, false); - EditorHelper.openInEditor(taskPyFile, false); - view.selectElement(taskFile); + if (view != null) { + EditorHelper.openInEditor(testsFile, false); + EditorHelper.openInEditor(taskPyFile, false); + view.selectElement(taskFile); + EditorHelper.openInEditor(taskFile, false); + } } }); } catch (Exception ignored) { } - - } } }); @@ -126,6 +138,5 @@ public class CCCreateTask extends DumbAwareAction { presentation.setVisible(true); presentation.setEnabled(true); - } } \ No newline at end of file From 1c5e8af32e92a647ebdcb9fa193f39bee6eb9da8 Mon Sep 17 00:00:00 2001 From: "liana.bakradze" Date: Fri, 24 Oct 2014 21:55:46 +0400 Subject: [PATCH 033/132] EDU-225 Don't allow to add nested task windows --- .../actions/CCAddTaskWindow.java | 39 +++++++++++++++++-- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java index 6c2635fc2273..951a5e85582b 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java @@ -18,11 +18,27 @@ import org.jetbrains.plugins.coursecreator.CCProjectService; import org.jetbrains.plugins.coursecreator.format.*; import org.jetbrains.plugins.coursecreator.ui.CreateTaskWindowDialog; +import java.util.List; + public class CCAddTaskWindow extends DumbAwareAction { private static final Logger LOG = Logger.getInstance(CCAddTaskWindow.class); public CCAddTaskWindow() { - super("Add problem to solve","Add problem to solve", null); + super("Add problem to solve", "Add problem to solve", null); + } + + + private static boolean areTaskWindowsIntersect(@NotNull final TaskFile taskFile, @NotNull final Document document, int start, int end) { + List taskWindows = taskFile.getTaskWindows(); + for (TaskWindow existingTaskWindow : taskWindows) { + int twStart = existingTaskWindow.getRealStartOffset(document); + int twEnd = existingTaskWindow.getReplacementLength() + twStart; + if ((start >= twStart && start < twEnd) || (end > twStart && end <= twEnd) || + (twStart >= start && twStart < end) || (twEnd > start && twEnd <= end)) { + return true; + } + } + return false; } @Override @@ -35,7 +51,6 @@ public class CCAddTaskWindow extends DumbAwareAction { if (file == null) return; final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); if (editor == null) return; - final SelectionModel model = editor.getSelectionModel(); final Document document = PsiDocumentManager.getInstance(project).getDocument(file); if (document == null) return; @@ -54,8 +69,16 @@ public class CCAddTaskWindow extends DumbAwareAction { final Lesson lesson = course.getLesson(lessonDir.getName()); final Task task = lesson.getTask(taskDir.getName()); final TaskFile taskFile = task.getTaskFile(file.getName()); + if (taskFile == null) { + return; + } + if (areTaskWindowsIntersect(taskFile, document, start, end)) { + return; + } final TaskWindow taskWindow = new TaskWindow(lineNumber, realStart, length, model.getSelectedText()); - CreateTaskWindowDialog dlg = new CreateTaskWindowDialog(project, taskWindow, lesson.getIndex(), task.getIndex(), file.getVirtualFile().getNameWithoutExtension(), taskFile.getTaskWindows().size() + 1); + CreateTaskWindowDialog dlg = new CreateTaskWindowDialog(project, taskWindow, lesson.getIndex(), + task.getIndex(), file.getVirtualFile().getNameWithoutExtension(), + taskFile.getTaskWindows().size() + 1); dlg.show(); if (dlg.getExitCode() != DialogWrapper.OK_EXIT_CODE) { return; @@ -85,11 +108,14 @@ public class CCAddTaskWindow extends DumbAwareAction { presentation.setEnabled(false); return; } - if (!editor.getSelectionModel().hasSelection()) { + SelectionModel selectionModel = editor.getSelectionModel(); + if (!selectionModel.hasSelection()) { presentation.setVisible(false); presentation.setEnabled(false); return; } + int start = selectionModel.getSelectionStart(); + int end = selectionModel.getSelectionEnd(); final CCProjectService service = CCProjectService.getInstance(project); final Course course = service.getCourse(); @@ -116,6 +142,11 @@ public class CCAddTaskWindow extends DumbAwareAction { presentation.setEnabled(false); return; } + if (areTaskWindowsIntersect(taskFile, editor.getDocument(), start, end)) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } presentation.setVisible(true); presentation.setEnabled(true); } From 1ec2de9c8b6e486b4f9bd8fc90302dd8c6e0bdea Mon Sep 17 00:00:00 2001 From: "liana.bakradze" Date: Fri, 24 Oct 2014 23:02:32 +0400 Subject: [PATCH 034/132] EDU-194 Add actions to change course author/description --- .../resources/META-INF/plugin.xml | 3 + .../actions/CCChangeCourseInfo.java | 106 ++++++++++++++++++ .../plugins/coursecreator/format/Course.java | 16 +++ .../coursecreator/ui/CCNewProjectPanel.java | 11 +- 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java diff --git a/python/edu/course-creator/resources/META-INF/plugin.xml b/python/edu/course-creator/resources/META-INF/plugin.xml index 7173f9d1c15b..f4e0d510a8d8 100644 --- a/python/edu/course-creator/resources/META-INF/plugin.xml +++ b/python/edu/course-creator/resources/META-INF/plugin.xml @@ -48,6 +48,9 @@ + + + diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java new file mode 100644 index 000000000000..0f3b3ae4a092 --- /dev/null +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java @@ -0,0 +1,106 @@ +package org.jetbrains.plugins.coursecreator.actions; + +import com.intellij.ide.IdeView; +import com.intellij.ide.util.DirectoryChooserUtil; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiDirectory; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.coursecreator.CCProjectService; +import org.jetbrains.plugins.coursecreator.format.Course; +import org.jetbrains.plugins.coursecreator.ui.CCNewProjectPanel; + +import javax.swing.*; + +public class CCChangeCourseInfo extends DumbAwareAction { + public CCChangeCourseInfo() { + super("Change course information", "Change course information", null); + } + + @Override + public void update(@NotNull AnActionEvent event) { + if (!CCProjectService.setCCActionAvailable(event)) { + return; + } + final Presentation presentation = event.getPresentation(); + presentation.setVisible(false); + presentation.setEnabled(false); + final Project project = event.getData(CommonDataKeys.PROJECT); + if (project == null) { + return; + } + final IdeView view = event.getData(LangDataKeys.IDE_VIEW); + if (view == null) { + return; + } + final PsiDirectory[] directories = view.getDirectories(); + if (directories.length == 0) { + return; + } + final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view); + if (directory != null && !project.getBaseDir().equals(directory.getVirtualFile())) { + return; + } + presentation.setVisible(true); + presentation.setEnabled(true); + + } + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + if (!CCProjectService.setCCActionAvailable(e)) { + return; + } + final Project project = e.getProject(); + if (project == null) { + return; + } + Course course = CCProjectService.getInstance(project).getCourse(); + if (course == null) { + return; + } + final IdeView view = e.getData(LangDataKeys.IDE_VIEW); + if (view == null) { + return; + } + final PsiDirectory[] directories = view.getDirectories(); + if (directories.length == 0) { + return; + } + final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view); + if (directory != null && !project.getBaseDir().equals(directory.getVirtualFile())) { + return; + } + CCNewProjectPanel panel = new CCNewProjectPanel(course.getName(), course.getAuthor(), course.getDescription()); + ChangeCourseInfoDialog changeCourseInfoDialog = + new ChangeCourseInfoDialog(project, panel); + changeCourseInfoDialog.show(); + if (changeCourseInfoDialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) { + course.setAuthor(panel.getAuthor()); + course.setName(panel.getName()); + course.setDescription(panel.getDescription()); + } + } + + static class ChangeCourseInfoDialog extends DialogWrapper { + + CCNewProjectPanel myNewProjectPanel; + public ChangeCourseInfoDialog(@Nullable Project project, CCNewProjectPanel panel) { + super(project); + myNewProjectPanel = panel; + init(); + } + + @Nullable + @Override + protected JComponent createCenterPanel() { + return myNewProjectPanel.getMainPanel(); + } + } +} diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Course.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Course.java index e124a6eb305d..e9af3472f260 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Course.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Course.java @@ -58,4 +58,20 @@ public class Course { } Collections.sort(lessons); } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public void setName(String name) { + this.name = name; + } + + public void setDescription(String description) { + this.description = description; + } } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CCNewProjectPanel.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CCNewProjectPanel.java index d463718978bb..de23a904422c 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CCNewProjectPanel.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CCNewProjectPanel.java @@ -27,6 +27,13 @@ public class CCNewProjectPanel { myDescription.setLineWrap(true); } + public CCNewProjectPanel(String name, String author, String description) { + this(); + myName.setText(name); + myAuthorField.setText(author); + myDescription.setText(description); + } + public JPanel getMainPanel() { return myPanel; } @@ -54,7 +61,9 @@ public class CCNewProjectPanel { @Override protected void textChanged(DocumentEvent e) { - myValidationManager.validate(); + if (myValidationManager != null) { + myValidationManager.validate(); + } } } } From 59907085c15c4cb92293c8760cd31b10ddbe99f6 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Fri, 24 Oct 2014 23:00:03 +0400 Subject: [PATCH 035/132] Fix the layout of the HTTP Proxy configurable --- .../util/net/HttpProxySettingsUi.form | 188 +++++++++--------- .../util/net/HttpProxySettingsUi.java | 18 +- .../src/messages/CommonBundle.properties | 12 +- 3 files changed, 106 insertions(+), 112 deletions(-) diff --git a/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.form b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.form index 3d2ae0575e1f..70561034a3ea 100644 --- a/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.form +++ b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.form @@ -1,58 +1,30 @@ - + - + - - + + - + - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - + @@ -62,15 +34,67 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -79,67 +103,39 @@ - + - + - + - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - + - + @@ -148,23 +144,25 @@ - + - + - + + + - + @@ -173,14 +171,14 @@ - + - + @@ -188,7 +186,7 @@ - + @@ -198,7 +196,7 @@ - + @@ -206,22 +204,24 @@ - + - + - + - + + + - + - + @@ -234,14 +234,6 @@ - - - - - - - - @@ -252,6 +244,14 @@ + + + + + + + + diff --git a/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java index e71d8e5af4ec..f4c849f015f7 100644 --- a/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java +++ b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java @@ -21,17 +21,16 @@ import com.google.common.net.InternetDomainName; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.options.ConfigurableUi; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.ui.MultiLineLabelUI; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.IdeFrame; import com.intellij.ui.PortField; -import com.intellij.ui.components.JBLabel; +import com.intellij.ui.RawCommandLineEditor; +import com.intellij.ui.RelativeFont; import com.intellij.ui.components.JBRadioButton; import com.intellij.util.proxy.CommonProxy; import com.intellij.util.proxy.JavaProxyProperty; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -59,16 +58,16 @@ class HttpProxySettingsUi implements ConfigurableUi { private JLabel myPortNumberLabel; private JBRadioButton myAutoDetectProxyRb; private JBRadioButton myUseHTTPProxyRb; - private JBLabel mySystemProxyDefined; + private JLabel mySystemProxyDefined; private JBRadioButton myNoProxyRb; private JBRadioButton myHTTP; private JBRadioButton mySocks; private JButton myClearPasswordsButton; private JLabel myErrorLabel; private JButton myCheckButton; - private JBLabel myOtherWarning; + private JLabel myOtherWarning; private JLabel myProxyExceptionsLabel; - private JTextArea myProxyExceptions; + private RawCommandLineEditor myProxyExceptions; private JLabel myNoProxyForLabel; private JCheckBox myPacUrlCheckBox; private JTextField myPacUrlTextField; @@ -106,14 +105,11 @@ class HttpProxySettingsUi implements ConfigurableUi { proxyTypeGroup.add(mySocks); myHTTP.setSelected(true); - myProxyExceptions.setBorder(UIUtil.getTextFieldBorder()); - Boolean property = Boolean.getBoolean(JavaProxyProperty.USE_SYSTEM_PROXY); mySystemProxyDefined.setVisible(Boolean.TRUE.equals(property)); if (Boolean.TRUE.equals(property)) { mySystemProxyDefined.setIcon(Messages.getWarningIcon()); - mySystemProxyDefined.setFont(mySystemProxyDefined.getFont().deriveFont(Font.BOLD)); - mySystemProxyDefined.setUI(new MultiLineLabelUI()); + RelativeFont.BOLD.install(mySystemProxyDefined); } myProxyAuthCheckBox.addActionListener(new ActionListener() { @@ -270,7 +266,6 @@ class HttpProxySettingsUi implements ConfigurableUi { myOtherWarning.setVisible(oldStyleText != null); if (oldStyleText != null) { myOtherWarning.setText(oldStyleText); - myOtherWarning.setUI(new MultiLineLabelUI()); myOtherWarning.setIcon(Messages.getWarningIcon()); } } @@ -354,7 +349,6 @@ class HttpProxySettingsUi implements ConfigurableUi { mySocks.setEnabled(enabled); myHTTP.setEnabled(enabled); myProxyExceptions.setEnabled(enabled); - myProxyExceptions.setBackground(myProxyPortTextField.getBackground()); myProxyExceptionsLabel.setEnabled(enabled); myNoProxyForLabel.setEnabled(enabled); diff --git a/platform/platform-resources-en/src/messages/CommonBundle.properties b/platform/platform-resources-en/src/messages/CommonBundle.properties index 1fbbd0a61f57..a8f41d9f5cf0 100644 --- a/platform/platform-resources-en/src/messages/CommonBundle.properties +++ b/platform/platform-resources-en/src/messages/CommonBundle.properties @@ -159,16 +159,16 @@ safe.write.rename.backup=Cannot save {0}.\nThe file was renamed to {1}.\nYour ch safe.write.drop.temp=Cannot delete temporary file {0}. vfs.broken.link=Broken link -label.system.proxy.used=You have JVM property 'java.net.useSystemProxies' set to true.\n\ -This will cause some network calls to go through operating system-defined proxy.\n\ +label.system.proxy.used=You have JVM property 'java.net.useSystemProxies' set to true.
\ +This will cause some network calls to go through operating system-defined proxy.
\ If you didn't intend to use system-defined proxy, disable this property http.noproxy=No proxy http.proxy.type=HTTP socks.proxy.type=SOCKS autodetected.proxies.clear.button=Clear passwords -label.old.way.jvm.property.used=You have JVM property \"{0}\" set to \"{1}\".\n\ -This may lead to incorrect behaviour. Proxy should be set in Settings | HTTP Proxy\n\ -This JVM property is old and its usage is not recommended by Oracle.\n\ -\n(Note: It could have been assigned by some code dynamically.) +label.old.way.jvm.property.used=You have JVM property \"{0}\" set to \"{1}\".
\ +This may lead to incorrect behaviour. Proxy should be set in Settings | HTTP Proxy
\ +This JVM property is old and its usage is not recommended by Oracle.
\ +(Note: It could have been assigned by some code dynamically.) label.proxy.exceptions.text=Example\: *.domain.com, 192.168.* checkbox.automatic.proxy.configuration.url=Automatic proxy configuration URL\: \ No newline at end of file From 4c15edec5ce3c976f2d5870cec85f7645180faab Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 24 Oct 2014 21:46:41 +0200 Subject: [PATCH 036/132] Cleanup (formatting) --- .../modules/decompiler/ExprProcessor.java | 25 +++++++++---------- .../decompiler/exps/InvocationExprent.java | 12 +++++---- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index 6bf80725bf88..edccefe2405e 100644 --- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -855,8 +855,12 @@ public class ExprProcessor implements CodeConstants { return defaultval; } - public static boolean getCastedExprent(Exprent exprent, VarType leftType, TextBuffer buffer, int indent, - boolean castNull, BytecodeMappingTracer tracer) { + public static boolean getCastedExprent(Exprent exprent, + VarType leftType, + TextBuffer buffer, + int indent, + boolean castNull, + BytecodeMappingTracer tracer) { return getCastedExprent(exprent, leftType, buffer, indent, castNull, false, tracer); } @@ -865,7 +869,8 @@ public class ExprProcessor implements CodeConstants { TextBuffer buffer, int indent, boolean castNull, - boolean castAlways, BytecodeMappingTracer tracer) { + boolean castAlways, + BytecodeMappingTracer tracer) { boolean ret = false; VarType rightType = exprent.getExprType(); @@ -873,16 +878,10 @@ public class ExprProcessor implements CodeConstants { TextBuffer res = exprent.toJava(indent, tracer); boolean cast = - !leftType.isSuperset(rightType) && (rightType.equals(VarType.VARTYPE_OBJECT) || leftType.type != CodeConstants.TYPE_OBJECT); - cast |= castAlways; - - if (!cast && castNull && rightType.type == CodeConstants.TYPE_NULL) { - // check for a nameless anonymous class - cast = !UNDEFINED_TYPE_STRING.equals(getTypeName(leftType)); - } - if (!cast) { - cast = isIntConstant(exprent) && VarType.VARTYPE_INT.isStrictSuperset(leftType); - } + castAlways || + (!leftType.isSuperset(rightType) && (rightType.equals(VarType.VARTYPE_OBJECT) || leftType.type != CodeConstants.TYPE_OBJECT)) || + (castNull && rightType.type == CodeConstants.TYPE_NULL && !UNDEFINED_TYPE_STRING.equals(getTypeName(leftType))) || + (isIntConstant(exprent) && VarType.VARTYPE_INT.isStrictSuperset(leftType)); if (cast) { if (exprent.getPrecedence() >= FunctionExprent.getPrecedence(FunctionExprent.FUNCTION_CAST)) { diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java index 57711eee2bd0..b80b745c04e2 100644 --- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -357,21 +357,23 @@ public class InvocationExprent extends Exprent { Set setAmbiguousParameters = getAmbiguousParameters(); - boolean firstpar = true; + boolean firstParameter = true; int start = isEnum ? 2 : 0; for (int i = start; i < lstParameters.size(); i++) { if (sigFields == null || sigFields.get(i) == null) { - if (!firstpar) { + if (!firstParameter) { buf.append(", "); } TextBuffer buff = new TextBuffer(); - ExprProcessor.getCastedExprent(lstParameters.get(i), descriptor.params[i], buff, indent, true, setAmbiguousParameters.contains(i), tracer); - + boolean ambiguous = setAmbiguousParameters.contains(i); + ExprProcessor.getCastedExprent(lstParameters.get(i), descriptor.params[i], buff, indent, true, ambiguous, tracer); buf.append(buff); - firstpar = false; + + firstParameter = false; } } + buf.append(")"); return buf; From 8f67ad587e6dcf8d12198cf628493924ced4ec3b Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 24 Oct 2014 20:44:56 +0200 Subject: [PATCH 037/132] "might not have been initialized" adjusted for lambdas inside anonymous (IDEA-130468) --- .../analysis/HighlightControlFlowUtil.java | 2 +- ...ghtNotHaveBeenInitializedInsideLambda.java | 66 +++++++++++++++++++ .../lambda/LightAdvHighlightingJdk8Test.java | 4 ++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/advHighlighting/FinalVariableMightNotHaveBeenInitializedInsideLambda.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java index 43282b614544..d1c5d9bec832 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java @@ -260,7 +260,7 @@ public class HighlightControlFlowUtil { } else { PsiElement scope = variable instanceof PsiField - ? variable.getContainingFile() + ? ((PsiField)variable).getContainingClass() : variable.getParent() != null ? variable.getParent().getParent() : null; if (scope instanceof PsiCodeBlock && scope.getParent() instanceof PsiSwitchStatement) { scope = PsiTreeUtil.getParentOfType(scope, PsiCodeBlock.class); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/advHighlighting/FinalVariableMightNotHaveBeenInitializedInsideLambda.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/advHighlighting/FinalVariableMightNotHaveBeenInitializedInsideLambda.java new file mode 100644 index 000000000000..c8e80cc743c4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/advHighlighting/FinalVariableMightNotHaveBeenInitializedInsideLambda.java @@ -0,0 +1,66 @@ +class Test { + final Runnable runnable; + + { + runnable = () -> System.out.println(runnable); + } + + final Runnable runnable1; + { + runnable1 = new Runnable() { + @Override + public void run() { + System.out.println(runnable1); + } + }; + } + +} + +abstract class TestInnerAnonymous { + + + void foo() { + new Object() { + final Runnable runnable; + + { + runnable = () -> System.out.println(runnable); + } + + final Runnable runnable1; + + { + runnable1 = new Runnable() { + @Override + public void run() { + System.out.println(runnable1); + } + }; + } + + }; + } + + + private static class MyObject { + final Runnable runnable; + + { + runnable = () -> System.out.println(runnable); + } + + final Runnable runnable1; + + { + runnable1 = new Runnable() { + @Override + public void run() { + System.out.println(runnable1); + } + }; + } + + } +} + diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LightAdvHighlightingJdk8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LightAdvHighlightingJdk8Test.java index 08a2b63550ff..4ecf0b2b434e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LightAdvHighlightingJdk8Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LightAdvHighlightingJdk8Test.java @@ -39,6 +39,10 @@ public class LightAdvHighlightingJdk8Test extends LightDaemonAnalyzerTestCase { doTest(); } + public void testFinalVariableMightNotHaveBeenInitializedInsideLambda() throws Exception { + doTest(); + } + private void doTest() { IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); doTest(BASE_PATH + "/" + getTestName(false) + ".java", true, false); From 7184d46d8ad923c922d1d1e81be730ce8a1289dc Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 24 Oct 2014 21:44:38 +0200 Subject: [PATCH 038/132] new inference: compare classes from different jdks (IDEA-131888) --- .../graphInference/constraints/TypeEqualityConstraint.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java index 62f1ff1d819c..03b20b3fb443 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java @@ -91,7 +91,7 @@ public class TypeEqualityConstraint implements ConstraintFormula { final PsiClassType.ClassResolveResult sResult = ((PsiClassType)myS).resolveGenerics(); final PsiClass tClass = tResult.getElement(); //equal erasure - if (tClass != null && tClass.equals(sResult.getElement())) { + if (tClass != null && tClass.getManager().areElementsEquivalent(tClass, sResult.getElement())) { final PsiSubstitutor tSubstitutor = tResult.getSubstitutor(); final PsiSubstitutor sSubstitutor = sResult.getSubstitutor(); for (PsiTypeParameter typeParameter : tClass.getTypeParameters()) { From 19a15f5573c650d59f2efb5bb13145258ff8b355 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 24 Oct 2014 21:49:02 +0200 Subject: [PATCH 039/132] Cleanup (unneeded variable) --- .../java/decompiler/modules/decompiler/ExprProcessor.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index edccefe2405e..16ef95b38a3c 100644 --- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -872,7 +872,6 @@ public class ExprProcessor implements CodeConstants { boolean castAlways, BytecodeMappingTracer tracer) { - boolean ret = false; VarType rightType = exprent.getExprType(); TextBuffer res = exprent.toJava(indent, tracer); @@ -889,12 +888,11 @@ public class ExprProcessor implements CodeConstants { } res.prepend("(" + getCastTypeName(leftType) + ")"); - ret = true; } buffer.append(res); - return ret; + return cast; } private static boolean isIntConstant(Exprent exprent) { From e482b1021618108e454c7540b43ad7dd3d21bb08 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Sat, 25 Oct 2014 15:24:40 +0400 Subject: [PATCH 040/132] fixed EDU-236 Open first task after project creation --- .../edu/StudyDirectoryProjectGenerator.java | 54 +++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java index b558667734bc..4d389cd06294 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java @@ -5,19 +5,27 @@ import com.google.gson.stream.JsonReader; import com.intellij.facet.ui.FacetEditorValidator; import com.intellij.facet.ui.FacetValidatorsManager; import com.intellij.facet.ui.ValidationResult; +import com.intellij.ide.projectView.ProjectView; +import com.intellij.ide.projectView.impl.AbstractProjectViewPane; import com.intellij.lang.javascript.boilerplate.GithubDownloadUtil; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; import com.intellij.platform.DirectoryProjectGenerator; import com.intellij.platform.templates.github.GeneratorException; import com.intellij.platform.templates.github.ZipUtil; -import com.jetbrains.python.edu.course.Course; -import com.jetbrains.python.edu.course.CourseInfo; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.jetbrains.python.edu.course.*; import com.jetbrains.python.edu.ui.StudyNewProjectPanel; import com.jetbrains.python.newProject.PythonProjectGenerator; import icons.StudyIcons; @@ -150,12 +158,52 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple try { reader = new InputStreamReader(new FileInputStream(mySelectedCourseFile)); Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create(); - Course course = gson.fromJson(reader, Course.class); + final Course course = gson.fromJson(reader, Course.class); course.init(false); course.create(baseDir, new File(mySelectedCourseFile.getParent())); course.setResourcePath(mySelectedCourseFile.getAbsolutePath()); VirtualFileManager.getInstance().refreshWithoutFileWatcher(true); StudyTaskManager.getInstance(project).setCourse(course); + final boolean[] initialized = {false}; + ToolWindowManagerEx.getInstanceEx(myProject).addToolWindowManagerListener(new ToolWindowManagerAdapter() { + @Override + public void stateChanged() { + final AbstractProjectViewPane projectViewPane = ProjectView.getInstance(myProject).getCurrentProjectViewPane(); + if (projectViewPane == null || initialized[0]) return; + JTree tree = projectViewPane.getTree(); + tree.updateUI(); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + LocalFileSystem.getInstance().refresh(false); + final Lesson firstLesson = StudyUtils.getFirst(course.getLessons()); + final Task firstTask = StudyUtils.getFirst(firstLesson.getTaskList()); + final VirtualFile taskDir = firstTask.getTaskDir(myProject); + if (taskDir == null) return; + final Map taskFiles = firstTask.getTaskFiles(); + + VirtualFile activeVirtualFile = null; + for (Map.Entry entry : taskFiles.entrySet()) { + final String name = entry.getKey(); + final TaskFile taskFile = entry.getValue(); + final VirtualFile virtualFile = taskDir.findChild(name); + if (virtualFile != null) { + FileEditorManager.getInstance(project).openFile(virtualFile, true); + if (!taskFile.getTaskWindows().isEmpty()) { + activeVirtualFile = virtualFile; + } + } + } + if (activeVirtualFile != null) { + final PsiFile file = PsiManager.getInstance(myProject).findFile(activeVirtualFile); + ProjectView.getInstance(project).select(file, activeVirtualFile, true); + initialized[0] = true; + } + } + }); + } + }); } catch (FileNotFoundException e) { LOG.error(e); From 60134295c03b77f46190287d8a41a92b0e898e15 Mon Sep 17 00:00:00 2001 From: "liana.bakradze" Date: Sat, 25 Oct 2014 20:29:22 +0400 Subject: [PATCH 041/132] fixed NPE while opening first task in new study project --- .../jetbrains/python/edu/StudyDirectoryProjectGenerator.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java index 4d389cd06294..6d4270788b82 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java @@ -171,6 +171,9 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple final AbstractProjectViewPane projectViewPane = ProjectView.getInstance(myProject).getCurrentProjectViewPane(); if (projectViewPane == null || initialized[0]) return; JTree tree = projectViewPane.getTree(); + if (tree == null) { + return; + } tree.updateUI(); ApplicationManager.getApplication().invokeLater(new Runnable() { From ebe34e28d5beb00db575213cdb2d32f51bc7d9c5 Mon Sep 17 00:00:00 2001 From: "liana.bakradze" Date: Sat, 25 Oct 2014 22:23:24 +0400 Subject: [PATCH 042/132] EDU-232 Cancel task window text editing actually doesn't work --- .../coursecreator/actions/CCShowTaskWindowDetails.java | 8 +++----- .../plugins/coursecreator/ui/CreateTaskWindowDialog.java | 4 ++++ .../plugins/coursecreator/ui/CreateTaskWindowPanel.java | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowTaskWindowDetails.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowTaskWindowDetails.java index d865902a8025..e08743fc6941 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowTaskWindowDetails.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowTaskWindowDetails.java @@ -5,10 +5,7 @@ import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.coursecreator.CCProjectService; -import org.jetbrains.plugins.coursecreator.format.Course; -import org.jetbrains.plugins.coursecreator.format.Lesson; -import org.jetbrains.plugins.coursecreator.format.Task; -import org.jetbrains.plugins.coursecreator.format.TaskFile; +import org.jetbrains.plugins.coursecreator.format.*; import org.jetbrains.plugins.coursecreator.ui.CreateTaskWindowDialog; public class CCShowTaskWindowDetails extends CCTaskWindowAction { @@ -29,7 +26,8 @@ public class CCShowTaskWindowDetails extends CCTaskWindowAction { final Lesson lesson = course.getLesson(lessonDir.getName()); final Task task = lesson.getTask(taskDir.getName()); final TaskFile taskFile = state.getTaskFile(); - CreateTaskWindowDialog dlg = new CreateTaskWindowDialog(project, state.getTaskWindow(), lesson.getIndex(), task.getIndex(), + TaskWindow taskWindow = state.getTaskWindow(); + CreateTaskWindowDialog dlg = new CreateTaskWindowDialog(project, taskWindow, lesson.getIndex(), task.getIndex(), file.getVirtualFile().getNameWithoutExtension(), taskFile.getTaskWindows().size() + 1); dlg.show(); diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java index 2240d58a2846..213fc55e2cb7 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java @@ -95,6 +95,10 @@ public class CreateTaskWindowDialog extends DialogWrapper { myTaskWindow.setHint(hintName); String hintText = myPanel.getHintText(); createHint(hintName, hintText); + } else { + if (myTaskWindow.getHintName() != null) { + deleteHint(); + } } super.doOKAction(); } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.java index 4fc64fa769c6..a09945718aaa 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.java @@ -32,7 +32,7 @@ public class CreateTaskWindowPanel extends JPanel { // 1 for checked enableHint(state == 1); if (state == 2) { - myDialog.deleteHint(); + resetHint(); } } }); From c42a4ca54e0ee35c39253fb0fceb04fa904937e3 Mon Sep 17 00:00:00 2001 From: "liana.bakradze" Date: Sat, 25 Oct 2014 22:35:14 +0400 Subject: [PATCH 043/132] EDU-234 Generated python file becomes visible after .answer file was deleted --- .../plugins/coursecreator/CCProjectComponent.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectComponent.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectComponent.java index 8b524dbffd4b..88a242492581 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectComponent.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectComponent.java @@ -17,6 +17,7 @@ import com.intellij.openapi.vfs.VirtualFileAdapter; import com.intellij.openapi.vfs.VirtualFileEvent; import com.intellij.openapi.vfs.VirtualFileManager; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.coursecreator.actions.CCRunTestsAction; import org.jetbrains.plugins.coursecreator.format.Course; import org.jetbrains.plugins.coursecreator.format.Lesson; import org.jetbrains.plugins.coursecreator.format.Task; @@ -158,7 +159,8 @@ public class CCProjectComponent implements ProjectComponent { } private void deleteTaskFile(Course course, VirtualFile removedFile) { - VirtualFile taskDir = removedFile.getParent(); + + final VirtualFile taskDir = removedFile.getParent(); if (taskDir == null || !taskDir.getName().contains("task")) { return; } @@ -182,6 +184,12 @@ public class CCProjectComponent implements ProjectComponent { if (taskFile == null) { return; } + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + CCRunTestsAction.clearTestEnvironment(taskDir, myProject); + } + }); String name = CCProjectService.getRealTaskFileName(removedFile.getName()); task.getTaskFiles().remove(name); } From bfd3c27a641efd7acc9840b75708ae4c589f7f43 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Sun, 26 Oct 2014 01:19:33 +0400 Subject: [PATCH 044/132] Update test of JSON's structure view (broken after IDEA-131495) --- json/tests/test/com/intellij/json/JsonStructureViewTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/json/tests/test/com/intellij/json/JsonStructureViewTest.java b/json/tests/test/com/intellij/json/JsonStructureViewTest.java index aa5e43cf89c5..24d563e6ef77 100644 --- a/json/tests/test/com/intellij/json/JsonStructureViewTest.java +++ b/json/tests/test/com/intellij/json/JsonStructureViewTest.java @@ -66,7 +66,9 @@ public class JsonStructureViewTest extends JsonTestCase { " -object\n" + " nestedObject\n" + " -array\n" + - " +array\n" + + " -array\n" + + " -object\n" + + " deepNestedObject\n" + " -object\n" + " siblingObject\n"); } From 7c3a5f7047d053c065690b2788666797a125e777 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Sun, 26 Oct 2014 10:10:31 +0300 Subject: [PATCH 045/132] open first task: refresh directory, stop with project dispose --- .../python/edu/StudyDirectoryProjectGenerator.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java index 6d4270788b82..a9630f6f730c 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java @@ -9,15 +9,18 @@ import com.intellij.ide.projectView.ProjectView; import com.intellij.ide.projectView.impl.AbstractProjectViewPane; import com.intellij.lang.javascript.boilerplate.GithubDownloadUtil; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl; import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter; import com.intellij.openapi.wm.ex.ToolWindowManagerEx; import com.intellij.platform.DirectoryProjectGenerator; @@ -190,7 +193,7 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple for (Map.Entry entry : taskFiles.entrySet()) { final String name = entry.getKey(); final TaskFile taskFile = entry.getValue(); - final VirtualFile virtualFile = taskDir.findChild(name); + final VirtualFile virtualFile = ((VirtualDirectoryImpl)taskDir).refreshAndFindChild(name); if (virtualFile != null) { FileEditorManager.getInstance(project).openFile(virtualFile, true); if (!taskFile.getTaskWindows().isEmpty()) { @@ -204,6 +207,11 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple initialized[0] = true; } } + }, ModalityState.current(), new Condition() { + @Override + public boolean value(Object o) { + return project.isDisposed(); + } }); } }); From 6eb19626196d439c62976dcfd1bb57d49ed73b11 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 26 Oct 2014 15:05:32 +0400 Subject: [PATCH 046/132] [git] make some git push classes & methods public by request of gerrit plugin author --- .../git4idea/src/git4idea/push/GitPushTagPanel.java | 4 ++-- plugins/git4idea/src/git4idea/push/GitPushTarget.java | 10 +++++----- .../git4idea/src/git4idea/push/GitPushTargetPanel.java | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/git4idea/src/git4idea/push/GitPushTagPanel.java b/plugins/git4idea/src/git4idea/push/GitPushTagPanel.java index 21a86a63ac41..300d0b9d1a1a 100644 --- a/plugins/git4idea/src/git4idea/push/GitPushTagPanel.java +++ b/plugins/git4idea/src/git4idea/push/GitPushTagPanel.java @@ -28,12 +28,12 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -class GitPushTagPanel extends VcsPushOptionsPanel { +public class GitPushTagPanel extends VcsPushOptionsPanel { private final ComboBox myCombobox; private final JBCheckBox myCheckBox; - GitPushTagPanel(@Nullable GitPushTagMode defaultMode, boolean followTagsSupported) { + public GitPushTagPanel(@Nullable GitPushTagMode defaultMode, boolean followTagsSupported) { String checkboxText = "Push Tags"; if (followTagsSupported) { checkboxText += ": "; diff --git a/plugins/git4idea/src/git4idea/push/GitPushTarget.java b/plugins/git4idea/src/git4idea/push/GitPushTarget.java index 467c4e7448e4..4536973b9281 100644 --- a/plugins/git4idea/src/git4idea/push/GitPushTarget.java +++ b/plugins/git4idea/src/git4idea/push/GitPushTarget.java @@ -33,20 +33,20 @@ import java.util.Collection; import static git4idea.GitUtil.findRemoteBranch; -class GitPushTarget implements PushTarget { +public class GitPushTarget implements PushTarget { private static final Logger LOG = Logger.getInstance(GitPushTarget.class); @NotNull private final GitRemoteBranch myRemoteBranch; private final boolean myIsNewBranchCreated; - GitPushTarget(@NotNull GitRemoteBranch remoteBranch, boolean isNewBranchCreated) { + public GitPushTarget(@NotNull GitRemoteBranch remoteBranch, boolean isNewBranchCreated) { myRemoteBranch = remoteBranch; myIsNewBranchCreated = isNewBranchCreated; } @NotNull - GitRemoteBranch getBranch() { + public GitRemoteBranch getBranch() { return myRemoteBranch; } @@ -55,12 +55,12 @@ class GitPushTarget implements PushTarget { return isNewBranchCreated(); } - boolean isNewBranchCreated() { + public boolean isNewBranchCreated() { return myIsNewBranchCreated; } @NotNull - static GitPushTarget parse(@NotNull GitRepository repository, @Nullable String remoteName, @NotNull String branchName) throws + public static GitPushTarget parse(@NotNull GitRepository repository, @Nullable String remoteName, @NotNull String branchName) throws ParseException { if (remoteName == null) { throw new ParseException("No remotes defined", -1); diff --git a/plugins/git4idea/src/git4idea/push/GitPushTargetPanel.java b/plugins/git4idea/src/git4idea/push/GitPushTargetPanel.java index aa03697963c8..62ecbd670d4c 100644 --- a/plugins/git4idea/src/git4idea/push/GitPushTargetPanel.java +++ b/plugins/git4idea/src/git4idea/push/GitPushTargetPanel.java @@ -44,7 +44,7 @@ import java.text.ParseException; import java.util.Comparator; import java.util.List; -class GitPushTargetPanel extends PushTargetPanel { +public class GitPushTargetPanel extends PushTargetPanel { private static final Logger LOG = Logger.getInstance(GitPushTargetPanel.class); From 172d506cddc6ba0cfa91748528ffe0f68a90a8cd Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 26 Oct 2014 15:11:32 +0400 Subject: [PATCH 047/132] [push] IDEA-130622 Temporary fix for "confusing selection" problem: select all repositories with commits. --- .../dvcs-impl/src/com/intellij/dvcs/push/PushController.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java index 5de06ffd7969..92e0ae772f3b 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java @@ -176,6 +176,9 @@ public class PushController implements Disposable { final RepositoryNode repoNode = mySingleRepoProject ? new SingleRepositoryNode(repoPanel, checkBoxModel) : new RepositoryNode(repoPanel, checkBoxModel, target != null); + if (!support.shouldRequestIncomingChangesForNotCheckedRepositories()) { + model.getCheckBoxModel().setChecked(myPreselectedRepositories.contains(repository)); + } pushTargetPanel.setFireOnChangeAction(new Runnable() { @Override public void run() { @@ -325,7 +328,7 @@ public class PushController implements Disposable { shouldBeSelected = hasCommits || target.hasSomethingToPush(); } else { - shouldBeSelected = (hasCommits || target.hasSomethingToPush()) && myPreselectedRepositories.contains(repository); + shouldBeSelected = (hasCommits || target.hasSomethingToPush()); } return shouldBeSelected; } From bfc8d2343b99c31f2225c58e779c2293e3168c25 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 26 Oct 2014 16:56:22 +0400 Subject: [PATCH 048/132] [vcs] cleanup: String.format() to ease reading --- .../vcs/roots/VcsRootProblemNotifier.java | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java index 3b8100978094..68efc20d985b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java @@ -133,18 +133,12 @@ public class VcsRootProblemNotifier { if (!invalidRoots.isEmpty()) { if (invalidRoots.size() == 1) { VcsRootError rootError = invalidRoots.iterator().next(); - description - .append("The directory " + - rootToDisplayableString.fun(rootError) + - " is registered as a " + - rootError.getVcsKey().getName() + - " root, " + - "but no " + - rootError.getVcsKey().getName() + - " repositories were found there."); + String vcsName = rootError.getVcsKey().getName(); + description.append(String.format("The directory %s is registered as a %s root, but no %s repositories were found there.", + rootToDisplayableString.fun(rootError), vcsName, vcsName)); } else { - description.append("The following directories are registered as Vcs roots, but they are not:
" + + description.append("The following directories are registered as VCS roots, but they are not:
" + StringUtil.join(invalidRoots, rootToDisplayableString, ", ")); } description.append("
"); @@ -153,16 +147,11 @@ public class VcsRootProblemNotifier { if (!unregisteredRoots.isEmpty()) { if (unregisteredRoots.size() == 1) { VcsRootError unregisteredRoot = unregisteredRoots.iterator().next(); - description - .append("The directory " + - rootToDisplayableString.fun(unregisteredRoot) + - " is under " + - unregisteredRoot.getVcsKey().getName() + - ", " + - "but is not registered in the Settings."); + description.append(String.format("The directory %s is under %s, but is not registered in the Settings.", + rootToDisplayableString.fun(unregisteredRoot), unregisteredRoot.getVcsKey().getName())); } else { - description.append("The following directories are roots of Vcs repositories, but they are not registered in the Settings:
" + + description.append("The following directories are roots of VCS repositories, but they are not registered in the Settings:
" + StringUtil.join(unregisteredRoots, rootToDisplayableString, ", ")); } description.append("
"); From 1dd4c35d1d88ec93e339d09d4c842ad845e3f98e Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 26 Oct 2014 17:07:52 +0400 Subject: [PATCH 049/132] [vcs] Don't notify about "less interesting" unregistered roots IDEA-87769 roots not under project dir; IDEA-98781 roots under ignored directories. But still show them in the Settings. --- .../vcs/roots/VcsRootProblemNotifier.java | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java index 68efc20d985b..c720834fa594 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java @@ -21,12 +21,16 @@ import com.intellij.notification.NotificationListener; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.VcsConfiguration; import com.intellij.openapi.vcs.VcsDirectoryMapping; import com.intellij.openapi.vcs.VcsNotifier; import com.intellij.openapi.vcs.VcsRootError; +import com.intellij.openapi.vcs.changes.ChangeListManager; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -35,6 +39,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.event.HyperlinkEvent; import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.Set; import static com.intellij.openapi.util.text.StringUtil.pluralize; @@ -46,12 +51,14 @@ import static com.intellij.openapi.util.text.StringUtil.pluralize; */ public class VcsRootProblemNotifier { - private final @NotNull Project myProject; - private final @NotNull VcsConfiguration mySettings; + @NotNull private final Project myProject; + @NotNull private final VcsConfiguration mySettings; + @NotNull private final ChangeListManager myChangeListManager; + @NotNull private final Set myReportedUnregisteredRoots = ContainerUtil.newHashSet(); - private @Nullable Notification myNotification; - private final @NotNull Object NOTIFICATION_LOCK = new Object(); + @Nullable private Notification myNotification; + @NotNull private final Object NOTIFICATION_LOCK = new Object(); public static VcsRootProblemNotifier getInstance(@NotNull Project project) { return new VcsRootProblemNotifier(project); @@ -60,6 +67,7 @@ public class VcsRootProblemNotifier { private VcsRootProblemNotifier(@NotNull Project project) { myProject = project; mySettings = VcsConfiguration.getInstance(myProject); + myChangeListManager = ChangeListManager.getInstance(project); } public void rescanAndNotifyIfNeeded() { @@ -76,16 +84,17 @@ public class VcsRootProblemNotifier { } Collection unregisteredRoots = getUnregisteredRoots(errors); + Collection important = getImportantMappings(unregisteredRoots); Collection invalidRoots = getInvalidRoots(errors); - String title = makeTitle(unregisteredRoots, invalidRoots); - String description = makeDescription(unregisteredRoots, invalidRoots); - - if (myReportedUnregisteredRoots.containsAll(unregisteredRoots) && invalidRoots.isEmpty()) { + if (invalidRoots.isEmpty() && (important.isEmpty() || myReportedUnregisteredRoots.containsAll(important))) { return; } myReportedUnregisteredRoots.addAll(unregisteredRoots); + String title = makeTitle(unregisteredRoots, invalidRoots); + String description = makeDescription(unregisteredRoots, invalidRoots); + synchronized (NOTIFICATION_LOCK) { expireNotification(); NotificationListener listener = new MyNotificationListener(myProject, mySettings); @@ -96,6 +105,26 @@ public class VcsRootProblemNotifier { } } + @NotNull + private List getImportantMappings(@NotNull Collection unregisteredRoots) { + return ContainerUtil.filter(unregisteredRoots, new Condition() { + @Override + public boolean value(VcsRootError error) { + String mapping = error.getMapping(); + return isUnderProjectDir(mapping) && !isIgnored(mapping); + } + }); + } + + private boolean isUnderProjectDir(@NotNull String mapping) { + return mapping.equals(VcsDirectoryMapping.PROJECT_CONSTANT) || FileUtil.isAncestor(myProject.getBasePath(), mapping, false); + } + + private boolean isIgnored(@NotNull String mapping) { + VirtualFile file = LocalFileSystem.getInstance().findFileByPath(mapping); + return file != null && myChangeListManager.isIgnoredFile(file); + } + private void expireNotification() { if (myNotification != null) { final Notification notification = myNotification; @@ -139,7 +168,7 @@ public class VcsRootProblemNotifier { } else { description.append("The following directories are registered as VCS roots, but they are not:
" + - StringUtil.join(invalidRoots, rootToDisplayableString, ", ")); + StringUtil.join(invalidRoots, rootToDisplayableString, "
")); } description.append("
"); } @@ -152,7 +181,7 @@ public class VcsRootProblemNotifier { } else { description.append("The following directories are roots of VCS repositories, but they are not registered in the Settings:
" + - StringUtil.join(unregisteredRoots, rootToDisplayableString, ", ")); + StringUtil.join(unregisteredRoots, rootToDisplayableString, "
")); } description.append("
"); } From 736e40851b33346c29d316f83656cf4d2be6f21c Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 26 Oct 2014 17:21:23 +0400 Subject: [PATCH 050/132] [vcs] IDEA-131859 Fix grammar --- .../openapi/vcs/configurable/VcsLimitHistoryConfigurable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsLimitHistoryConfigurable.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsLimitHistoryConfigurable.java index 07de0c4404e4..4bd2cb5c6aef 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsLimitHistoryConfigurable.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsLimitHistoryConfigurable.java @@ -33,7 +33,7 @@ public class VcsLimitHistoryConfigurable extends VcsCheckBoxWithSpinnerConfigura private final VcsConfiguration myConfiguration; public VcsLimitHistoryConfigurable(Project project) { - super(project, "Limit history by: ", "rows"); + super(project, "Limit history to: ", "rows"); myConfiguration = VcsConfiguration.getInstance(myProject); } From 2848a1695275fa386426b63c265ea9991424b5a6 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Sun, 26 Oct 2014 21:29:46 +0400 Subject: [PATCH 051/132] IDEA-130848 Push dialog initial selection & enabling policy * remember unselected roots and store in workspace.xml; * don't select and don't load excludedRoots; * always enable push button for mercurial; * load all repos for git exclude remembered; * wait until all or one repo loaded according to sync branch settings; * always allow push for git new branch; * preselect git repos only from project view and ignore current editor 'selection' --- .../com/intellij/dvcs/push/PushSettings.java | 61 ++++++++++ platform/dvcs-impl/src/META-INF/dvcs.xml | 3 + .../intellij/dvcs/push/PushController.java | 108 ++++++++++++++---- .../intellij/dvcs/push/ui/VcsPushDialog.java | 13 +++ .../src/git4idea/actions/GitPushAction.java | 9 +- .../org/zmlx/hg4idea/push/HgPushSupport.java | 8 +- .../src/org/zmlx/hg4idea/push/HgTarget.java | 4 +- 7 files changed, 173 insertions(+), 33 deletions(-) create mode 100644 platform/dvcs-api/src/com/intellij/dvcs/push/PushSettings.java diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/PushSettings.java b/platform/dvcs-api/src/com/intellij/dvcs/push/PushSettings.java new file mode 100644 index 000000000000..e1250c3dfeb4 --- /dev/null +++ b/platform/dvcs-api/src/com/intellij/dvcs/push/PushSettings.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.dvcs.push; + +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import com.intellij.openapi.components.StoragePathMacros; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.xmlb.annotations.AbstractCollection; +import com.intellij.util.xmlb.annotations.Tag; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Set; + +@State(name = "Push.Settings", storages = {@Storage(file = StoragePathMacros.WORKSPACE_FILE)}) +public class PushSettings implements PersistentStateComponent { + + private State myState = new State(); + + public static class State { + @Tag("excluded-roots") + @AbstractCollection(surroundWithTag = false, elementTag = "path") + public Set EXCLUDED_ROOTS = ContainerUtil.newHashSet(); + } + + @Nullable + @Override + public State getState() { + return myState; + } + + @Override + public void loadState(State state) { + myState = state; + } + + @NotNull + public Set getExcludedRepoRoots() { + return myState.EXCLUDED_ROOTS; + } + + public void saveExcludedRepoRoots(@NotNull Set roots) { + myState.EXCLUDED_ROOTS = roots; + } +} + diff --git a/platform/dvcs-impl/src/META-INF/dvcs.xml b/platform/dvcs-impl/src/META-INF/dvcs.xml index aa81616f24f6..dc8a45b5f9b1 100644 --- a/platform/dvcs-impl/src/META-INF/dvcs.xml +++ b/platform/dvcs-impl/src/META-INF/dvcs.xml @@ -8,5 +8,8 @@ + + + diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java index 92e0ae772f3b..7ddeb138425f 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java @@ -18,8 +18,8 @@ package com.intellij.dvcs.push; import com.intellij.dvcs.DvcsUtil; import com.intellij.dvcs.push.ui.*; import com.intellij.dvcs.repo.Repository; -import com.intellij.dvcs.repo.RepositoryManager; import com.intellij.openapi.Disposable; +import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; @@ -53,6 +53,8 @@ public class PushController implements Disposable { @NotNull private final List> myPushSupports; @NotNull private final PushLog myPushLog; @NotNull private final VcsPushDialog myDialog; + @NotNull private final PushSettings myExcludedSettings; + @NotNull private final Set myExcludedRepositoryRoots; private boolean mySingleRepoProject; private static final int DEFAULT_CHILDREN_PRESENTATION_NUMBER = 20; private final ExecutorService myExecutorService = Executors.newSingleThreadExecutor(); @@ -64,6 +66,8 @@ public class PushController implements Disposable { @NotNull VcsPushDialog dialog, @NotNull List preselectedRepositories) { myProject = project; + myExcludedSettings = ServiceManager.getService(project, PushSettings.class); + myExcludedRepositoryRoots = ContainerUtil.newHashSet(myExcludedSettings.getExcludedRepoRoots()); myPreselectedRepositories = preselectedRepositories; myPushSupports = getAffectedSupports(myProject); mySingleRepoProject = isSingleRepoProject(myPushSupports); @@ -125,10 +129,12 @@ public class PushController implements Disposable { Map others = ContainerUtil.newLinkedHashMap(); for (Map.Entry entry : myView2Model.entrySet()) { MyRepoModel model = entry.getValue(); - if (myPreselectedRepositories.contains(model.getRepository())) { + Repository repository = model.getRepository(); + if (preselectByUser(repository)) { priorityLoading.put(entry.getKey(), model); } - else if (model.getSupport().shouldRequestIncomingChangesForNotCheckedRepositories()) { + else if (model.getSupport().shouldRequestIncomingChangesForNotCheckedRepositories() && + !myExcludedRepositoryRoots.contains(repository.getRoot().getPath())) { others.put(entry.getKey(), model); } } @@ -176,9 +182,6 @@ public class PushController implements Disposable { final RepositoryNode repoNode = mySingleRepoProject ? new SingleRepositoryNode(repoPanel, checkBoxModel) : new RepositoryNode(repoPanel, checkBoxModel, target != null); - if (!support.shouldRequestIncomingChangesForNotCheckedRepositories()) { - model.getCheckBoxModel().setChecked(myPreselectedRepositories.contains(repository)); - } pushTargetPanel.setFireOnChangeAction(new Runnable() { @Override public void run() { @@ -191,6 +194,7 @@ public class PushController implements Disposable { @Override public void onTargetChanged(T newTarget) { repoNode.setChecked(true); + myExcludedRepositoryRoots.remove(model.getRepository().getRoot().getPath()); model.setTarget(newTarget); model.clearErrors(); loadCommits(model, repoNode, false); @@ -199,9 +203,14 @@ public class PushController implements Disposable { @Override public void onSelectionChanged(boolean isSelected) { myDialog.enableOkActions(isPushAllowed()); - if (isSelected && !model.hasCommitInfo() && !model.getSupport().shouldRequestIncomingChangesForNotCheckedRepositories()) { - //download incoming if was not loaded before and marked as selected - loadCommits(model, repoNode, false); + if (isSelected) { + boolean forceLoad = myExcludedRepositoryRoots.remove(model.getRepository().getRoot().getPath()); + if (!model.hasCommitInfo() && (forceLoad || !model.getSupport().shouldRequestIncomingChangesForNotCheckedRepositories())) { + loadCommits(model, repoNode, false); + } + } + else { + myExcludedRepositoryRoots.add(model.getRepository().getRoot().getPath()); } } }); @@ -238,9 +247,54 @@ public class PushController implements Disposable { public boolean isPushAllowed() { JTree tree = myPushLog.getTree(); - return !tree.isEditing() && !getSelectedRepoNode().isEmpty() && allNodesAreLoaded(myView2Model.keySet()); + return !tree.isEditing() && + ContainerUtil.exists(myPushSupports, new Condition>() { + @Override + public boolean value(PushSupport support) { + return isPushAllowed(support); + } + }); } + private boolean isPushAllowed(@NotNull PushSupport pushSupport) { + Collection nodes = getNodesForSupport(pushSupport); + if (pushSupport.getRepositoryManager().isSyncEnabled()) { + return hasSomethingToPush(nodes) || (hasCheckedNode(nodes) && allNodesAreLoaded(nodes)); + } + return hasSomethingToPush(nodes) || (hasCheckedNode(nodes)); + } + + private boolean hasSomethingToPush(Collection nodes) { + return ContainerUtil.exists(nodes, new Condition() { + @Override + public boolean value(@NotNull RepositoryNode node) { + PushTarget target = myView2Model.get(node).getTarget(); + //if node is selected target should not be null + return (node.isChecked() || node.isLoading()) && target != null && target.hasSomethingToPush(); + } + }); + } + + private static boolean hasCheckedNode(@NotNull Collection nodes) { + return ContainerUtil.exists(nodes, new Condition() { + @Override + public boolean value(@NotNull RepositoryNode node) { + return node.isChecked(); + } + }); + } + + @NotNull + private Collection getNodesForSupport(final PushSupport support) { + return ContainerUtil.mapNotNull(myView2Model.entrySet(), new Function, RepositoryNode>() { + @Override + public RepositoryNode fun(Map.Entry entry) { + return support.equals(entry.getValue().getSupport()) ? entry.getKey() : null; + } + }); + } + + private static boolean allNodesAreLoaded(@NotNull Collection nodes) { return !ContainerUtil.exists(nodes, new Condition() { @Override @@ -297,8 +351,8 @@ public class PushController implements Disposable { } else { List commits = outgoing.getCommits(); - shouldBeSelected = shouldSelectInitially(target, repository, model.getSupport().getRepositoryManager(), !commits.isEmpty()); model.setLoadedCommits(commits); + shouldBeSelected = shouldSelect(model); myPushLog.setChildren(node, getPresentationForCommits(PushController.this.myProject, model.getLoadedCommits(), model.getNumberOfShownCommits())); @@ -318,19 +372,24 @@ public class PushController implements Disposable { node.startLoading(myPushLog.getTree(), myExecutorService.submit(task, result)); } - private boolean shouldSelectInitially(@NotNull PushTarget target, @NotNull Repository repository, - @NotNull RepositoryManager repositoryManager, boolean hasCommits) { - boolean shouldBeSelected; - if (mySingleRepoProject) { - shouldBeSelected = true; - } - else if (repositoryManager.isSyncEnabled()) { - shouldBeSelected = hasCommits || target.hasSomethingToPush(); - } - else { - shouldBeSelected = (hasCommits || target.hasSomethingToPush()); - } - return shouldBeSelected; + private boolean shouldSelect(@NotNull MyRepoModel model) { + if (mySingleRepoProject) return true; + Repository repository = model.getRepository(); + return hasCommitsToPush(model) && (preselectByUser(repository) || notExcludedByUser(repository)); + } + + private boolean notExcludedByUser(@NotNull Repository repository) { + return !myExcludedRepositoryRoots.contains(repository.getRoot().getPath()); + } + + private boolean preselectByUser(@NotNull Repository repository) { + return myPreselectedRepositories.contains(repository); + } + + private static boolean hasCommitsToPush(@NotNull MyRepoModel model) { + PushTarget target = model.getTarget(); + assert target != null; + return (!model.getLoadedCommits().isEmpty() || target.hasSomethingToPush()); } public PushLog getPushPanelLog() { @@ -341,6 +400,7 @@ public class PushController implements Disposable { Task.Backgroundable task = new Task.Backgroundable(myProject, "Pushing...", false) { @Override public void run(@NotNull ProgressIndicator indicator) { + myExcludedSettings.saveExcludedRepoRoots(myExcludedRepositoryRoots); for (PushSupport support : myPushSupports) { doPush(support, force); } diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java index a86d9368e7d2..03fdca55c2c2 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java @@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.OptionAction; +import com.intellij.openapi.ui.ValidationInfo; import net.miginfocom.swing.MigLayout; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -81,6 +82,18 @@ public class VcsPushDialog extends DialogWrapper { return ID; } + @Nullable + @Override + protected ValidationInfo doValidate() { + enableOkActions(myController.isPushAllowed()); + return null; + } + + @Override + protected boolean postponeValidation() { + return false; + } + @Override @NotNull protected Action[] createActions() { diff --git a/plugins/git4idea/src/git4idea/actions/GitPushAction.java b/plugins/git4idea/src/git4idea/actions/GitPushAction.java index 04e139fa8934..8340de21c560 100644 --- a/plugins/git4idea/src/git4idea/actions/GitPushAction.java +++ b/plugins/git4idea/src/git4idea/actions/GitPushAction.java @@ -24,7 +24,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; import git4idea.GitUtil; -import git4idea.branch.GitBranchUtil; import git4idea.repo.GitRepository; import git4idea.repo.GitRepositoryManager; import org.jetbrains.annotations.NotNull; @@ -38,15 +37,15 @@ public class GitPushAction extends DumbAwareAction { @Override public void actionPerformed(@NotNull AnActionEvent e) { Project project = e.getRequiredData(CommonDataKeys.PROJECT); - Collection repositories = collectRepositories(project, e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY)); + Collection repositories = e.getData(CommonDataKeys.EDITOR) != null + ? ContainerUtil.emptyList() + : collectRepositories(project, e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY)); new VcsPushDialog(project, RepositoryUtil.sortRepositories(repositories)).show(); } @NotNull private static Collection collectRepositories(@NotNull Project project, @Nullable VirtualFile[] files) { - if (files == null) { - return Collections.singletonList(GitBranchUtil.getCurrentRepository(project)); - } + if (files == null) return Collections.emptyList(); GitRepositoryManager manager = GitUtil.getRepositoryManager(project); Collection repositories = ContainerUtil.newHashSet(); for (VirtualFile file : files) { diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java index b05cde7fbd9f..e5539ef7c57e 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java @@ -15,14 +15,15 @@ */ package org.zmlx.hg4idea.push; +import com.intellij.dvcs.branch.DvcsSyncSettings; import com.intellij.dvcs.push.*; -import com.intellij.dvcs.repo.Repository; import com.intellij.dvcs.repo.RepositoryManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.zmlx.hg4idea.HgProjectSettings; import org.zmlx.hg4idea.HgVcs; import org.zmlx.hg4idea.repo.HgRepository; import org.zmlx.hg4idea.util.HgUtil; @@ -31,10 +32,12 @@ public class HgPushSupport extends PushSupport Date: Sun, 26 Oct 2014 22:18:09 +0300 Subject: [PATCH 052/132] IDEABKL-6086 Distraction Free mode --- .../ToggleDistractionFreeModeAction.java | 67 ++++++++++++++++++- .../actions/TogglePresentationModeAction.java | 4 +- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ToggleDistractionFreeModeAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ToggleDistractionFreeModeAction.java index 4afd28d9f893..196d36ea5a6b 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ToggleDistractionFreeModeAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ToggleDistractionFreeModeAction.java @@ -15,18 +15,33 @@ */ package com.intellij.ide.actions; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings; +import com.intellij.ide.ui.LafManager; +import com.intellij.ide.ui.UISettings; +import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; +import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.registry.RegistryValue; import org.jetbrains.annotations.NotNull; +import javax.swing.*; + public class ToggleDistractionFreeModeAction extends AnAction implements DumbAware { private static final String key = "editor.distraction.free.mode"; + @Override public void update(@NotNull AnActionEvent e) { + if (e.getProject() == null) { + e.getPresentation().setEnabled(false); + return; + } RegistryValue value = Registry.get(key); boolean selected = value.asBoolean(); e.getPresentation().setText((selected ? "Exit" : "Enter") + " Distraction Free Mode"); @@ -34,8 +49,58 @@ public class ToggleDistractionFreeModeAction extends AnAction implements DumbAwa @Override public void actionPerformed(@NotNull AnActionEvent e) { + Project project = e.getProject(); RegistryValue value = Registry.get(key); - value.setValue(!value.asBoolean()); + boolean v = !value.asBoolean(); + value.setValue(v); + + if (project == null) return; + + PropertiesComponent p = PropertiesComponent.getInstance(project); + UISettings ui = UISettings.getInstance(); + EditorSettingsExternalizable.OptionSet eo = EditorSettingsExternalizable.getInstance().getOptions(); + DaemonCodeAnalyzerSettings ds = DaemonCodeAnalyzerSettings.getInstance(); + + String before = "BEFORE.DISTRACTION.MODE."; + if (v) { + p.setValue(before + "SHOW_STATUS_BAR", String.valueOf(ui.SHOW_STATUS_BAR)); ui.SHOW_STATUS_BAR = false; + p.setValue(before + "SHOW_MAIN_TOOLBAR", String.valueOf(ui.SHOW_MAIN_TOOLBAR)); ui.SHOW_MAIN_TOOLBAR = false; + p.setValue(before + "SHOW_NAVIGATION_BAR", String.valueOf(ui.SHOW_NAVIGATION_BAR)); ui.SHOW_NAVIGATION_BAR = false; + p.setValue(before + "HIDE_TOOL_STRIPES", String.valueOf(ui.HIDE_TOOL_STRIPES)); ui.HIDE_TOOL_STRIPES = true; + p.setValue(before + "EDITOR_TAB_PLACEMENT", String.valueOf(ui.EDITOR_TAB_PLACEMENT)); ui.EDITOR_TAB_PLACEMENT = UISettings.TABS_NONE; + + p.setValue(before + "IS_FOLDING_OUTLINE_SHOWN", String.valueOf(eo.IS_FOLDING_OUTLINE_SHOWN)); eo.IS_FOLDING_OUTLINE_SHOWN = false; + p.setValue(before + "IS_WHITESPACES_SHOWN", String.valueOf(eo.IS_WHITESPACES_SHOWN)); eo.IS_WHITESPACES_SHOWN = false; + p.setValue(before + "ARE_LINE_NUMBERS_SHOWN", String.valueOf(eo.ARE_LINE_NUMBERS_SHOWN)); eo.ARE_LINE_NUMBERS_SHOWN = false; + //p.setValue(before + "IS_RIGHT_MARGIN_SHOWN", String.valueOf(eo.IS_RIGHT_MARGIN_SHOWN)); eo.IS_RIGHT_MARGIN_SHOWN = false; + p.setValue(before + "IS_INDENT_GUIDES_SHOWN", String.valueOf(eo.IS_INDENT_GUIDES_SHOWN)); eo.IS_INDENT_GUIDES_SHOWN = false; + + p.setValue(before + "SHOW_METHOD_SEPARATORS", String.valueOf(ds.SHOW_METHOD_SEPARATORS)); ds.SHOW_METHOD_SEPARATORS = false; + + TogglePresentationModeAction.storeToolWindows(project); + } + else { + ui.SHOW_STATUS_BAR = p.getBoolean(before + "SHOW_STATUS_BAR", true); + ui.SHOW_MAIN_TOOLBAR = p.getBoolean(before + "SHOW_MAIN_TOOLBAR", true); + ui.SHOW_NAVIGATION_BAR = p.getBoolean(before + "SHOW_NAVIGATION_BAR", true); + ui.HIDE_TOOL_STRIPES = p.getBoolean(before + "HIDE_TOOL_STRIPES", true); + ui.EDITOR_TAB_PLACEMENT = p.getOrInitInt(before + "EDITOR_TAB_PLACEMENT", SwingConstants.TOP); + + eo.IS_FOLDING_OUTLINE_SHOWN = p.getBoolean(before + "IS_FOLDING_OUTLINE_SHOWN", true); + eo.IS_WHITESPACES_SHOWN = p.getBoolean(before + "IS_WHITESPACES_SHOWN", false); + eo.ARE_LINE_NUMBERS_SHOWN = p.getBoolean(before + "ARE_LINE_NUMBERS_SHOWN", false); + //eo.IS_RIGHT_MARGIN_SHOWN = p.getBoolean(before + "IS_RIGHT_MARGIN_SHOWN", true); + eo.IS_INDENT_GUIDES_SHOWN = p.getBoolean(before + "IS_INDENT_GUIDES_SHOWN", false); + + ds.SHOW_METHOD_SEPARATORS = p.getBoolean(before + "SHOW_METHOD_SEPARATORS", false); + + TogglePresentationModeAction.restoreToolWindows(project, true, false); + } + + UISettings.getInstance().fireUISettingsChanged(); + LafManager.getInstance().updateUI(); + EditorUtil.reinitSettings(); + DaemonCodeAnalyzer.getInstance(project).settingsChanged(); EditorFactory.getInstance().refreshAllEditors(); } } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/TogglePresentationModeAction.java b/platform/platform-impl/src/com/intellij/ide/actions/TogglePresentationModeAction.java index 78b84652563c..16dae889b101 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/TogglePresentationModeAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/TogglePresentationModeAction.java @@ -180,7 +180,7 @@ public class TogglePresentationModeAction extends AnAction implements DumbAware return hasVisible; } - private static boolean storeToolWindows(@Nullable Project project) { + static boolean storeToolWindows(@Nullable Project project) { if (project == null) return false; ToolWindowManagerEx manager = ToolWindowManagerEx.getInstanceEx(project); @@ -195,7 +195,7 @@ public class TogglePresentationModeAction extends AnAction implements DumbAware return hasVisible; } - private static void restoreToolWindows(Project project, boolean needsRestore, boolean inPresentation) { + static void restoreToolWindows(Project project, boolean needsRestore, boolean inPresentation) { if (project == null || !needsRestore) return; ToolWindowManagerEx manager = ToolWindowManagerEx.getInstanceEx(project); DesktopLayout restoreLayout = manager.getLayoutToRestoreLater(); From 06d844e145413f523cccf7f53fa71c78b0ab6f3c Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sun, 26 Oct 2014 20:20:31 +0100 Subject: [PATCH 053/132] catch AbstractMethodError for old api clients --- .../src/org/intellij/lang/regexp/RegExpLanguageHosts.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java index ec2b9192c2d5..c1cff8aff61e 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java @@ -79,7 +79,12 @@ public final class RegExpLanguageHosts extends ClassExtension Date: Sun, 26 Oct 2014 23:02:56 +0300 Subject: [PATCH 054/132] fixed EDU-233, switched to flat model in offset listener --- .../coursecreator/CCDocumentListener.java | 89 +++++++++++++------ .../CCEditorFactoryListener.java | 6 -- .../actions/CCAddTaskWindow.java | 1 + .../actions/CCCreateCourseArchive.java | 10 +-- .../coursecreator/format/TaskFile.java | 58 +++--------- .../coursecreator/format/TaskWindow.java | 9 +- .../python/edu/StudyDocumentListener.java | 72 ++++++++++----- .../jetbrains/python/edu/course/TaskFile.java | 44 --------- 8 files changed, 132 insertions(+), 157 deletions(-) diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCDocumentListener.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCDocumentListener.java index 3573216e9efa..b1917292df32 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCDocumentListener.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCDocumentListener.java @@ -1,24 +1,23 @@ package org.jetbrains.plugins.coursecreator; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.LogicalPosition; import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.editor.impl.event.DocumentEventImpl; import org.jetbrains.plugins.coursecreator.format.TaskFile; import org.jetbrains.plugins.coursecreator.format.TaskWindow; +import java.util.ArrayList; +import java.util.List; + /** - * author: liana - * data: 7/16/14. * Listens changes in study files and updates * coordinates of all the windows in current task file */ public abstract class CCDocumentListener extends DocumentAdapter { private final TaskFile myTaskFile; - private int myOldLine; - private int myOldLineStartOffset; - private TaskWindow myTaskWindow; + private List myTaskWindows = new ArrayList(); + public CCDocumentListener(TaskFile taskFile) { myTaskFile = taskFile; @@ -29,39 +28,71 @@ public abstract class CCDocumentListener extends DocumentAdapter { // with fragments containing "\n" @Override public void beforeDocumentChange(DocumentEvent e) { - int offset = e.getOffset(); - int oldEnd = offset + e.getOldLength(); Document document = e.getDocument(); - myOldLine = document.getLineNumber(oldEnd); - myOldLineStartOffset = document.getLineStartOffset(myOldLine); - int line = document.getLineNumber(offset); - int offsetInLine = offset - document.getLineStartOffset(line); - LogicalPosition pos = new LogicalPosition(line, offsetInLine); - myTaskWindow = myTaskFile.getTaskWindow(document, pos); + myTaskWindows.clear(); + for (TaskWindow taskWindow : myTaskFile.getTaskWindows()) { + int twStart = taskWindow.getRealStartOffset(document); + int length = useLength() ? taskWindow.getLength() : taskWindow.getReplacementLength(); + int twEnd = twStart + length; + myTaskWindows.add(new TaskWindowWrapper(taskWindow, twStart, twEnd)); + } } @Override public void documentChanged(DocumentEvent e) { if (e instanceof DocumentEventImpl) { - DocumentEventImpl event = (DocumentEventImpl)e; - Document document = e.getDocument(); - int offset = e.getOffset(); - int change = event.getNewLength() - event.getOldLength(); - if (myTaskWindow != null) { - updateTaskWindowLength(e.getNewFragment(), myTaskWindow, change); + DocumentEventImpl event = (DocumentEventImpl)e; + Document document = e.getDocument(); + int offset = e.getOffset(); + int change = event.getNewLength() - event.getOldLength(); + for (TaskWindowWrapper taskWindowWrapper : myTaskWindows) { + int twStart = taskWindowWrapper.getTwStart(); + if (twStart > offset) { + twStart += change; + } + int twEnd = taskWindowWrapper.getTwEnd(); + if (twEnd >= offset) { + twEnd += change; + } + TaskWindow taskWindow = taskWindowWrapper.getTaskWindow(); + int line = document.getLineNumber(twStart); + int start = twStart - document.getLineStartOffset(line); + int length = twEnd - twStart; + taskWindow.setLine(line); + taskWindow.setStart(start); + if (useLength()) { + taskWindow.setLength(length); + } else { + taskWindow.setReplacementLength(length); } - int newEnd = offset + event.getNewLength(); - int newLine = document.getLineNumber(newEnd); - int lineChange = newLine - myOldLine; - myTaskFile.incrementLines(myOldLine + 1, lineChange); - int newEndOffsetInLine = offset + e.getNewLength() - document.getLineStartOffset(newLine); - int oldEndOffsetInLine = offset + e.getOldLength() - myOldLineStartOffset; - myTaskFile.updateLine(lineChange, myOldLine, newEndOffsetInLine, oldEndOffsetInLine, useLength()); } + } } - protected abstract void updateTaskWindowLength(CharSequence fragment, TaskWindow taskWindow, int change); - protected abstract boolean useLength(); + + private static class TaskWindowWrapper { + public TaskWindow myTaskWindow; + public int myTwStart; + public int myTwEnd; + + public TaskWindowWrapper(TaskWindow taskWindow, int twStart, int twEnd) { + myTaskWindow = taskWindow; + myTwStart = twStart; + myTwEnd = twEnd; + } + + public int getTwStart() { + return myTwStart; + } + + public int getTwEnd() { + return myTwEnd; + } + + public TaskWindow getTaskWindow() { + return myTaskWindow; + } + } } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCEditorFactoryListener.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCEditorFactoryListener.java index 74afc795b60a..24688c4b2709 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCEditorFactoryListener.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCEditorFactoryListener.java @@ -72,12 +72,6 @@ public class CCEditorFactoryListener implements EditorFactoryListener { super(taskFile); } - @Override - protected void updateTaskWindowLength(CharSequence fragment, TaskWindow taskWindow, int change) { - int newLength = taskWindow.getReplacementLength() + change; - taskWindow.setReplacementLength(newLength <= 0 ? 0 : newLength); - } - @Override protected boolean useLength() { return false; diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java index 951a5e85582b..e423da553d1b 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java @@ -85,6 +85,7 @@ public class CCAddTaskWindow extends DumbAwareAction { } int index = taskFile.getTaskWindows().size() + 1; taskFile.addTaskWindow(taskWindow, index); + taskFile.sortTaskWindows(); taskWindow.drawHighlighter(editor, false); taskWindow.createGuardedBlocks(editor); } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateCourseArchive.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateCourseArchive.java index c201e4ddaee4..b5a0292db684 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateCourseArchive.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateCourseArchive.java @@ -134,6 +134,9 @@ public class CCCreateCourseArchive extends DumbAwareAction { final TaskFile taskFile = taskFiles.getValue(); TaskFile taskFileSaved = new TaskFile(); taskFile.copy(taskFileSaved); + for (TaskWindow taskWindow : taskFile.getTaskWindows()) { + taskWindow.setLength(taskWindow.getReplacementLength()); + } CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override public void run() { @@ -168,7 +171,7 @@ public class CCCreateCourseArchive extends DumbAwareAction { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { - document.replaceString(offset, offset + taskWindow.getReplacementLength(), taskText); + document.replaceString(offset, offset + taskWindow.getLength(), taskText); FileDocumentManager.getInstance().saveDocument(document); } }); @@ -254,11 +257,6 @@ public class CCCreateCourseArchive extends DumbAwareAction { super(taskFile); } - @Override - protected void updateTaskWindowLength(CharSequence fragment, TaskWindow taskWindow, int change) { - //we don't need to update task window length - } - @Override protected boolean useLength() { return true; diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskFile.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskFile.java index c48a4f41d7e1..9fb10eaa179a 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskFile.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskFile.java @@ -6,9 +6,9 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.LogicalPosition; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.coursecreator.CCProjectService; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class TaskFile { @@ -57,52 +57,6 @@ public class TaskFile { return null; } - /** - * Updates task window lines - * - * @param startLine lines greater than this line and including this line will be updated - * @param change change to be added to line numbers - */ - public void incrementLines(int startLine, int change) { - for (TaskWindow taskTaskWindow : task_windows) { - if (taskTaskWindow.getLine() >= startLine) { - taskTaskWindow.setLine(taskTaskWindow.getLine() + change); - } - } - } - - /** - * Updates windows in specific line - * - * @param lineChange change in line number - * @param line line to be updated - * @param newEndOffsetInLine distance from line start to end of inserted fragment - * @param oldEndOffsetInLine distance from line start to end of changed fragment - */ - public void updateLine(int lineChange, int line, int newEndOffsetInLine, int oldEndOffsetInLine, boolean useLength) { - for (TaskWindow w : task_windows) { - if ((w.getLine() == line) && (w.getStart() > oldEndOffsetInLine)) { - int distance = w.getStart() - oldEndOffsetInLine; - boolean coveredByPrevTW = false; - int prevIndex = w.getIndex() - 1; - if (CCProjectService.indexIsValid(prevIndex, task_windows)) { - TaskWindow prevTW = task_windows.get(prevIndex - 1); - if (prevTW.getLine() == line) { - int prevLength = useLength ? prevTW.getLength() : prevTW.getReplacementLength(); - int endOffset = prevTW.getStart() + prevLength; - if (endOffset >= newEndOffsetInLine) { - coveredByPrevTW = true; - } - } - } - if (lineChange != 0 || newEndOffsetInLine <= w.getStart() || coveredByPrevTW) { - w.setStart(distance + newEndOffsetInLine); - w.setLine(line + lineChange); - } - } - } - } - public void copy(@NotNull final TaskFile target) { target.setIndex(myIndex); for (TaskWindow taskWindow : task_windows) { @@ -110,6 +64,7 @@ public class TaskFile { taskWindow.getLength(), ""); target.getTaskWindows().add(savedWindow); savedWindow.setIndex(taskWindow.getIndex()); + savedWindow.setReplacementLength(taskWindow.getReplacementLength()); } } @@ -121,6 +76,8 @@ public class TaskFile { } taskWindowUpdated.setLine(taskWindow.getLine()); taskWindowUpdated.setStart(taskWindow.getStart()); + taskWindowUpdated.setReplacementLength(taskWindow.getReplacementLength()); + taskWindowUpdated.setLength(taskWindow.getLength()); } } @@ -142,4 +99,11 @@ public class TaskFile { taskWindow.createGuardedBlocks(editor); } } + + public void sortTaskWindows() { + Collections.sort(task_windows); + for (int i = 0; i < task_windows.size(); i++) { + task_windows.get(i).setIndex(i + 1); + } + } } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskWindow.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskWindow.java index dc7551929e30..385aaeddf26e 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskWindow.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskWindow.java @@ -20,7 +20,7 @@ import org.jetbrains.plugins.coursecreator.CCProjectService; import java.io.File; import java.util.List; -public class TaskWindow implements Comparable{ +public class TaskWindow implements Comparable { @Expose public int line; @Expose public int start; @@ -120,8 +120,7 @@ public class TaskWindow implements Comparable{ } @Override - public int compareTo(Object o) { - TaskWindow taskWindow = (TaskWindow)o; + public int compareTo(@NotNull TaskWindow taskWindow) { int lineDiff = line - taskWindow.line; if (lineDiff == 0) { return start - taskWindow.start; @@ -154,4 +153,8 @@ public class TaskWindow implements Comparable{ .addRangeHighlighter(start, end, HighlighterLayer.LAST + 1, null, HighlighterTargetArea.EXACT_RANGE); blocks.add(rh); } + + public void setLength(int length) { + this.length = length; + } } \ No newline at end of file diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDocumentListener.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDocumentListener.java index 8955032aa408..848becfae1b1 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDocumentListener.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDocumentListener.java @@ -2,22 +2,22 @@ package com.jetbrains.python.edu; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.LogicalPosition; import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.editor.impl.event.DocumentEventImpl; import com.jetbrains.python.edu.course.TaskFile; import com.jetbrains.python.edu.course.TaskWindow; +import java.util.ArrayList; +import java.util.List; + /** * Listens changes in study files and updates * coordinates of all the windows in current task file */ public class StudyDocumentListener extends DocumentAdapter { private final TaskFile myTaskFile; - private int myOldLine; - private int myOldLineStartOffset; - private TaskWindow myTaskWindow; + private List myTaskWindows = new ArrayList(); public StudyDocumentListener(TaskFile taskFile) { myTaskFile = taskFile; @@ -28,15 +28,13 @@ public class StudyDocumentListener extends DocumentAdapter { // with fragments containing "\n" @Override public void beforeDocumentChange(DocumentEvent e) { - int offset = e.getOffset(); - int oldEnd = offset + e.getOldLength(); Document document = e.getDocument(); - myOldLine = document.getLineNumber(oldEnd); - myOldLineStartOffset = document.getLineStartOffset(myOldLine); - int line = document.getLineNumber(offset); - int offsetInLine = offset - document.getLineStartOffset(line); - LogicalPosition pos = new LogicalPosition(line, offsetInLine); - myTaskWindow = myTaskFile.getTaskWindow(document, pos); + myTaskWindows.clear(); + for (TaskWindow taskWindow : myTaskFile.getTaskWindows()) { + int twStart = taskWindow.getRealStartOffset(document); + int twEnd = twStart + taskWindow.getLength(); + myTaskWindows.add(new TaskWindowWrapper(taskWindow, twStart, twEnd)); + } } @Override @@ -46,17 +44,47 @@ public class StudyDocumentListener extends DocumentAdapter { Document document = e.getDocument(); int offset = e.getOffset(); int change = event.getNewLength() - event.getOldLength(); - if (myTaskWindow != null) { - int newLength = myTaskWindow.getLength() + change; - myTaskWindow.setLength(newLength <= 0 ? 0 : newLength); + for (TaskWindowWrapper taskWindowWrapper : myTaskWindows) { + int twStart = taskWindowWrapper.getTwStart(); + if (twStart > offset) { + twStart += change; + } + int twEnd = taskWindowWrapper.getTwEnd(); + if (twEnd >= offset) { + twEnd += change; + } + TaskWindow taskWindow = taskWindowWrapper.getTaskWindow(); + int line = document.getLineNumber(twStart); + int start = twStart - document.getLineStartOffset(line); + int length = twEnd - twStart; + taskWindow.setLine(line); + taskWindow.setStart(start); + taskWindow.setLength(length); } - int newEnd = offset + event.getNewLength(); - int newLine = document.getLineNumber(newEnd); - int lineChange = newLine - myOldLine; - myTaskFile.incrementLines(myOldLine + 1, lineChange); - int newEndOffsetInLine = offset + e.getNewLength() - document.getLineStartOffset(newLine); - int oldEndOffsetInLine = offset + e.getOldLength() - myOldLineStartOffset; - myTaskFile.updateLine(lineChange, myOldLine, newEndOffsetInLine, oldEndOffsetInLine); + } + } + + private static class TaskWindowWrapper { + public TaskWindow myTaskWindow; + public int myTwStart; + public int myTwEnd; + + public TaskWindowWrapper(TaskWindow taskWindow, int twStart, int twEnd) { + myTaskWindow = taskWindow; + myTwStart = twStart; + myTwEnd = twEnd; + } + + public int getTwStart() { + return myTwStart; + } + + public int getTwEnd() { + return myTwEnd; + } + + public TaskWindow getTaskWindow() { + return myTaskWindow; } } } diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java b/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java index aaaef375a093..e9281e957855 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java @@ -127,20 +127,6 @@ public class TaskFile implements Stateful { return null; } - /** - * Updates task window lines - * - * @param startLine lines greater than this line and including this line will be updated - * @param change change to be added to line numbers - */ - public void incrementLines(int startLine, int change) { - for (TaskWindow taskTaskWindow : taskWindows) { - if (taskTaskWindow.getLine() >= startLine) { - taskTaskWindow.setLine(taskTaskWindow.getLine() + change); - } - } - } - /** * Initializes state of task file * @@ -165,36 +151,6 @@ public class TaskFile implements Stateful { myIndex = index; } - /** - * Updates windows in specific line - * - * @param lineChange change in line number - * @param line line to be updated - * @param newEndOffsetInLine distance from line start to end of inserted fragment - * @param oldEndOffsetInLine distance from line start to end of changed fragment - */ - public void updateLine(int lineChange, int line, int newEndOffsetInLine, int oldEndOffsetInLine) { - for (TaskWindow w : taskWindows) { - if ((w.getLine() == line) && (w.getStart() > oldEndOffsetInLine)) { - int distance = w.getStart() - oldEndOffsetInLine; - boolean coveredByPrevTW = false; - int prevIndex = w.getIndex() - 1; - if (StudyUtils.indexIsValid(prevIndex, taskWindows)) { - TaskWindow prevTW = taskWindows.get(prevIndex); - if (prevTW.getLine() == line) { - int endOffset = prevTW.getStart() + prevTW.getLength(); - if (endOffset >= newEndOffsetInLine) { - coveredByPrevTW = true; - } - } - } - if (lineChange != 0 || newEndOffsetInLine <= w.getStart() || coveredByPrevTW) { - w.setStart(distance + newEndOffsetInLine); - w.setLine(line + lineChange); - } - } - } - } public static void copy(@NotNull final TaskFile source, @NotNull final TaskFile target) { List sourceTaskWindows = source.getTaskWindows(); From f56e798a5d8a66cae2efbbfdccb33ffa5b8493c8 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Mon, 27 Oct 2014 00:59:31 +0400 Subject: [PATCH 055/132] load all roots for git and for sync hg --- .../dvcs-impl/src/com/intellij/dvcs/push/PushController.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java index 7ddeb138425f..e4a8c1a64826 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java @@ -133,8 +133,7 @@ public class PushController implements Disposable { if (preselectByUser(repository)) { priorityLoading.put(entry.getKey(), model); } - else if (model.getSupport().shouldRequestIncomingChangesForNotCheckedRepositories() && - !myExcludedRepositoryRoots.contains(repository.getRoot().getPath())) { + else if (model.getSupport().shouldRequestIncomingChangesForNotCheckedRepositories()) { others.put(entry.getKey(), model); } } From cc6cd053dfbfca30bfa452dd0b173c143c0b5190 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Sat, 25 Oct 2014 17:12:32 +0200 Subject: [PATCH 056/132] don't evaluate arrays on EDT when debugging remotely (cherry picked from commit ed2a20feeec3dad31e25d5e027940cf85f2b065f) --- .../impl/evaluate/XDebuggerEditorLinePainter.java | 2 +- .../xdebugger/impl/ui/tree/XDebuggerTree.java | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java index 1f8d636d1fab..cce3eac58098 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java @@ -79,7 +79,7 @@ public class XDebuggerEditorLinePainter extends EditorLinePainter { final XValuePresentation presentation = value.getValuePresentation(); if (presentation == null) continue; try { - if (presentation instanceof XValueCompactPresentation) { + if (presentation instanceof XValueCompactPresentation && !value.getTree().isUnderRemoteDebug()) { ((XValueCompactPresentation)presentation).renderValue(renderer, value); } else { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java index 91de065a12d8..feb62d3c03df 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java @@ -15,6 +15,9 @@ */ package com.intellij.xdebugger.impl.ui.tree; +import com.intellij.execution.configurations.RemoteRunProfile; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.ide.DataManager; import com.intellij.ide.dnd.aware.DnDAwareTree; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; @@ -226,6 +229,15 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa private void updateEditor() { myAlarm.cancelAndRequest(); } + + public boolean isUnderRemoteDebug() { + DataContext context = DataManager.getInstance().getDataContext(this); + ExecutionEnvironment env = LangDataKeys.EXECUTION_ENVIRONMENT.getData(context); + if (env != null && env.getRunProfile() instanceof RemoteRunProfile) { + return true; + } + return false; + } private boolean expandIfEllipsis() { MessageTreeNode[] treeNodes = getSelectedNodes(MessageTreeNode.class, null); From b68fe530c1b09e231ce4546697dd06a50d5aef14 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Sat, 25 Oct 2014 17:16:54 +0200 Subject: [PATCH 057/132] remove code duplicate (use isUnderRemoteDebug directly) (cherry picked from commit 43b8a662654406422ad01743841324736c5d7214) --- .../impl/ui/tree/nodes/XValueContainerNode.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java index 2f9d60d11785..6c175f52d6a6 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java @@ -15,12 +15,9 @@ */ package com.intellij.xdebugger.impl.ui.tree.nodes; -import com.intellij.execution.configurations.RemoteRunProfile; import com.intellij.execution.configurations.RunConfiguration; import com.intellij.execution.configurations.RunProfile; -import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.ide.DataManager; -import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.util.registry.Registry; import com.intellij.ui.SimpleTextAttributes; @@ -121,13 +118,11 @@ public abstract class XValueContainerNode Date: Mon, 27 Oct 2014 08:44:36 +0100 Subject: [PATCH 058/132] Platform: extensible welcome wizard: * themes page can be customized * additionas UI setting supported --- .../com/intellij/ide/WelcomeWizardUtil.java | 83 ++++++++++++ .../src/com/intellij/ide/ui/UISettings.java | 4 + .../CustomizeKeyboardSchemeStepPanel.java | 6 +- .../customize/CustomizeUIThemeStepPanel.java | 121 ++++++++++-------- .../intellij/ide/customize/PluginGroups.java | 4 +- .../intellij/ide/ui/laf/LafManagerImpl.java | 10 +- .../src/com/intellij/idea/StartupUtil.java | 41 +----- .../colors/impl/EditorColorsManagerImpl.java | 10 +- .../openapi/keymap/impl/DefaultKeymap.java | 3 +- .../keymap/impl/KeymapManagerImpl.java | 5 +- 10 files changed, 182 insertions(+), 105 deletions(-) create mode 100644 platform/core-api/src/com/intellij/ide/WelcomeWizardUtil.java diff --git a/platform/core-api/src/com/intellij/ide/WelcomeWizardUtil.java b/platform/core-api/src/com/intellij/ide/WelcomeWizardUtil.java new file mode 100644 index 000000000000..dabb6ac530ea --- /dev/null +++ b/platform/core-api/src/com/intellij/ide/WelcomeWizardUtil.java @@ -0,0 +1,83 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide; + +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public class WelcomeWizardUtil { + private static volatile String ourDefaultLAF; + private static volatile String ourWizardLAF; + private static volatile String ourWizardMacKeymap; + private static volatile String ourWizardEditorScheme; + private static volatile Boolean ourAutoScrollToSource; + private static volatile Set ourFeaturedPluginsToInstall = new HashSet(); + + public static void setDefaultLAF(String laf) { + ourDefaultLAF = laf; + } + + public static String getDefaultLAF() { + return ourDefaultLAF; + } + + public static void setWizardLAF(String laf) { + ourWizardLAF = laf; + } + + public static String getWizardLAF() { + return ourWizardLAF; + } + + public static void setWizardKeymap(@Nullable String keymap) { + ourWizardMacKeymap = keymap; + } + + @Nullable + public static String getWizardMacKeymap() { + return ourWizardMacKeymap; + } + + public static void setWizardEditorScheme(@Nullable String wizardEditorScheme) { + ourWizardEditorScheme = wizardEditorScheme; + } + + @Nullable + public static String getWizardEditorScheme() { + return ourWizardEditorScheme; + } + + @Nullable + public static Boolean getAutoScrollToSource() { + return ourAutoScrollToSource; + } + + public static void setAutoScrollToSource(@Nullable Boolean autoScrollToSource) { + ourAutoScrollToSource = autoScrollToSource; + } + + public static Set getFeaturedPluginsToInstall() { + return Collections.unmodifiableSet(ourFeaturedPluginsToInstall); + } + + public static void setFeaturedPluginsToInstall(Set pluginsToInstall) { + ourFeaturedPluginsToInstall.clear(); + ourFeaturedPluginsToInstall.addAll(pluginsToInstall); + } +} diff --git a/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java b/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java index 998620ffa599..4a390bc1383b 100644 --- a/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java +++ b/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java @@ -16,6 +16,7 @@ package com.intellij.ide.ui; import com.intellij.ide.IdeBundle; +import com.intellij.ide.WelcomeWizardUtil; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; @@ -128,6 +129,9 @@ public class UISettings extends SimpleModificationTracker implements PersistentS public UISettings() { tweakPlatformDefaults(); setSystemFontFaceAndSize(); + + Boolean scrollToSource = WelcomeWizardUtil.getAutoScrollToSource(); + if (scrollToSource != null) DEFAULT_AUTOSCROLL_TO_SOURCE = scrollToSource; } private void tweakPlatformDefaults() { diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeKeyboardSchemeStepPanel.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeKeyboardSchemeStepPanel.java index 53b215516c09..1b1779141ab6 100644 --- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeKeyboardSchemeStepPanel.java +++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeKeyboardSchemeStepPanel.java @@ -16,7 +16,7 @@ package com.intellij.ide.customize; import com.intellij.CommonBundle; -import com.intellij.idea.StartupUtil; +import com.intellij.ide.WelcomeWizardUtil; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.ui.VerticalFlowLayout; @@ -37,7 +37,7 @@ public class CustomizeKeyboardSchemeStepPanel extends AbstractCustomizeWizardSte myMacPanel = createBigButtonPanel(new VerticalFlowLayout(), macRadioButton, new Runnable() { @Override public void run() { - StartupUtil.setMyWizardMacKeymap(KeymapManager.MAC_OS_X_10_5_PLUS_KEYMAP); + WelcomeWizardUtil.setWizardKeymap(KeymapManager.MAC_OS_X_10_5_PLUS_KEYMAP); } }); String style = "" + + "bar
public interface MyExtensionPoint
\n" + + " MyExtensionPoint JavaDoc.", + provider.generateDoc(epPsiElement, originalElement)); + } +} From 0c781807dbc2816cbf60cff54a4b5bc09175d3dc Mon Sep 17 00:00:00 2001 From: Vyacheslav Karpukhin Date: Fri, 24 Oct 2014 14:49:02 +0400 Subject: [PATCH 124/132] XmlPsiManager should not increase tracker on changes in unrelated files --- xml/xml-psi-impl/src/com/intellij/xml/XmlPsiManager.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/xml/xml-psi-impl/src/com/intellij/xml/XmlPsiManager.java b/xml/xml-psi-impl/src/com/intellij/xml/XmlPsiManager.java index 3525a00163a7..b5c24bbe070b 100644 --- a/xml/xml-psi-impl/src/com/intellij/xml/XmlPsiManager.java +++ b/xml/xml-psi-impl/src/com/intellij/xml/XmlPsiManager.java @@ -21,7 +21,10 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFileSystemItem; import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.PsiTreeChangeEventImpl; import com.intellij.psi.impl.PsiTreeChangePreprocessorBase; +import com.intellij.psi.xml.XmlFile; +import org.jetbrains.annotations.NotNull; /** * Created by fedorkorotkov. @@ -52,6 +55,12 @@ public class XmlPsiManager extends AbstractProjectComponent { // cause we display even attributes and tag values in structure view return !isXml; } + + @Override + public void treeChanged(@NotNull PsiTreeChangeEventImpl event) { + if (!(event.getFile() instanceof XmlFile)) return; + super.treeChanged(event); + } }; } } From 9f9a64efa69eadeeeb63a18f4fddb49d3314efeb Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Tue, 28 Oct 2014 01:21:25 +0400 Subject: [PATCH 125/132] html viewer doesn't need focus --- platform/platform-impl/src/com/intellij/util/ui/SwingHelper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/platform-impl/src/com/intellij/util/ui/SwingHelper.java b/platform/platform-impl/src/com/intellij/util/ui/SwingHelper.java index 488c52d14207..bd2d7bc4a623 100644 --- a/platform/platform-impl/src/com/intellij/util/ui/SwingHelper.java +++ b/platform/platform-impl/src/com/intellij/util/ui/SwingHelper.java @@ -442,6 +442,7 @@ public class SwingHelper { textPane.setOpaque(false); } textPane.setForeground(foreground != null ? foreground : UIUtil.getLabelForeground()); + textPane.setFocusable(false); return textPane; } From d8915f5e02ee5cdce1f591e4eccf1ff80011cf0b Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 28 Oct 2014 00:58:08 +0300 Subject: [PATCH 126/132] UI: one simple way to control toolwindow toolbars visibility --- .../hierarchy/HierarchyBrowserManager.java | 13 ++- .../ide/impl/StructureViewWrapperImpl.java | 8 +- .../impl/StructureViewFactoryImpl.java | 1 - .../StructureViewComponent.java | 24 +----- .../usageView/impl/UsageViewManagerImpl.java | 7 ++ .../openapi/ui/SimpleToolWindowPanel.java | 80 ++++++++++++++++++- .../changes/ui/ChangesViewContentManager.java | 7 ++ 7 files changed, 109 insertions(+), 31 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserManager.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserManager.java index c0f156fedd28..7c7f9e7988a7 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserManager.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserManager.java @@ -18,12 +18,15 @@ package com.intellij.ide.hierarchy; import com.intellij.icons.AllIcons; import com.intellij.ide.impl.ContentManagerWatcher; +import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.components.*; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.SimpleToolWindowPanel; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowAnchor; import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ex.ToolWindowEx; import com.intellij.ui.content.ContentManager; @State( @@ -46,11 +49,15 @@ public final class HierarchyBrowserManager implements PersistentStateComponent deque = ContainerUtil.newLinkedList(content.getComponent()); + while(!deque.isEmpty()) { + JComponent component = deque.pollFirst(); + if (!(component instanceof JPanel)) continue; + + for (int i = 0, count = component.getComponentCount(); i < count; i++) { + Component c = component.getComponent(i); + if (c instanceof ActionToolbar) { + c.setVisible(state); + } + else if (c instanceof JPanel) { + deque.addLast((JPanel)c); + } + } + } + } + } } \ No newline at end of file diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesViewContentManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesViewContentManager.java index 297408c3ec24..96e62cfa7cb0 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesViewContentManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesViewContentManager.java @@ -19,6 +19,7 @@ package com.intellij.openapi.vcs.changes.ui; import com.intellij.icons.AllIcons; import com.intellij.lifecycle.PeriodicalTasksCloser; import com.intellij.openapi.Disposable; +import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.components.AbstractProjectComponent; @@ -26,6 +27,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.ui.SimpleToolWindowPanel; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; @@ -36,6 +38,7 @@ import com.intellij.openapi.vcs.VcsListener; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowAnchor; import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ex.ToolWindowEx; import com.intellij.ui.content.*; import com.intellij.util.Alarm; import com.intellij.util.NotNullFunction; @@ -83,6 +86,10 @@ public class ChangesViewContentManager extends AbstractProjectComponent implemen if (toolWindowManager != null) { myToolWindow = toolWindowManager.registerToolWindow(TOOLWINDOW_ID, true, ToolWindowAnchor.BOTTOM, myProject, true); myToolWindow.setIcon(AllIcons.Toolwindows.ToolWindowChanges); + DefaultActionGroup gearActions = new DefaultActionGroup(); + gearActions.addAction(SimpleToolWindowPanel.createToggleToolbarAction(myToolWindow)).setAsSecondary(true); + ((ToolWindowEx)myToolWindow).setAdditionalGearActions(gearActions); + updateToolWindowAvailability(); final ContentManager contentManager = myToolWindow.getContentManager(); myContentManagerListener = new MyContentManagerListener(); From c3faa89b21ab8a7ec9ed936680ada32afb521d74 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 28 Oct 2014 01:46:08 +0300 Subject: [PATCH 127/132] UI: one simple way to control toolwindow toolbars visibility 2 --- .../com/intellij/ide/hierarchy/HierarchyBrowserManager.java | 2 +- .../src/com/intellij/ide/impl/StructureViewWrapperImpl.java | 2 +- .../com/intellij/usageView/impl/UsageViewManagerImpl.java | 2 +- .../src/com/intellij/openapi/ui/SimpleToolWindowPanel.java | 5 +++-- .../openapi/vcs/changes/ui/ChangesViewContentManager.java | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserManager.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserManager.java index 7c7f9e7988a7..595907aa5720 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserManager.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserManager.java @@ -52,7 +52,7 @@ public final class HierarchyBrowserManager implements PersistentStateComponent Date: Tue, 28 Oct 2014 08:22:40 +0100 Subject: [PATCH 128/132] IDEA-131862 Missing quick doc in extension tag completion --- .../ExtensionPointDocumentationProvider.java | 28 +++++++++---------- ...tensionPointDocumentationProviderTest.java | 16 ++++------- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/plugins/devkit/src/references/extensions/ExtensionPointDocumentationProvider.java b/plugins/devkit/src/references/extensions/ExtensionPointDocumentationProvider.java index cc9f3ed3ab26..2ce1c27e6e38 100644 --- a/plugins/devkit/src/references/extensions/ExtensionPointDocumentationProvider.java +++ b/plugins/devkit/src/references/extensions/ExtensionPointDocumentationProvider.java @@ -18,21 +18,19 @@ package org.jetbrains.idea.devkit.references.extensions; import com.intellij.codeInsight.javadoc.JavaDocInfoGenerator; import com.intellij.lang.documentation.DocumentationProviderEx; import com.intellij.lang.java.JavaDocumentationProvider; -import com.intellij.lang.xml.XMLLanguage; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.pom.PomTarget; +import com.intellij.pom.PomTargetPsiElement; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTypesUtil; import com.intellij.psi.xml.XmlFile; -import com.intellij.psi.xml.XmlTag; -import com.intellij.psi.xml.XmlToken; -import com.intellij.psi.xml.XmlTokenType; import com.intellij.util.xml.DomElement; +import com.intellij.util.xml.DomTarget; import com.intellij.util.xml.DomUtil; import org.jetbrains.annotations.Nullable; -import org.jetbrains.idea.devkit.dom.Extension; import org.jetbrains.idea.devkit.dom.ExtensionPoint; import org.jetbrains.idea.devkit.util.DescriptorUtil; @@ -43,7 +41,7 @@ public class ExtensionPointDocumentationProvider extends DocumentationProviderEx @Override public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) { - ExtensionPoint extensionPoint = findExtensionPoint(originalElement); + ExtensionPoint extensionPoint = findExtensionPoint(element); if (extensionPoint == null) return null; final XmlFile epDeclarationFile = (XmlFile)extensionPoint.getXmlTag().getContainingFile(); @@ -69,7 +67,7 @@ public class ExtensionPointDocumentationProvider extends DocumentationProviderEx @Override public String generateDoc(PsiElement element, @Nullable PsiElement originalElement) { - ExtensionPoint extensionPoint = findExtensionPoint(originalElement); + ExtensionPoint extensionPoint = findExtensionPoint(element); if (extensionPoint == null) return null; final PsiClass epClass = getExtensionPointClass(extensionPoint); @@ -89,15 +87,15 @@ public class ExtensionPointDocumentationProvider extends DocumentationProviderEx } @Nullable - private static ExtensionPoint findExtensionPoint(@Nullable PsiElement element) { - if (element == null) return null; - if (element.getLanguage() == XMLLanguage.INSTANCE && - (element instanceof XmlTag || - element instanceof XmlToken && ((XmlToken)element).getTokenType() == XmlTokenType.XML_NAME) && + private static ExtensionPoint findExtensionPoint(PsiElement element) { + if (element instanceof PomTargetPsiElement && DescriptorUtil.isPluginXml(element.getContainingFile())) { - final DomElement domElement = DomUtil.getDomElement(element); - if (domElement instanceof Extension) { - return ((Extension)domElement).getExtensionPoint(); + final PomTarget pomTarget = ((PomTargetPsiElement)element).getTarget(); + if (pomTarget instanceof DomTarget) { + final DomElement domElement = ((DomTarget)pomTarget).getDomElement(); + if (domElement instanceof ExtensionPoint) { + return (ExtensionPoint)domElement; + } } } return null; diff --git a/plugins/devkit/testSources/references/extensions/ExtensionPointDocumentationProviderTest.java b/plugins/devkit/testSources/references/extensions/ExtensionPointDocumentationProviderTest.java index 7cb0a30a0548..a9c16ec0335a 100644 --- a/plugins/devkit/testSources/references/extensions/ExtensionPointDocumentationProviderTest.java +++ b/plugins/devkit/testSources/references/extensions/ExtensionPointDocumentationProviderTest.java @@ -3,10 +3,8 @@ package org.jetbrains.idea.devkit.references.extensions; import com.intellij.codeInsight.documentation.DocumentationManager; import com.intellij.lang.documentation.DocumentationProvider; import com.intellij.openapi.application.PluginPathManager; -import com.intellij.pom.PomTargetPsiElement; import com.intellij.psi.PsiElement; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; -import com.intellij.util.xml.DomTarget; public class ExtensionPointDocumentationProviderTest extends LightCodeInsightFixtureTestCase { @Override @@ -17,12 +15,10 @@ public class ExtensionPointDocumentationProviderTest extends LightCodeInsightFix public void testExtensionPointDocumentation() { myFixture.configureByFiles("extensionPointDocumentation.xml", "bar/MyExtensionPoint.java"); - PsiElement originalElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset()); - PomTargetPsiElement pomTargetPsiElement = assertInstanceOf(myFixture.getElementAtCaret(), PomTargetPsiElement.class); - DomTarget domTarget = assertInstanceOf(pomTargetPsiElement.getTarget(), DomTarget.class); - PsiElement epPsiElement = domTarget.getNavigationElement(); - - DocumentationProvider provider = DocumentationManager.getProviderFromElement(epPsiElement); + final PsiElement docElement = + DocumentationManager.getInstance(getProject()).findTargetElement(myFixture.getEditor(), + myFixture.getFile()); + DocumentationProvider provider = DocumentationManager.getProviderFromElement(docElement); String epDefinition = "[" + myModule.getName() + "] foo
" + "bar " + @@ -30,7 +26,7 @@ public class ExtensionPointDocumentationProviderTest extends LightCodeInsightFix "MyExtensionPoint"; assertEquals(epDefinition, - provider.getQuickNavigateInfo(epPsiElement, originalElement)); + provider.getQuickNavigateInfo(docElement, null)); assertEquals("EP Definition
" + epDefinition + @@ -39,6 +35,6 @@ public class ExtensionPointDocumentationProviderTest extends LightCodeInsightFix " " + "bar
public interface MyExtensionPoint
\n" + " MyExtensionPoint JavaDoc.", - provider.generateDoc(epPsiElement, originalElement)); + provider.generateDoc(docElement, null)); } } From d679f53a3b063e950042f5062c68bc8aebea2575 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 27 Oct 2014 17:12:10 +0100 Subject: [PATCH 129/132] continue Firefox RDP --- .../protocolReader/FieldProcessor.java | 99 +++++++++++-------- .../protocolReader/InterfaceReader.java | 2 - .../protocolReader/MethodHandler.java | 10 +- .../PreparsedFieldMethodHandler.java | 21 ---- .../protocolReader/PrimitiveValueReader.java | 6 +- .../protocolReader/ReadDelegate.java | 2 +- .../protocolReader/ReaderGenerator.java | 1 + .../jetbrains/protocolReader/ReaderRoot.java | 6 +- .../jetbrains/protocolReader/TypeHandler.java | 4 +- 9 files changed, 73 insertions(+), 78 deletions(-) delete mode 100644 platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PreparsedFieldMethodHandler.java diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java index 77a91e8543d1..3925239a98d2 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java @@ -10,22 +10,17 @@ import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.*; -class FieldProcessor { - private final Class typeClass; - +final class FieldProcessor { private final List fieldLoaders = new ArrayList<>(2); private final LinkedHashMap methodHandlerMap = new LinkedHashMap<>(); private final List volatileFields = new ArrayList<>(2); boolean lazyRead; private final InterfaceReader reader; - FieldProcessor(InterfaceReader reader, Class typeClass) { - this.typeClass = typeClass; + FieldProcessor(@NotNull InterfaceReader reader, @NotNull Class typeClass) { this.reader = reader; - } - void go() { - Method[] methods = typeClass.getDeclaredMethods(); + Method[] methods = typeClass.getMethods(); // todo sort by source location Arrays.sort(methods, new Comparator() { @Override @@ -34,58 +29,77 @@ class FieldProcessor { } }); - for (Method m : methods) { + Package aPackage = typeClass.getPackage(); + for (Method method : methods) { + Class methodClass = method.getDeclaringClass(); + // use method from super if super located in the same package + if (methodClass != typeClass && methodClass.getPackage() != aPackage) { + continue; + } + + if (method.getParameterTypes().length != 0) { + throw new JsonProtocolModelParseException("No parameters expected in " + method); + } + try { - processMethod(m); + String fieldName = checkAndGetJsonFieldName(method); + MethodHandler methodHandler; + + JsonSubtypeCasting jsonSubtypeCaseAnnotation = method.getAnnotation(JsonSubtypeCasting.class); + if (jsonSubtypeCaseAnnotation != null) { + methodHandler = processManualSubtypeMethod(method, jsonSubtypeCaseAnnotation); + lazyRead = true; + } + else { + methodHandler = processFieldGetterMethod(method, fieldName); + } + methodHandlerMap.put(method, methodHandler); } catch (JsonProtocolModelParseException e) { - throw new JsonProtocolModelParseException("Problem with method " + m, e); + throw new JsonProtocolModelParseException("Problem with method " + method, e); } } } - private void processMethod(Method m) { - if (m.getParameterTypes().length != 0) { - throw new JsonProtocolModelParseException("No parameters expected in " + m); - } - String fieldName = checkAndGetJsonFieldName(m); - MethodHandler methodHandler; - - JsonSubtypeCasting jsonSubtypeCaseAnnotation = m.getAnnotation(JsonSubtypeCasting.class); - if (jsonSubtypeCaseAnnotation != null) { - methodHandler = processManualSubtypeMethod(m, jsonSubtypeCaseAnnotation); - lazyRead = true; - } - else { - methodHandler = processFieldGetterMethod(m, fieldName); - } - methodHandlerMap.put(m, methodHandler); - } - - private MethodHandler processFieldGetterMethod(Method m, String fieldName) { - Type genericReturnType = m.getGenericReturnType(); + private MethodHandler processFieldGetterMethod(@NotNull Method method, @NotNull String fieldName) { + Type genericReturnType = method.getGenericReturnType(); boolean nullable; - if (m.getAnnotation(JsonNullable.class) != null) { + if (method.getAnnotation(JsonNullable.class) != null) { nullable = true; } else if (genericReturnType == String.class || genericReturnType == Enum.class) { - JsonField jsonField = m.getAnnotation(JsonField.class); + JsonField jsonField = method.getAnnotation(JsonField.class); if (jsonField != null) { nullable = jsonField.optional() && !jsonField.allowAnyPrimitiveValue() && !jsonField.allowAnyPrimitiveValueAndMap(); } else { - nullable = m.getAnnotation(JsonOptionalField.class) != null; + nullable = method.getAnnotation(JsonOptionalField.class) != null; } } else { nullable = false; } - ValueReader fieldTypeParser = reader.getFieldTypeParser(genericReturnType, nullable, false, m); + ValueReader fieldTypeParser = reader.getFieldTypeParser(genericReturnType, nullable, false, method); if (fieldTypeParser != InterfaceReader.VOID_PARSER) { fieldLoaders.add(new FieldLoader(fieldName, fieldTypeParser)); } - return new PreparsedFieldMethodHandler(fieldTypeParser == InterfaceReader.VOID_PARSER ? null : fieldName); + + final String effectiveFieldName = fieldTypeParser == InterfaceReader.VOID_PARSER ? null : fieldName; + return new MethodHandler() { + @Override + void writeMethodImplementationJava(@NotNull ClassScope scope, @NotNull Method method, @NotNull TextOutput out) { + if (!nullable) { + out.append("@NotNull").newLine(); + } + writeMethodDeclarationJava(out, method); + out.openBlock(); + if (effectiveFieldName != null) { + out.append("return ").append(FieldLoader.FIELD_PREFIX).append(effectiveFieldName).semi(); + } + out.closeBlock(); + } + }; } private MethodHandler processManualSubtypeMethod(final Method m, JsonSubtypeCasting jsonSubtypeCaseAnn) { @@ -131,17 +145,18 @@ class FieldProcessor { return binding; } - private static String checkAndGetJsonFieldName(Method m) { - if (m.getParameterTypes().length != 0) { + @NotNull + private static String checkAndGetJsonFieldName(@NotNull Method method) { + if (method.getParameterTypes().length != 0) { throw new JsonProtocolModelParseException("Must have 0 parameters"); } - JsonField fieldAnn = m.getAnnotation(JsonField.class); - if (fieldAnn != null) { - String jsonLiteralName = fieldAnn.jsonLiteralName(); + JsonField fieldAnnotation = method.getAnnotation(JsonField.class); + if (fieldAnnotation != null) { + String jsonLiteralName = fieldAnnotation.jsonLiteralName(); if (!jsonLiteralName.isEmpty()) { return jsonLiteralName; } } - return m.getName(); + return method.getName(); } } diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/InterfaceReader.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/InterfaceReader.java index a02b4ae8f18a..2cb6b9a28d07 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/InterfaceReader.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/InterfaceReader.java @@ -161,8 +161,6 @@ class InterfaceReader { } FieldProcessor fields = new FieldProcessor<>(this, typeClass); - fields.go(); - LinkedHashMap methodHandlerMap = fields.getMethodHandlerMap(); for (Method method : methodHandlerMap.keySet()) { Class returnType = method.getReturnType(); diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/MethodHandler.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/MethodHandler.java index a877b654c020..a9caa4e22929 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/MethodHandler.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/MethodHandler.java @@ -14,10 +14,10 @@ import java.util.List; abstract class MethodHandler { abstract void writeMethodImplementationJava(ClassScope classScope, Method m, TextOutput out); - protected static void appendMethodSignatureJava(@NotNull Method m, @NotNull List paramNames, @NotNull TextOutput out) { - out.append(m.getName()).append('('); + protected static void appendMethodSignatureJava(@NotNull Method method, @NotNull List paramNames, @NotNull TextOutput out) { + out.append(method.getName()).append('('); boolean firstArg = true; - Type[] types = m.getGenericParameterTypes(); + Type[] types = method.getGenericParameterTypes(); for (int i = 0, length = types.length; i < length; i++) { Type arg = types[i]; if (firstArg) { @@ -32,8 +32,8 @@ abstract class MethodHandler { out.append(')'); } - protected static void writeMethodDeclarationJava(TextOutput out, Method m) { - writeMethodDeclarationJava(out, m, Collections.emptyList()); + protected static void writeMethodDeclarationJava(TextOutput out, Method method) { + writeMethodDeclarationJava(out, method, Collections.emptyList()); } protected static void writeMethodDeclarationJava(@NotNull TextOutput out, @NotNull Method m, @NotNull List paramNames) { diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PreparsedFieldMethodHandler.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PreparsedFieldMethodHandler.java deleted file mode 100644 index 19e7714a0bd2..000000000000 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PreparsedFieldMethodHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.jetbrains.protocolReader; - -import java.lang.reflect.Method; - -class PreparsedFieldMethodHandler extends MethodHandler { - private final String fieldName; - - PreparsedFieldMethodHandler(String fieldName) { - this.fieldName = fieldName; - } - - @Override - void writeMethodImplementationJava(ClassScope scope, Method m, TextOutput out) { - writeMethodDeclarationJava(out, m); - out.openBlock(); - if (fieldName != null) { - out.append("return ").append(FieldLoader.FIELD_PREFIX).append(fieldName).semi(); - } - out.closeBlock(); - } -} diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PrimitiveValueReader.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PrimitiveValueReader.java index 5e53088b9b39..4f950fc4bb44 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PrimitiveValueReader.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PrimitiveValueReader.java @@ -38,11 +38,13 @@ class PrimitiveValueReader extends ValueReader { if (asRawString) { out.append("readRawString("); addReaderParameter(subtyping, out); + out.append(')'); } else { - beginReadCall(readPostfix, subtyping, out, fieldName); + ValueReader.addReaderParameter(subtyping, out); + out.append(".next").append(readPostfix).append("()"); + //beginReadCall(readPostfix, subtyping, out, fieldName); } - out.append(')'); } @Override diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReadDelegate.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReadDelegate.java index 56dcc310fa83..ca3253b1595b 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReadDelegate.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReadDelegate.java @@ -23,7 +23,7 @@ class ReadDelegate { paramNames = hasNextNameParam ? STATIC_METHOD_PARAM_NAME_LIST2 : STATIC_METHOD_PARAM_NAME_LIST; } - void write(ClassScope scope, Method method, TextOutput out) { + void write(@NotNull ClassScope scope, @NotNull Method method, @NotNull TextOutput out) { MethodHandler.writeMethodDeclarationJava(out, method, paramNames); out.openBlock(); out.append("return "); diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderGenerator.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderGenerator.java index c51ae4c55e0f..71150f1fad79 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderGenerator.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderGenerator.java @@ -121,6 +121,7 @@ public final class ReaderGenerator { out.append("// Generated source"); out.newLine().append("package ").append(configuration.packageName).append(';'); out.newLine().newLine().append("import org.jetbrains.jsonProtocol.*;"); + out.newLine().newLine().append("import org.jetbrains.annotations.NotNull;"); out.newLine().newLine().append("import static org.jetbrains.jsonProtocol.JsonReaders.*;"); out.newLine().newLine().append("public final class ").append(configuration.className).space(); out.append(configuration.root.getType().isInterface() ? "implements" : "extends").space().append(configuration.root.getType().getCanonicalName()).openBlock(false); diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderRoot.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderRoot.java index f7ce9eb9eb39..8a480f9ec819 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderRoot.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderRoot.java @@ -94,11 +94,11 @@ class ReaderRoot { return rootClass; } - public void writeStaticMethodJava(ClassScope scope) { + public void writeStaticMethodJava(@NotNull ClassScope scope) { TextOutput out = scope.getOutput(); - for (Map.Entry en : methodMap.entrySet()) { + for (Map.Entry entry : methodMap.entrySet()) { out.newLine(); - en.getValue().write(scope, en.getKey(), out); + entry.getValue().write(scope, entry.getKey(), out); out.newLine(); } } diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/TypeHandler.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/TypeHandler.java index 261b0e94e07c..983ce0c69d01 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/TypeHandler.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/TypeHandler.java @@ -93,9 +93,9 @@ class TypeHandler { subtypeAspect.writeParseMethod(valueImplClassName, classScope, out); } - for (Map.Entry en : methodHandlerMap.entrySet()) { + for (Map.Entry entry : methodHandlerMap.entrySet()) { out.newLine(); - en.getValue().writeMethodImplementationJava(classScope, en.getKey(), out); + entry.getValue().writeMethodImplementationJava(classScope, entry.getKey(), out); out.newLine(); } From 2b15af802372eea188dd7e3e6fc20b086543c0c8 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 28 Oct 2014 11:52:57 +0300 Subject: [PATCH 130/132] IDEA-131993 Debugger: arrays/collections: "more items" specifies wrong value --- .../src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java index f7f05fcc496f..e66990a04775 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java @@ -192,7 +192,7 @@ public class ArrayRenderer extends NodeRendererImpl{ if(!myForced && END_INDEX < array.length() - 1) { //children.add(nodeManager.createMessageNode(new MessageDescriptor(MORE_ELEMENTS, MessageDescriptor.SPECIAL))); - builder.setRemaining(array.length()-END_INDEX); + builder.setRemaining(array.length()-1-END_INDEX); } } } From 4a6142a813d91233aba4616b91069de550bccaa8 Mon Sep 17 00:00:00 2001 From: Vyacheslav Karpukhin Date: Tue, 28 Oct 2014 12:12:50 +0300 Subject: [PATCH 131/132] JsonTreeChangePreprocessor should not increase tracker on changes in unrelated files --- .../com/intellij/json/psi/impl/JsonTreeChangePreprocessor.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/json/src/com/intellij/json/psi/impl/JsonTreeChangePreprocessor.java b/json/src/com/intellij/json/psi/impl/JsonTreeChangePreprocessor.java index 5f51296b37d9..6bb2ee9ee166 100644 --- a/json/src/com/intellij/json/psi/impl/JsonTreeChangePreprocessor.java +++ b/json/src/com/intellij/json/psi/impl/JsonTreeChangePreprocessor.java @@ -1,6 +1,7 @@ package com.intellij.json.psi.impl; import com.intellij.json.JsonLanguage; +import com.intellij.json.psi.JsonFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFileSystemItem; @@ -20,6 +21,8 @@ public class JsonTreeChangePreprocessor implements PsiTreeChangePreprocessor { */ @Override public void treeChanged(@NotNull PsiTreeChangeEventImpl event) { + if (!(event.getFile() instanceof JsonFile)) return; + final PsiElement element = event.getParent(); if (element == null || !(element.getManager() instanceof PsiManagerImpl)) { return; From 20efa841997af02335b6e473a1c194d4102cf945 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 28 Oct 2014 12:32:09 +0300 Subject: [PATCH 132/132] DSGN-869 New icons for task management --- plugins/tasks/tasks-core/src/icons/clock.png | Bin 655 -> 633 bytes plugins/tasks/tasks-core/src/icons/clock@2x.png | Bin 0 -> 1462 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 plugins/tasks/tasks-core/src/icons/clock@2x.png diff --git a/plugins/tasks/tasks-core/src/icons/clock.png b/plugins/tasks/tasks-core/src/icons/clock.png index d9cbbfc508a1980c5b72be0c640c65d0c56b56cd..701863c24cd44791889496ee30b65f2931b93c99 100644 GIT binary patch delta 609 zcmV-n0-pVk1^EP!BYyxHbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU! z8%ab#RCwBSQqODCa1_rs`KIY&*I3fpHErq!9h(*DVTU2s9Yn#yJiDTJa+l77`vV03 z1rJqW$ANhCpa>omW-ls3hUm5;PCA>d#?U3UX_{YOzi+gcfq#LQ_kAy)Pu_c66;%clG=)am&>wOXvcRv+Q;5Dfm2bZV?Rla-l?L_8#}9iWJqIqXo$0ZA+M%RS1AsN47yQ!dnqnP z>+@$5u9C~|uzxJ_0?$Ln{&!JU3pU5|Bn%0!{c6sBY#v3-UcU^LRtni9W9>Igf+&GN z(>(e7@>w1{#E^&Y1x1EJ_h6PQay&-Hvi?Q;_YTko^VGhy?A(cZgiF>XU(arH-7_4Na7$2+ddY~oL{`t5Tu0X z5C4As!P@4CKtdlmRwvRULeUSjLzwBEanwZzyIX03Fagd)|#aWYC;$oK`Q--5fUg9gIH)r zu_$yReoP_M5K0P{KZeWM+(dIuH{00e>{aJy(wm5-V=1d><##CsS`mU#QT-6)^khjC zUAXXEIOo7Q=OOxgL=<+ZV3)!)A6H;SY_8=SC(}EL4j!WaPJeirJg&qQtRHv**Ta`+ z7!0CCm_~KUhR;Ss%EJ z4oH+e*k3w~KL1-ps|D;(dfD=zR2zycK2$r$K9fY*4Eyjbq**+q7y1#FCE!5mI40*l zBCToyTzdbe5S?&Bt{sBT;|Gb;>ed}2jHJ2^ab`QhvwsCd=lM|Ev5erWuh6>Y5t`)% zB{e`%GYFmAw?PzJ$u|qLNY%0sj?``@Cdyj`>sX&2RJN8iu}HX&XbiWn|;*je#XeMpFxg6eex~e*pESNt4e7 Rxd{LO002ovPDHLkV1k7XATIy_ diff --git a/plugins/tasks/tasks-core/src/icons/clock@2x.png b/plugins/tasks/tasks-core/src/icons/clock@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c2e69d55385e2eee40318cf248a8e77af7bb6099 GIT binary patch literal 1462 zcmV;n1xfmeP)TPf7y21 zU0T@Eg#raE5B{P2SV=&|h~k^RnTS5Bk19_ZjLlp=iP|_l$ zwB42d?9%=1?9R^4%$@O^{h@2wtqIe7y=U(^=R5bFd+)iIJ2hP*D}CRdzSIZJtAKrg zen4AIl?L1boCBNy+*yf-!$3cN_|`*;!p^t%K=TP;SG|wtdEyX-imd7eF-^14xnH`_cKg29 zXV-SEGdlbpe{ay+IiFYTBUAHSNz>l}^<%*GG6c&!$cD8PM1tlt1_^j1GB^-rZDt`k zckPc9HT4X~bGkpgR&9^0ml6Ke5f%GThc*GQ9o!ye0WZ>!9mrMVtOZ({&{u$`f<717 zwY67UWv7#-T3GZ3yGo219NKX_wYKejEr~!G`JK$%SA}-fML@Dv`u263iXG7{1%nsOH68vnW3fs>I3&~$WV_cx1cBx$ zFEUE1X;}X0C54uYvdD3qSXLA&IwiK;MwC28MKH~LyU(+Rka_&In}>g!@Wk6Wrsrp4 zlo_mL+D3mn7P3r}Ga2J5a;x+K2XOIr!gR`G2(l4p)MgVX(Tj_0;==K+K%`IJ_}nYW zW@)*1i=l7dgs0^QH2I z2UiFNI*!tOI!B61F*tqcY%m?a?J`$btCfJhz|nzRbE#}S&@ukto+n2@7%nI(Sy(JN zy^+n73clWVJO`WTIgJt^tdy5NmPL8YIJy;Q@hfa1PP_Cp3bZCRNa+yVM zg70EcLB1W>r2X(yq;D&qILiJiA}Rw@`UIG#G( zf@X0vw^$&FOqM96a(zwkaq>Z9kfyI7Fu=P0E+~J7_A?-OW@;8T$!z7hC5i$S@jlay zh2_t!zW^WA*W{ry{58yIrSHt})lJYG1ndWFUiN_e8*mnI5-ZF~JpT$X0O96d7nIIN QzyJUM07*qoM6N<$f=yw*ivR!s literal 0 HcmV?d00001