| ''' | |
| Copyright (c) 2017 Martin Kloesch and others. | |
| All rights reserved. This program and the accompanying materials | |
| are made available under the terms of the Eclipse Public License v2.0 | |
| which accompanies this distribution, and is available at | |
| https://www.eclipse.org/legal/epl-2.0/ | |
| Contributors: | |
| * Martin Kloesch - initial API and implementation | |
| ''' | |
| try: | |
| # Try to use jedi library for best results | |
| import jedi as _pyease_jedi | |
| except ImportError: | |
| _pyease_jedi = None | |
| import __main__ | |
| try: | |
| # Additional analysis using EASE code_completion library | |
| from code_completion.completion import parse as _pyease_cc | |
| except ImportError: | |
| # Fallback to no-op generator | |
| def _pyease_cc(*args, **kwargs): | |
| return | |
| yield | |
| try: | |
| # If possible try to use docutils to generate better docstrings | |
| from docutils.core import publish_string as _pyease_docutils_ps | |
| def _pyease_html_documentation(docstring): | |
| try: | |
| return _pyease_docutils_ps(docstring, writer_name="html", settings_overrides={'report_level':'quiet'}).decode("utf-8") | |
| except Exception: | |
| return docstring | |
| except ImportError: | |
| # Fallback to no-op function | |
| def _pyease_html_documentation(docstring): | |
| return docstring | |
| class _pyease_CompletionProvider: | |
| ''' | |
| EASE ICompletionProvider wrapping to different code completion | |
| libraries. | |
| Currently wraps to: | |
| * jedi (for longer inputs) | |
| * code_completion (EASE) | |
| ''' | |
| def getProposals(self, context): | |
| # Java class because of problem with python list serialization | |
| java_completions = java.util.ArrayList() | |
| source = context.getOriginalCode() | |
| completions = [] | |
| # code_completion library for simple default proposals | |
| completions.extend(_pyease_cc(source)) | |
| # Jedi library for best proposals (only if available) | |
| if _pyease_jedi: | |
| # jedi.Script for static checks | |
| script = _pyease_jedi.Script(source) | |
| completions.extend(script.completions()) | |
| # jedi.Interpreter for dynamic checks | |
| interpreter = _pyease_jedi.Interpreter(source, [__main__.__dict__]) | |
| completions.extend(interpreter.completions()) | |
| # Remove duplicates | |
| completions_no_duplicates = {} | |
| for completion in completions: | |
| to_check = completion | |
| if hasattr(completion, 'name'): | |
| to_check = completion.name | |
| if to_check not in completions_no_duplicates: | |
| completions_no_duplicates[to_check] = completion | |
| # Parse completions to Java suitable format | |
| for comp in completions_no_duplicates.values(): | |
| # Safety fallback, should always use name | |
| proposal = comp.name if hasattr(comp, 'name') else comp | |
| # Ignore internals | |
| if not proposal.startswith('_pyease'): | |
| # code_completion library object | |
| if hasattr(comp, 'documentation') and comp.documentation: | |
| help_resolver = org.eclipse.ease.lang.python.ui.completion.PythonHelpResolver(comp.documentation.plain, comp.documentation.html) | |
| # jedi object | |
| elif hasattr(comp, 'doc') and comp.doc: | |
| help_resolver = org.eclipse.ease.lang.python.ui.completion.PythonHelpResolver( | |
| comp.doc, | |
| _pyease_html_documentation(comp.doc) | |
| ) | |
| # No documentation | |
| else: | |
| help_resolver = None | |
| java_completions.add( | |
| org.eclipse.ease.ui.completion.ScriptCompletionProposal( | |
| context, | |
| proposal, | |
| proposal, | |
| None, | |
| 1, | |
| help_resolver | |
| ) | |
| ) | |
| return java_completions | |
| def isActive(self, context): | |
| ''' | |
| Always active. | |
| ''' | |
| return True | |
| class Java: | |
| implements = ['org.eclipse.ease.ui.completion.ICompletionProvider'] | |
| # Set up connection between eclipse and python | |
| _pyease_jedi_completion_provider = _pyease_CompletionProvider() | |
| _pyease_jedi_completion_provider_wrapper.setPythonPprovider( | |
| _pyease_jedi_completion_provider) |