Step 0: Light class object is created, no delegates are computed
Step 1: constructs dummy delegate which can not be relied upon to know signature of any member
It can be used to construct light field and light method objects
(which can correctly respond to some queries) before constructing real delegate
Step 2:
Construct real delegate if dummy delegate is not enough to respond to a query
This speeds up multiple scenarios where getMethods() and getFields() are called on numerous classes
Dummy delegate's faster consruction is achieved by using specially setup dumb analysis instead of ide analysis
Introduce LazyLightClassDataHolder: which manages creation of Step 1 and Step 2 delegates
Introduce MemberIndex: keeping track of member creation order, helps matching light class delegates created in different contexts
KtLightMethod and Field: make use of dummy delegate
KtLightMethod no longer extends LightMethod since it requires eager delegate construction
KtLightMethod now implements PsiAnnotationMethod for convenience (ClsMethodImpl implements PsiAnnotationMethod)
Introduce LightClassDataHolder: which now is reponsible for constructing clsDelegate
Move out light big chunk of delegate building logic out of LightClassDataProvider into LightClassBuilder
LightClassData only holds information about single class
Consider this code:
object Delegate {
operator fun getValue(t: Any?, p: KProperty<*>): String {
return ""
}
}
class A {
val String.ext by Delegate
}
then the type of <p> is KProperty2 (it has 2 receivers).
Test fix + review fixes
Pass it in the CompilerConfiguration instead of LanguageVersionSettings.
This is better because LanguageVersionSettings is accessible everywhere
in front-end and back-end, and this flag should not be used there
Previously there were three LanguageFeature instances -- Coroutines,
DoNotWarnOnCoroutines and ErrorOnCoroutines -- which were handled very
awkwardly in the compiler and in the IDE to basically support a language
feature with a more complex state: not just enabled/disabled, but also
enabled with warning and enabled with error. Introduce a new enum
LanguageFeature.State for this and allow LanguageVersionSettings to get
the state of any language feature with 'getFeatureSupport'.
One noticeable drawback of this approach is that looking at the API, one
may assume that any language feature can be in one of the four states
(enabled, warning, error, disabled). This is not true however; there's
only one language feature at the moment (coroutines) for which these
intermediate states (warning, error) are handled in any way. This may be
refactored further by abstracting the logic that checks the language
feature availability so that it would work exactly the same for any
feature.
Another issue is that the difference among ENABLED_WITH_ERROR and
DISABLED is not clear. They are left as separate states because at the
moment, different diagnostics are reported in these two cases and
quick-fixes in IDE rely on that
Inject LanguageVersionSettings instead; all information relevant to the
analysis should be now passed via an instance of LanguageVersionSettings
(which should be renamed to a more general name in the future).
This is partially a revert of d499998 and related commits
This makes it possible to avoid the CompilerConfiguration instance in
injectors, because CompilerDeserializationConfiguration was the only
left component that required it.
LanguageVersionSettings is not a good name for this entity anymore, it
should be renamed in the future
This makes it possible to drop CompilerConfiguration from
CallCheckerContext, which in turn helps to avoid passing the entire
CompilerConfiguration instance through front-end
Previously JvmTarget was declared in module 'util' which is accessible
for example from 'frontend', which is not very good.
Also add a superinterface named TargetPlatformVersion which is going to
be used in platform-independent injectors in 'frontend' in the following
commits. Use it in one place (LanguageVersionSettingsProviderImpl.kt)
instead of DescriptionAware because TargetPlatformVersion sounds like a
better abstraction than DescriptionAware here
Before this change the check was quite complicated
because of cases like:
for (i in 1..9)
foo(i)<caret>
It's not located in a block, but in the same time it's a stament.
So we had a tricky heuristics that if is parent is not a block, then
we should check if element isn't used as expression.
Of course this heuristics is wrong, e.g. for import/package nodes.
The solution is to reuse similar logic from BasicExpressionTypingVisitor.
it has been checked once that statement container is one of:
- KtBlockExpression
- KtContainerNodeForControlStructureBody
- KtWhenEntry
So there's no need to check anything else
#KT-14986 Fixed
#KT-14483 Fixed