Compare commits

..

112 Commits

Author SHA1 Message Date
Ilya Gorbunov
994eceabc0 Deprecate dropWhileTo and takeWhileTo on CharSequences.
(cherry picked from commit 14f17e7)
2016-01-19 07:14:30 +03:00
Ilya Gorbunov
e46544cc5e Deprecate 'comparator { ... }' in favor of Comparator SAM-constructor. Provide SAM-like constructor for JS.
(cherry picked from commit 5bbce7a)
2016-01-19 07:14:18 +03:00
Ilya Gorbunov
c0668334b4 Move comparison related functions to kotlin.comparisons, update imports in stdlib.
(cherry picked from commit 67ef790)
2016-01-19 07:14:06 +03:00
Ilya Gorbunov
1ad2c6e4a7 Deprecate getOrImplicitDefault to make it private later.
(cherry picked from commit c250921)
2016-01-19 07:13:50 +03:00
Ilya Gorbunov
26b3c06963 Provide mutableSetOf and mutableMapOf
#KT-9663 Fixed
(cherry picked from commit aafd790)
2016-01-19 07:13:38 +03:00
Ilya Gorbunov
362f1641b8 Provide mutableListOf.
Deprecate linkedListOf.
#KT-9663
(cherry picked from commit fe8ba4d)
2016-01-19 07:13:27 +03:00
Stanislav Erokhin
889126cc25 Possible fix for KT-10603. 2016-01-18 19:47:12 +03:00
Mikhail Glukhikh
000b14d86e Diagnostic message fixed for 'PRIVATE_SETTER_FOR_OPEN_PROPERTY'
(cherry picked from commit 380e2dd)
2016-01-18 14:07:18 +03:00
Valentin Kipyatkov
258ae08a6e "Rename on import" hides importing of the same symbol by other imports with the original name
(cherry picked from commit 5a079de)
2016-01-18 13:11:05 +03:00
Valentin Kipyatkov
a0d9271e00 Do not use incorrect import
(cherry picked from commit 4704188)
2016-01-18 13:07:15 +03:00
Valentin Kipyatkov
3ceba38a78 Minor
(cherry picked from commit 866f3f1)
2016-01-18 13:07:05 +03:00
Valentin Kipyatkov
c28e9b0f3c Renamed class
(cherry picked from commit 8984368)
2016-01-18 13:06:53 +03:00
Mikhail Glukhikh
5b23a86f6e Cleanup: DataFlowAnalyzer, ignore MethodMayBeStatic for SmartCastManager
(cherry picked from commit c48c3fc)
2016-01-18 10:05:39 +03:00
Mikhail Glukhikh
8c1cd3a1ed Separate UNSAFE_IMPLICIT_INVOKE_CALL diagnostics introduced (see KT-8252)
(cherry picked from commit 6157ebe)
2016-01-18 10:05:30 +03:00
Mikhail Glukhikh
ab7c2cb82a Minor
(cherry picked from commit fe11b5a)
2016-01-18 10:05:14 +03:00
Mikhail Glukhikh
b707da415c Nullable function-like property call is prohibited now #KT-8252 Fixed
(cherry picked from commit 1049d4c)
2016-01-18 10:05:01 +03:00
Mikhail Glukhikh
ddfdff0b30 initialDataFlowInfoForArguments introduced in CallExpressionResolver methods #KT-10175 Fixed
(cherry picked from commit 0f80df7)
2016-01-18 10:03:47 +03:00
Mikhail Glukhikh
e7c81388b7 Get rid of MutableDataFlorInfoForArguments.setInitialDataFlowInfo
(cherry picked from commit 16d97ab)
2016-01-18 10:03:35 +03:00
Mikhail Glukhikh
b00d05ecad Minor refactoring of getQualifiedExpressionTypeInfo
(cherry picked from commit 5ceb973)
2016-01-18 10:03:15 +03:00
Pavel V. Talanov
f5ead3507a Avoid throwing on trying to obtain module info by some unexpected light element 2016-01-17 14:02:44 +03:00
Pavel V. Talanov
a4b9c32933 Analyze local variable declarations in expression position
Fixes exception on invalid code "val c = 1 < val Int.f: Int = 3"
2016-01-17 14:02:44 +03:00
Pavel V. Talanov
8839e9f707 Minor: prettify code after autoconversion 2016-01-17 14:02:43 +03:00
Pavel V. Talanov
4f9b441a66 Refactor: extract type checking code for local variables to a separate component, extract code that creates descriptors for local variable out of DescriptorResolver 2016-01-17 14:02:43 +03:00
Pavel V. Talanov
e4116624c3 AnnotationUtil: Do not throw on ErrorValue constant 2016-01-17 14:02:42 +03:00
Pavel V. Talanov
4dd91c0a81 Minor: fix missed error marker in test data 2016-01-17 14:02:42 +03:00
Pavel V. Talanov
47ad2370e3 Do not build light classes for local classes when the there is no class descriptor
These cases should be dealt with and this is only a way to degrade gracefully
2016-01-17 14:02:41 +03:00
Pavel V. Talanov
39598530d5 Parse local interfaces in expression position 2016-01-17 14:02:41 +03:00
Pavel V. Talanov
fa98553461 Create class descriptors for local classes in illegal positions
Typecheck code in illegal selector position
Fixes exceptions on "val p = A.class" erroneous code
2016-01-17 14:02:40 +03:00
Pavel V. Talanov
94369a24d5 Fix codegen predictor for properties and property accessors 2016-01-17 14:02:40 +03:00
Pavel V. Talanov
036828b923 Add and use KtPropertyAccessor#getProperty() 2016-01-17 14:02:39 +03:00
Pavel V. Talanov
5f27032bae IDELightClassGenerationSupport: fix a problem when marking source root as both source and library source led to SO
# KT-10413 Fixed
2016-01-17 14:02:39 +03:00
Pavel V. Talanov
cee7724d9f Minor, ProjectRootsUtil: extract a couple of utils and use them 2016-01-17 14:02:38 +03:00
Pavel V. Talanov
a86fcf1141 Add better diagnostic for "could not create stub for nested class" failures 2016-01-17 14:02:38 +03:00
Pavel V. Talanov
02262534db Fix an exception caused by objects literals in supertype list not considered local 2016-01-17 14:02:36 +03:00
Ilya Gorbunov
2706dd1d8e Annotate Iterable.forEach and Map.forEach with HidesMembers.
#KT-10538 Fixed
#KT-10479 Fixed
(cherry picked from commit 3d5e415)
2016-01-16 18:48:39 +03:00
Ilya Gorbunov
2b1b54bc28 Hide listFiles as it's no more preferred by overload resolution over synthetic SAM invocations.
#KT-10652 Fixed
(cherry picked from commit 56ddd49)
2016-01-16 17:51:23 +03:00
Ilya Gorbunov
0cd0f54b21 Rename defaultBufferSize to DEFAULT_BUFFER_SIZE.
(cherry picked from commit a64c1ff)
2016-01-16 17:51:00 +03:00
Ilya Gorbunov
24522175e5 J2K: Avoid to convert to deprecated String methods, namely toByteArray.
(cherry picked from commit ddcafdd)
2016-01-16 17:50:52 +03:00
Ilya Gorbunov
74d7d109b9 Deprecate functions taking charset name as string.
(cherry picked from commit ac15807)
2016-01-16 17:50:47 +03:00
Stanislav Erokhin
fe5df28123 Create new HidesMembers annotation 2016-01-15 23:39:44 +03:00
Dmitry Jemerov
62f92f2453 streamlined plugin update logic
(cherry picked from commit 63dd0fc)
2016-01-15 19:20:27 +01:00
Dmitry Jemerov
839c1d29d3 plugin autoupdate fixed: always provide plugin descriptor with new version number to plugin downloader
(cherry picked from commit 765d58b)
2016-01-15 19:20:16 +01:00
NataliaUkhorskaya
ecddf5ee20 Gradle plugin: fix compatibility with android-gradle plugin 2.0.0-alpha5
#KT-10676 Fixed
(cherry picked from commit d4fcb59)
2016-01-15 20:59:10 +03:00
Michael Bogdanov
b7b099e795 Prohibit super calls with default parameters
(cherry picked from commit 9b3d974)
2016-01-15 17:55:54 +03:00
Dmitry Petrov
292055276d KT-10646, KT-10647:
Move IMPLICIT_CAST_TO_UNIT_OR_ANY to ControlFlowInformationProvider
(where checks for 'if' and 'when' used as expressions are performed).
(cherry picked from commit f54de08)
2016-01-15 16:07:54 +03:00
Dmitry Petrov
90491cf683 KT-6646, KT-10482:
when a method (or a property getter) returns Nothing, emit
  ACONST_NULL
  ATHROW
after a call so that class files verifier knows that this is an exit point in a method.
Note that if an inline method returning Nothing throws an exception explicitly
(or via a chain of inline methods), this code will be deleted by DCE.
(cherry picked from commit b736880)
2016-01-15 16:07:53 +03:00
Dmitry Petrov
d4c55159bd Drop "substitute with upper bounds" mode for calls with mapped arguments
(we don't need it since we build constraint system for generic types).
Cleanup tests.
(cherry picked from commit 74c1390)
2016-01-15 16:07:53 +03:00
Dmitry Petrov
b7451c6e2b Check specificity relation for generant types of the constraint system.
Otherwise we can't properly chose between 'dynamic' and generic type.
(cherry picked from commit 4b3290d)
2016-01-15 16:07:53 +03:00
Dmitry Petrov
3941ac308d stdlib fixes:
- 'sequence(initialValue: T?, ...)' should have LowPriorityInOverloadResolution
(otherwise 'sequence({...}, {...})' is ambiguous).
- 'copyOf' and 'copyOfRange' should be defined for 'Array<T>' only
('Array<out T>' version always loses to 'Array<T>', since the second one
is always more specific).
(cherry picked from commit c97294a)
2016-01-15 16:07:53 +03:00
Dmitry Petrov
28f7ed010b Use constraint system for comparing for specificity against a generic signature.
Drop "discrimiate generics" mode where it's unneeded.
(cherry picked from commit 02daeac)
2016-01-15 16:07:52 +03:00
Yan Zhulanow
9a19322bac More precise diagnostic messages about "operator modifier is not applicable" 2016-01-15 20:14:27 +09:00
Yan Zhulanow
cca091991f "Inapplicable operator modifier" and "Inapplicable infix modifier" are now errors 2016-01-15 20:14:27 +09:00
Stanislav Erokhin
3933b8a48f Change resolution priority about implicit receivers and synthesized member-like descriptors.
Change resolution to consider extensions to implicit receiver before members of another implicit receiver.
Make synthesized member-like extensions resolve right after the members.

#KT-10510 Fixed
#KT-10219 Fixed
2016-01-14 21:37:39 +03:00
Stanislav Erokhin
a69bd11a77 Minor. Extract tower data creation to separate function. 2016-01-14 21:36:26 +03:00
Stanislav Erokhin
e3d45d22ac Move levels to TowerResolver 2016-01-14 21:36:25 +03:00
Zalim Bashorov
d6b04166c0 Don't fail when create IncrementalCacheImpl for target without output directory, and fail when try to use this info instead.
#KT-10505 Fixed
(cherry picked from commit c1dbfee)
2016-01-14 21:26:24 +03:00
Zalim Bashorov
dbcb91a118 Don't fail when output directory not specified for "friend" build target
#KT-10505 Fixed
(cherry picked from commit d9af947)
2016-01-14 21:25:52 +03:00
Zalim Bashorov
58b1cf42ae Report error when output directory not specified for build target
#KT-10505 Fixed
(cherry picked from commit 3df091e)
2016-01-14 21:25:39 +03:00
Valentin Kipyatkov
6221c76578 KT-10664 No code completion after variable initialized with elvis
#KT-10664 Fixed
(cherry picked from commit 7c6a33a)
2016-01-14 19:24:25 +03:00
Nikolay Krasko
7ffda5d985 Bootstrap against beta5 and temporary disable auto-increment 2016-01-14 17:24:16 +03:00
Mikhail Glukhikh
c40227d93f Implicit exhaustive whens now have exception in else branch #KT-8700 Fixed
(cherry picked from commit 7d6ccc4)
2016-01-14 16:30:31 +03:00
Mikhail Glukhikh
6b411b900e Implicit exhaustive when check for definite variable initialization (KT-8700)
(cherry picked from commit 011a9f2)
2016-01-14 16:30:28 +03:00
Mikhail Glukhikh
95cad01d97 ControlFlowInfo introduced to store variable states, related refactoring
(cherry picked from commit 52c3fb0)
2016-01-14 16:30:24 +03:00
Mikhail Glukhikh
0893dafab3 InitState / VariableUseState / VariableControlFlowState moved to a separate file
(cherry picked from commit 0f3997c)
2016-01-14 16:30:20 +03:00
Mikhail Glukhikh
118b619da3 PseudocodeVariablesData converted to Kotlin
(cherry picked from commit 4c4456c)
2016-01-14 16:30:16 +03:00
Mikhail Glukhikh
195bbfe1ba PseudocodeVariablesData.java --> PseudocodeVariablesData.kt
(cherry picked from commit 7179b37)
2016-01-14 16:30:12 +03:00
Mikhail Glukhikh
8dd3f438d8 Exhaustive whens without else and 'Nothing' as the result are considered 'implicit exhaustive'
(cherry picked from commit b938949)
2016-01-14 16:30:08 +03:00
Mikhail Glukhikh
741cdbe0a3 Introduced binding context storage for implicit exhaustive when (KT-8700)
(cherry picked from commit d62d7dd)
2016-01-14 16:30:04 +03:00
Mikhail Glukhikh
94b39326de CFG exhaustive when else instruction for KT-8700
(cherry picked from commit b805ce0)
2016-01-14 16:30:00 +03:00
Mikhail Glukhikh
c3432df3c8 Implemented missed checks for local functions #KT-10449 Fixed
Relevant code/test fixes
(cherry picked from commit 99a32b9)
2016-01-14 16:29:56 +03:00
Mikhail Glukhikh
c5a84077f0 Implicit callable type check refactoring, additional check for property with explicit Nothing type
(cherry picked from commit 15746cb)
2016-01-14 16:29:52 +03:00
Mikhail Glukhikh
7f36a3ea3a Intersection types are no more allowed in signatures #KT-10244 Fixed
(cherry picked from commit 6b8b39a)
2016-01-14 16:29:48 +03:00
Denis Zharkov
edf7200e5d Adjust type approximation to broken code and missing dependencies
- Do not run approximation if arguments number is different
- Add nullable Any? as supertype to MissingDependencyErrorClass

The latter is needed because otherwise TypeArgument.isConsistent became false
2016-01-14 15:38:07 +03:00
Denis Zharkov
8bf0f32b18 Fix supertypes calculation for types with projections
Use captured types as replacement for non top-level entries

 #KT-7296 Fixed
2016-01-14 15:38:06 +03:00
Denis Zharkov
9d08d51377 Fix captured approximation for case of flexible types
#KT-9294 Fixed
2016-01-14 15:38:05 +03:00
Denis Zharkov
fb09160d87 Make project compilable after member scope refinement 2016-01-14 15:38:05 +03:00
Denis Zharkov
30796c5dd2 Replace type entries of JsContext<*> with JsContext<JsNode>
It's needed to make method calls (e.g. replaceMe) on it typesafe,
otherwise it's value parameter type is subtype of captured
2016-01-14 15:38:04 +03:00
Denis Zharkov
69ba93fa16 Refine type from property setter parameter on assignment
In most cases these types are equals, the only known exception is
var-property contained in projected type member scope (see test data)
2016-01-14 15:38:04 +03:00
Denis Zharkov
bc06c0b264 Refine member scope for types with projections
Instead of erasing descriptors with conflicting substitution,
use invariant CapturedType(<projection>) as replacement for type parameter
within default member scope.

After substitution leave such types 'as is' everywhere except return types,
use common approximation for them.

 #KT-9294 In Progress
 #KT-5411 Fixed
 #KT-8647 Fixed

 #KT-9462 Fixed
 #KT-9893 Fixed
 #KT-7581 Fixed
 #KT-7296 In Progress
2016-01-14 15:38:03 +03:00
Denis Zharkov
009794dfd2 Extract and normalize member scope calculation
Basically it's wrong to use original types' member scope
as a worker for SubstitutionScope.
Member scope should always be determined by type constructor's default one
and substitution/arguments

 #KT-10448 Fixed
2016-01-14 15:38:00 +03:00
Denis Zharkov
cbaf84754c Minor. Add tests checking not-null assertions
More precisely these tests check cases when expected type
was somehow obtained from captured type (in member scope with projections)
2016-01-14 15:35:51 +03:00
Denis Zharkov
14d3208b7a Introduce CustomSubstitutionCapability.substitutionToComposeWith
Mainly it's needed to prevent creation of subsituions composition
everytime we replacing arguments, because it's both unoptimal and wrong

When replace arguments in `A<E, F>` with <String, E> you got `A<String, String>`
as a result, that is unexpected.

But composition is only needed when previous substituion was abnormal
(e.g. RawSubsitution that should actually wrap new arguments), see RawTypes tests
2016-01-14 15:35:51 +03:00
Denis Zharkov
9cfc11d0df Preserve type capabilities of captured type 2016-01-14 15:35:50 +03:00
Denis Zharkov
499ddeec82 Minor. Cleanup code 2016-01-14 15:35:50 +03:00
Denis Zharkov
63508c8e66 Minor. Move declaration closer to usages and optimize imports 2016-01-14 15:35:49 +03:00
Denis Zharkov
0e5b1ed884 Replace unchecked 'is' on local class with unchecked 'as'
It became unchecked after latest changes (see parent commit)
2016-01-14 15:35:48 +03:00
Denis Zharkov
8469003416 Fix type parameter list for local classes
Add captured parameters from enclosing functions

 #KT-9584 Fixed
2016-01-14 15:35:48 +03:00
Denis Zharkov
fb0e6c758d Clean project code after #KT-3996 fix
No overload resolution ambiguity in smart-casts
2016-01-14 15:35:47 +03:00
Denis Zharkov
7166b69c5f Fix wrong contract assumption
Currently SamAdapterOverridabilityCondition can be called
even for incompatible descriptors

 #KT-10486 Fixed
2016-01-14 15:35:47 +03:00
Nikolay Krasko
53f92f35d4 Remove assert that isn't valid in UpSource (UP-5742) 2016-01-12 21:41:54 +03:00
Michael Bogdanov
b4840bddc5 Always generate ACC_SUPER flag for all classes; Fix for KT-10260: java.lang.VerifyError in Android 4.x when Instant Run is used
#KT-10260 Fixed
(cherry picked from commit 0274ce4)
2016-01-11 13:02:34 +03:00
Pavel V. Talanov
3b253d10f3 Fix a problem caused by getting project using an invalid psi element 2015-12-23 16:47:40 +03:00
Yan Zhulanow
19c3382a19 Always compile Android projects without JDK in classpath #KT-10479 2015-12-23 16:43:47 +03:00
Dmitry Petrov
65a1c7b040 Fix KT-10472: compare all overloads including varargs in a single pass. 2015-12-22 17:10:55 +03:00
Stanislav Erokhin
0cffd955ea Hack for unavailable archive.apache.org: use bintray.com instead
(cherry picked from commit de6f520)
2015-12-22 16:47:43 +03:00
Nikolay Krasko
3847dd9794 Make add test lib quick-fix applicable only when there is unresolved import 2015-12-22 16:24:08 +03:00
Nikolay Krasko
bc5911e64b Add library for Gradle 2015-12-22 16:24:07 +03:00
Nikolay Krasko
6f96192e2f Determine maven library version from kotlin-stdlib 2015-12-22 16:24:07 +03:00
Nikolay Krasko
9f378345fc Add libraries to maven 2015-12-22 16:24:07 +03:00
Nikolay Krasko
760052b917 Add kotlin-test.jar to classpath quickfix 2015-12-22 16:24:07 +03:00
Sergey Mashkov
035fe187c1 kotlin-test: exclude OnlyInpuType from dist kotlin-test as well 2015-12-21 15:50:46 +03:00
Sergey Mashkov
e1a0caa27b kotlin-test: exclude OnlyInputTypes annotation from jar 2015-12-21 15:50:38 +03:00
Sergey Mashkov
e0061f5f37 rename kotlin.test to kotlin-test 2015-12-21 15:50:27 +03:00
Nikolay Krasko
128ddd5237 Enable version auto-increment and bootstrapping 2015-12-21 13:52:18 +03:00
Dmitry Petrov
b8094b2073 Prohibit functions (and constructors) with multiple vararg parameters.
(cherry picked from commit fab072e)
2015-12-21 13:28:27 +03:00
Andrey Breslav
e3924564ed Reserve "async* {}", extend the quick-fix 2015-12-21 07:07:15 +03:00
Andrey Breslav
3bb8d69760 Minor. Additional test for "async {}" 2015-12-21 07:07:15 +03:00
Stanislav Erokhin
c926c135ca Completion fix for reserved 'async' syntax 2015-12-21 07:07:15 +03:00
Nikolay Krasko
8714672ced Quick fix for deprecated async syntax 2015-12-21 07:07:15 +03:00
Ilya Gorbunov
bbc8941d76 Deprecate IndexingIterable and IndexingIterator and provide Iterator.withIndex() instead of the latter. 2015-12-19 09:58:28 +03:00
Ilya Gorbunov
2a18ab2d76 Deprecate some top-level constants to make 'em private later. 2015-12-19 09:58:26 +03:00
Ilya Chernikov
280c41a64d Working around cancellation-related exception in case of different versions of daemon and client 2015-12-18 22:20:59 +01:00
6180 changed files with 54124 additions and 85879 deletions

View File

@@ -24,7 +24,6 @@
<element id="module-output" name="deserialization" />
<element id="extracted-dir" path="$PROJECT_DIR$/dependencies/native-platform-uberjar.jar" path-in-jar="/" />
<element id="module-output" name="android-jps-plugin" />
<element id="module-output" name="build-common" />
</root>
</artifact>
</component>

View File

@@ -2,9 +2,8 @@
<dictionary name="bashor">
<words>
<w>ctor</w>
<w>interner</w>
<w>lookups</w>
<w>unescape</w>
</words>
</dictionary>
</component>
</component>

View File

@@ -1,8 +0,0 @@
<component name="ProjectDictionaryState">
<dictionary name="dzharkov">
<words>
<w>checkcast</w>
<w>insn</w>
</words>
</dictionary>
</component>

6
.idea/kotlinc.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinCompilerSettings">
<option name="additionalArguments" value="-version -Xallow-kotlin-package -Xskip-metadata-version-check" />
</component>
</project>

View File

@@ -2,343 +2,17 @@
<library name="idea-full">
<ANNOTATIONS>
<root url="file://$PROJECT_DIR$/annotations" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/lib" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
</ANNOTATIONS>
<CLASSES>
<root url="file://$PROJECT_DIR$/ideaSDK/lib" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/antLayout/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-impl/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/jps-builders/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/jps-builders/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/standalone-builder/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-serialization/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-serialization/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/impl/resources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/tests/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/relaxng/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/relaxng/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/dom-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/dom-tests/tests" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/dom-openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/xml-psi-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/xml-psi-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/idea-ui/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/jsp-spi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/compiler/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/compiler/impl/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/compiler/javac2/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/compiler/openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/compiler/forms-compiler/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/compiler/forms-compiler/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/compiler/instrumentation-util/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/debugger/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/debugger/openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/manifest/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/manifest/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/execution/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/execution/openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-tests/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/jsp-openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-psi-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-runtime/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-psi-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/testFramework/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/remote-servers/api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/remote-servers/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/jsp-base-openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-analysis-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-indexing-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-analysis-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-indexing-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/build/cucumber-test-runner/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/tools/lexer/jflex-1.4/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/tools/lexer/jflex-1.4/examples/cup" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/tools/lexer/jflex-1.4/examples/java" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/tools/lexer/jflex-1.4/examples/binary" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/tools/lexer/jflex-1.4/examples/simple" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/tools/lexer/jflex-1.4/examples/interpreter" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/tools/launcher-generator/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/images/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ant/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ant/tests/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ant/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ant/jps-plugin/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/cvs/cvs-core/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/cvs/cvs-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/cvs/javacvs-src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/cvs/smartcvs-src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/cvs/trilead-ssh2-build213/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/cvs/trilead-ssh2-build213/examples" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/junit/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/src/main/java" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/src/test/java" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/jps-plugin/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/maven-server-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/maven2-server-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/maven2-server-impl/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/artifact-resolver-m2/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/artifact-resolver-m3/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/tasks/tasks-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/tasks/tasks-core/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/tasks/tasks-java/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/tasks/tasks-tests/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xpath/xslt-rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xpath/xpath-lang/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xpath/xpath-lang/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xpath/xpath-view/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/devkit/resources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/devkit/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/devkit/jps-plugin/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/github/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/github/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/gradle/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/gradle/testSources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/hotswap/agentSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/rt-constants/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/javaFX/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/javaFX/javaFX-CE/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/javaFX/javaFX-jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/javaFX/common-javaFX-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/testng/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/testng/testSources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/eclipse/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/eclipse/resources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/eclipse/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/eclipse/testSources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/hg4idea/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/hg4idea/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/git4idea/rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/git4idea/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/git4idea/tests" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/git4idea/resources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/git4idea/test-stepdefs" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/junit_rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/svn4idea/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/svn4idea/resources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/svn4idea/testSource" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/terminal/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/terminal/resources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/commander/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/copyright/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/java-i18n/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/java-i18n/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/testng_rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/properties/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/properties/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntelliLang/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntelliLang/xml-support" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntelliLang/java-support" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntelliLang/IntelliLang-tests/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntelliLang/intellilang-jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ui-designer/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ui-designer/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ui-designer/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ui-designer/jps-plugin/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xslt-debugger/rt/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xslt-debugger/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xslt-debugger/engine/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xslt-debugger/engine/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ByteCodeViewer/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ui-designer-core/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/InspectionGadgets/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/InspectionGadgets/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/InspectionGadgets/testsrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntentionPowerPak/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntentionPowerPak/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntentionPowerPak/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/generate-tostring/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/generate-tostring/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/google-app-engine/source" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/google-app-engine/runtime/source" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/google-app-engine/resources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/google-app-engine/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/google-app-engine/jps-plugin/testSource" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/google-app-engine/testSource" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/cucumber-jvm-formatter/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/samples/comparingReferences/source" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/samples/comparingReferences/testSource" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/samples/conditionalOperatorConvertor/source" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/samples/conditionalOperatorConvertor/testSource" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/updater/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/boot/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/util/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/util/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/util-rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/core-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/forms_rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/lang-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/lang-api/testSources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/lvcs-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/smRunner/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/smRunner/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-impl/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/bootstrap/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/core-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/funcTests/project1/module1/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/lang-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/lang-impl/testSources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/lvcs-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/usageView/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/extensions/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/extensions/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/testRunner/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/analysis-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/indexing-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/platform-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/analysis-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/editor-ui-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/editor-ui-ex/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/indexing-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/platform-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/platform-main/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/testFramework/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/testFramework/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/testFramework/bootstrap/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/xdebugger-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/platform-tests/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/remote-servers/api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/remote-servers/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/xdebugger-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/xdebugger-impl/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/projectModel-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/projectModel-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/external-system-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/external-system-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/external-system-impl/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/spellchecker/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/spellchecker/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/RegExpSupport/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/RegExpSupport/test" />
<root url="jar://$PROJECT_DIR$/dependencies/guava-17.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
<root url="jar://$PROJECT_DIR$/dependencies/cli-parser-1.1.1-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/build/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-impl/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-psi-impl/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-structure-view/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/structuralsearch-java/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/typeMigration/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/typeMigration/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/jps-launcher/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/plugin-system/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/json/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/json/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/json/tests/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/annotations/common/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/annotations/java5/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/annotations/java8/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/built-in-server-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/built-in-server/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/configuration-store-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/diff-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/diff-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/duplicates-analysis/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/dvcs-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/dvcs-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/lang-impl/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/remote-servers/agent-rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/script-debugger/backend/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/script-debugger/debugger-ui/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/script-debugger/debugger-ui/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/script-debugger/protocol/protocol-reader-runtime/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/structuralsearch/source" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/structuralsearch/testSource" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/structure-view-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/structure-view-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-api/vcs-api-core/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-log/api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-log/graph-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-log/graph/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-log/graph/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-log/impl/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-log/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-log/impl/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ShortcutPromoter/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/coverage-common/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/coverage/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/coverage/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/devkit/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/eclipse/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/editorconfig/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/git4idea/remote-servers-git/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/google-app-engine/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/gradle/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/gradle/tooling-extension-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/gradle/tooling-extension-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/gradle/tooling-extension-impl/testSources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/groovy-psi/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/groovy-psi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/structuralsearch-groovy/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/structuralsearch-groovy/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/java-decompiler/engine/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/java-decompiler/engine/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/java-decompiler/plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/java-decompiler/plugin/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/javaFX/FxBuilderEmbedder/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/junit/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/artifact-resolver-m31/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/artifact-resolver/common/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/maven3-server-common/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/maven30-server-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/maven32-server-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/properties/properties-psi-api/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/properties/properties-psi-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/properties/properties-psi-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/settings-repository/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/tasks/tasks-core/jira/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/tasks/tasks-core/jira/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/IntelliLang-python/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/edu/course-creator-intellij-py/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/edu/course-creator-python/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/edu/course-creator-python/tests" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/edu/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/edu/interactive-learning-intellij-py/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/edu/interactive-learning-python/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/edu/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/educational/course-creator/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/educational/interactive-learning-intellij/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/educational/interactive-learning/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/educational/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/ide/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/ipnb/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/ipnb/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/pluginSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/pluginTestSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/psi-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/pydevSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/python-rest/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/python-rest/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/rest/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/rest/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/updater/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/xml-analysis-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/xml-analysis-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/xml-psi-impl/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/xml-structure-view-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/xml-structure-view-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/lib" recursive="false" />
</library>

View File

@@ -2,9 +2,7 @@
<library name="intellij-core">
<ANNOTATIONS>
<root url="file://$PROJECT_DIR$/annotations" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/lib" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
</ANNOTATIONS>
<CLASSES>
<root url="file://$PROJECT_DIR$/ideaSDK/core" />
@@ -13,325 +11,7 @@
<SOURCES>
<root url="jar://$PROJECT_DIR$/dependencies/guava-17.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/RegExpSupport/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/build/cucumber-test-runner/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/build/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/images/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/compiler/forms-compiler/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/compiler/forms-compiler/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/compiler/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/compiler/impl/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/compiler/instrumentation-util/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/compiler/javac2/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/compiler/openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/debugger/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/debugger/openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/execution/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/execution/openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/idea-ui/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-analysis-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-analysis-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-impl/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-indexing-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-indexing-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-psi-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-psi-impl/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-psi-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-runtime/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-structure-view/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/java-tests/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/jsp-base-openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/jsp-openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/jsp-spi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/manifest/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/manifest/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/remote-servers/api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/remote-servers/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/structuralsearch-java/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/testFramework/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/typeMigration/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/java/typeMigration/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/antLayout/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/jps-builders/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/jps-builders/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/jps-launcher/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-impl/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-serialization/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-serialization/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/plugin-system/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/standalone-builder/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/json/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/json/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/json/tests/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/analysis-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/analysis-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/annotations/common/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/annotations/java5/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/annotations/java8/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/boot/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/bootstrap/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/built-in-server-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/built-in-server/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/configuration-store-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/core-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/core-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/diff-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/diff-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/duplicates-analysis/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/dvcs-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/dvcs-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/editor-ui-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/editor-ui-ex/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/extensions/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/extensions/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/external-system-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/external-system-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/external-system-impl/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/forms_rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/funcTests/project1/module1/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/indexing-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/indexing-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/lang-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/lang-api/testSources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/lang-impl/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/lang-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/lang-impl/testSources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/lvcs-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/lvcs-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/platform-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/platform-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/platform-main/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/platform-tests/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/projectModel-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/projectModel-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/remote-servers/agent-rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/remote-servers/api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/remote-servers/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/script-debugger/backend/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/script-debugger/debugger-ui/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/script-debugger/debugger-ui/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/script-debugger/protocol/protocol-reader-runtime/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/smRunner/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/smRunner/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/structuralsearch/source" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/structuralsearch/testSource" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/structure-view-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/structure-view-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/testFramework/bootstrap/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/testFramework/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/testFramework/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/testRunner/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/usageView/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/util-rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/util/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/util/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-api/vcs-api-core/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-impl/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-log/api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-log/graph-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-log/graph/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-log/graph/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-log/impl/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-log/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/vcs-log/impl/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/xdebugger-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/xdebugger-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/platform/xdebugger-impl/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ByteCodeViewer/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/InspectionGadgets/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/InspectionGadgets/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/InspectionGadgets/testsrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntelliLang/IntelliLang-tests/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntelliLang/intellilang-jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntelliLang/java-support" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntelliLang/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntelliLang/xml-support" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntentionPowerPak/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntentionPowerPak/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/IntentionPowerPak/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ShortcutPromoter/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ant/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ant/jps-plugin/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ant/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ant/tests/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/commander/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/copyright/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/coverage-common/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/coverage/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/coverage/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/cucumber-jvm-formatter/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/cvs/cvs-core/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/cvs/cvs-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/cvs/javacvs-src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/cvs/smartcvs-src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/cvs/trilead-ssh2-build213/examples" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/cvs/trilead-ssh2-build213/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/devkit/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/devkit/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/devkit/jps-plugin/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/eclipse/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/eclipse/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/eclipse/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/eclipse/testSources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/editorconfig/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/generate-tostring/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/generate-tostring/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/git4idea/remote-servers-git/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/git4idea/resources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/git4idea/rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/git4idea/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/git4idea/test-stepdefs" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/git4idea/tests" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/github/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/github/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/google-app-engine/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/google-app-engine/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/google-app-engine/jps-plugin/testSource" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/google-app-engine/runtime/source" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/google-app-engine/source" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/google-app-engine/testSource" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/gradle/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/gradle/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/gradle/testSources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/gradle/tooling-extension-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/gradle/tooling-extension-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/gradle/tooling-extension-impl/testSources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/groovy-psi/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/groovy-psi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/hotswap/agentSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/rt-constants/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/structuralsearch-groovy/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/structuralsearch-groovy/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/groovy/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/hg4idea/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/hg4idea/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/java-decompiler/engine/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/java-decompiler/engine/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/java-decompiler/plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/java-decompiler/plugin/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/java-i18n/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/java-i18n/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/javaFX/FxBuilderEmbedder/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/javaFX/common-javaFX-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/javaFX/javaFX-CE/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/javaFX/javaFX-jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/javaFX/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/junit/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/junit/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/junit_rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/artifact-resolver-m2/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/artifact-resolver-m31/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/artifact-resolver-m3/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/artifact-resolver/common/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/jps-plugin/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/maven-server-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/maven2-server-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/maven2-server-impl/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/maven3-server-common/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/maven30-server-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/maven32-server-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/src/main/java" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/maven/src/test/java" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/properties/properties-psi-api/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/properties/properties-psi-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/properties/properties-psi-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/properties/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/properties/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/settings-repository/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/svn4idea/resources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/svn4idea/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/svn4idea/testSource" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/tasks/tasks-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/tasks/tasks-core/jira/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/tasks/tasks-core/jira/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/tasks/tasks-core/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/tasks/tasks-java/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/tasks/tasks-tests/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/terminal/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/testng/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/testng/testSources" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/testng_rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ui-designer-core/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ui-designer/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ui-designer/jps-plugin/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ui-designer/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/ui-designer/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xpath/xpath-lang/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xpath/xpath-lang/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xpath/xpath-view/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xpath/xslt-rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xslt-debugger/engine/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xslt-debugger/engine/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xslt-debugger/rt/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/plugins/xslt-debugger/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/IntelliLang-python/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/edu/course-creator-intellij-py/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/edu/course-creator-python/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/edu/course-creator-python/tests" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/edu/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/edu/interactive-learning-intellij-py/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/edu/interactive-learning-python/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/edu/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/educational/course-creator/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/educational/interactive-learning-intellij/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/educational/interactive-learning/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/educational/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/ide/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/ipnb/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/ipnb/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/pluginSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/pluginTestSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/psi-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/pydevSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/python-rest/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/python-rest/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/rest/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/rest/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/python/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/samples/comparingReferences/source" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/samples/comparingReferences/testSource" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/samples/conditionalOperatorConvertor/source" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/samples/conditionalOperatorConvertor/testSource" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/spellchecker/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/spellchecker/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/tools/launcher-generator/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/tools/lexer/jflex-1.4/examples/binary" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/tools/lexer/jflex-1.4/examples/cup" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/tools/lexer/jflex-1.4/examples/interpreter" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/tools/lexer/jflex-1.4/examples/java" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/tools/lexer/jflex-1.4/examples/simple" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/tools/lexer/jflex-1.4/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/updater/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/updater/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/dom-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/dom-openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/dom-tests/tests" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/relaxng/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/relaxng/test" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/tests/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/xml-analysis-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/xml-analysis-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/xml-psi-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/xml-psi-impl/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/xml-psi-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/xml-structure-view-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/xml/xml-structure-view-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/core" recursive="false" />
</library>

View File

@@ -1,9 +0,0 @@
<component name="libraryTable">
<library name="kotlin-reflect">
<CLASSES>
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -2,12 +2,11 @@
<library name="kotlin-runtime">
<CLASSES>
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-runtime.jar!/" />
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/libraries/stdlib/src" />
<root url="file://$PROJECT_DIR$/core/builtins/native" />
<root url="file://$PROJECT_DIR$/core/builtins/src" />
</SOURCES>
</library>
</component>

3
.idea/modules.xml generated
View File

@@ -13,7 +13,6 @@
<module fileurl="file://$PROJECT_DIR$/compiler/backend/backend.iml" filepath="$PROJECT_DIR$/compiler/backend/backend.iml" group="compiler/java" />
<module fileurl="file://$PROJECT_DIR$/compiler/backend-common/backend-common.iml" filepath="$PROJECT_DIR$/compiler/backend-common/backend-common.iml" group="compiler" />
<module fileurl="file://$PROJECT_DIR$/jps-plugin/bare-plugin/bare-plugin.iml" filepath="$PROJECT_DIR$/jps-plugin/bare-plugin/bare-plugin.iml" group="ide/jps" />
<module fileurl="file://$PROJECT_DIR$/build-common/build-common.iml" filepath="$PROJECT_DIR$/build-common/build-common.iml" />
<module fileurl="file://$PROJECT_DIR$/core/builtins/builtins.iml" filepath="$PROJECT_DIR$/core/builtins/builtins.iml" group="core" />
<module fileurl="file://$PROJECT_DIR$/compiler/builtins-serializer/builtins-serializer.iml" filepath="$PROJECT_DIR$/compiler/builtins-serializer/builtins-serializer.iml" group="compiler/cli" />
<module fileurl="file://$PROJECT_DIR$/compiler/cli/cli.iml" filepath="$PROJECT_DIR$/compiler/cli/cli.iml" group="compiler/cli" />
@@ -68,4 +67,4 @@
<module fileurl="file://$PROJECT_DIR$/core/util.runtime/util.runtime.iml" filepath="$PROJECT_DIR$/core/util.runtime/util.runtime.iml" group="core" />
</modules>
</component>
</project>
</project>

View File

@@ -15,7 +15,7 @@
<method>
<option name="Make" enabled="false" />
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/build.xml" target="clean_idea_output" />
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/update_dependencies.xml" target="update_teamcity" />
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/update_dependencies.xml" target="update" />
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/build.xml" target="dist" />
<option name="MakeProject" enabled="true" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Generate Tests" run_configuration_type="Application" />

View File

@@ -18,6 +18,7 @@
<property name="plugin.zip" value="${artifact.output.path}/kotlin-plugin-${build.number}.zip"/>
<property name="bare.plugin.zip" value="${artifact.output.path}/kotlin-bare-plugin-${build.number}.zip"/>
<property name="android-extensions.zip" value="${artifact.output.path}/kotlin-android-extensions-plugin-${build.number}.zip"/>
<property name="kotlin.bare.plugin.xml" value="jps-plugin/bare-plugin/src/META-INF/plugin.xml"/>
<property name="kotlin.bare.plugin.xml.bk" value="${version_substitute_dir}/kotlin.bare.plugin.xml.bk"/>
@@ -126,6 +127,10 @@
<zipPlugin filename="${plugin.zip}" dir="Kotlin"/>
<zipPlugin filename="${bare.plugin.zip}" dir="BareKotlin"/>
<zip destfile="${android-extensions.zip}">
<zipfileset prefix="META-INF" dir="${basedir}/plugins/android-idea-plugin/old_plugin" includes="plugin.xml" />
</zip>
</target>
<macrodef name="print-statistic">

View File

@@ -9,7 +9,6 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="ant" level="project" />
<orderEntry type="library" name="kotlin-runtime" level="project" />
<orderEntry type="library" name="kotlin-reflect" level="project" />
<orderEntry type="module" module-name="preloader" />
</component>
</module>

View File

@@ -0,0 +1,7 @@
<!-- NOTE: this Antlib is deprecated. Use org/jetbrains/kotlin/ant/antlib.xml instead -->
<!-- TODO: delete this file -->
<antlib>
<taskdef name="kotlinc" classname="org.jetbrains.kotlin.ant.Kotlin2JvmTask"/>
<taskdef name="kotlin2js" classname="org.jetbrains.kotlin.ant.Kotlin2JsTask"/>
<typedef name="withKotlin" classname="org.jetbrains.kotlin.ant.KotlinCompilerAdapter"/>
</antlib>

View File

@@ -19,22 +19,22 @@ package org.jetbrains.kotlin.ant
import org.apache.tools.ant.types.Path
import java.io.File
class Kotlin2JsTask : KotlinCompilerBaseTask() {
public class Kotlin2JsTask : KotlinCompilerBaseTask() {
override val compilerFqName = "org.jetbrains.kotlin.cli.js.K2JSCompiler"
var library: Path? = null
var outputPrefix: File? = null
var outputPostfix: File? = null
var sourceMap: Boolean = false
var metaInfo: Boolean = false
public var library: Path? = null
public var outputPrefix: File? = null
public var outputPostfix: File? = null
public var sourceMap: Boolean = false
public var metaInfo: Boolean = false
/**
* {@link K2JsArgumentConstants.CALL} (default) if need generate a main function call (main function will be auto detected)
* {@link K2JsArgumentConstants.NO_CALL} otherwise.
*/
var main: String? = null
public var main: String? = null
fun createLibrary(): Path {
public fun createLibrary(): Path {
val libraryPath = library
if (libraryPath == null) {
val t = Path(getProject())

View File

@@ -20,15 +20,15 @@ import org.apache.tools.ant.types.Path
import org.apache.tools.ant.types.Reference
import java.io.File.pathSeparator
class Kotlin2JvmTask : KotlinCompilerBaseTask() {
public class Kotlin2JvmTask : KotlinCompilerBaseTask() {
override val compilerFqName = "org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"
var includeRuntime: Boolean = true
var moduleName: String? = null
public var includeRuntime: Boolean = true
public var moduleName: String? = null
private var compileClasspath: Path? = null
fun setClasspath(classpath: Path) {
public fun setClasspath(classpath: Path) {
if (compileClasspath == null) {
compileClasspath = classpath
}
@@ -37,14 +37,14 @@ class Kotlin2JvmTask : KotlinCompilerBaseTask() {
}
}
fun setClasspathRef(ref: Reference) {
public fun setClasspathRef(ref: Reference) {
if (compileClasspath == null) {
compileClasspath = Path(getProject())
}
compileClasspath!!.createPath().refid = ref
compileClasspath!!.createPath().setRefid(ref)
}
fun addConfiguredClasspath(classpath: Path) {
public fun addConfiguredClasspath(classpath: Path) {
setClasspath(classpath)
}

View File

@@ -29,12 +29,12 @@ object KotlinAntTaskUtil {
private val libPath: File by lazy {
// Find path of kotlin-ant.jar in the filesystem and find kotlin-compiler.jar in the same directory
val resourcePath = "/" + javaClass.name.replace('.', '/') + ".class"
val resourcePath = "/" + javaClass.getName().replace('.', '/') + ".class"
val jarConnection = javaClass.getResource(resourcePath).openConnection() as? JarURLConnection
?: throw UnsupportedOperationException("Kotlin compiler Ant task should be loaded from the JAR file")
val antTaskJarPath = File(jarConnection.jarFileURL.toURI())
val antTaskJarPath = File(jarConnection.getJarFileURL().toURI())
antTaskJarPath.parentFile
antTaskJarPath.getParentFile()
}
val compilerJar: File by lazy {
@@ -47,7 +47,7 @@ object KotlinAntTaskUtil {
private fun File.assertExists(): File {
if (!this.exists()) {
throw IllegalStateException("${name} is not found in the directory of Kotlin Ant task")
throw IllegalStateException("${getName()} is not found in the directory of Kotlin Ant task")
}
return this
}
@@ -68,5 +68,5 @@ object KotlinAntTaskUtil {
}
val Task.defaultModuleName: String?
public val Task.defaultModuleName: String?
get() = owningTarget?.name ?: project?.name

View File

@@ -70,7 +70,7 @@ class KotlinCompilerAdapter : Javac13() {
// Javac13#execute passes everything in compileList to javac, which doesn't recognize .kt files
val compileListForJavac = filterOutKotlinSources(compileList)
val hasKotlinFilesInSources = compileListForJavac.size < compileList.size
val hasKotlinFilesInSources = compileListForJavac.size() < compileList.size()
if (hasKotlinFilesInSources) {
kotlinc.execute()

View File

@@ -24,25 +24,25 @@ import org.apache.tools.ant.types.Reference
import java.io.File
import java.io.PrintStream
abstract class KotlinCompilerBaseTask : Task() {
public abstract class KotlinCompilerBaseTask : Task() {
protected abstract val compilerFqName: String
val args: MutableList<String> = arrayListOf()
public val args: MutableList<String> = arrayListOf()
var src: Path? = null
var output: File? = null
var nowarn: Boolean = false
var verbose: Boolean = false
var printVersion: Boolean = false
var failOnError: Boolean = true
public var src: Path? = null
public var output: File? = null
public var nowarn: Boolean = false
public var verbose: Boolean = false
public var printVersion: Boolean = false
public var failOnError: Boolean = true
var noStdlib: Boolean = false
public var noStdlib: Boolean = false
val additionalArguments: MutableList<Commandline.Argument> = arrayListOf()
public val additionalArguments: MutableList<Commandline.Argument> = arrayListOf()
var exitCode: Int? = null
public var exitCode: Int? = null
fun createSrc(): Path {
public fun createSrc(): Path {
val srcPath = src
if (srcPath == null) {
val t = Path(getProject())
@@ -53,11 +53,11 @@ abstract class KotlinCompilerBaseTask : Task() {
return srcPath.createPath()
}
fun setSrcRef(ref: Reference) {
createSrc().refid = ref
public fun setSrcRef(ref: Reference) {
createSrc().setRefid(ref)
}
fun createCompilerArg(): Commandline.Argument {
public fun createCompilerArg(): Commandline.Argument {
val argument = Commandline.Argument()
additionalArguments.add(argument)
return argument
@@ -65,7 +65,7 @@ abstract class KotlinCompilerBaseTask : Task() {
abstract fun fillSpecificArguments()
fun fillArguments() {
public fun fillArguments() {
val sourcePaths = src ?: throw BuildException("\"src\" should be specified")
args.addAll(sourcePaths.list().map { File(it).canonicalPath })
@@ -75,7 +75,7 @@ abstract class KotlinCompilerBaseTask : Task() {
if (verbose) args.add("-verbose")
if (printVersion) args.add("-version")
args.addAll(additionalArguments.flatMap { it.parts.toList() })
args.addAll(additionalArguments.flatMap { it.getParts().toList() })
fillSpecificArguments()
}
@@ -85,12 +85,12 @@ abstract class KotlinCompilerBaseTask : Task() {
val compilerClass = KotlinAntTaskUtil.getOrCreateClassLoader().loadClass(compilerFqName)
val compiler = compilerClass.newInstance()
val exec = compilerClass.getMethod("execFullPathsInMessages", PrintStream::class.java, Array<String>::class.java)
val exec = compilerClass.getMethod("execFullPathsInMessages", javaClass<PrintStream>(), javaClass<Array<String>>())
log("Compiling ${src!!.list().toList()} => [${output!!.canonicalPath}]");
val result = exec(compiler, System.err, args.toTypedArray())
exitCode = (result as Enum<*>).ordinal
exitCode = (result as Enum<*>).ordinal()
if (failOnError && exitCode != 0) {
throw BuildException("Compile failed; see the compiler error output for details.")

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="frontend.java" />
<orderEntry type="module" module-name="util.runtime" />
<orderEntry type="module" module-name="cli-common" />
<orderEntry type="module" module-name="util" />
<orderEntry type="module" module-name="compiler-tests" scope="TEST" />
<orderEntry type="library" scope="TEST" name="idea-full" level="project" />
</component>
</module>

View File

@@ -1,40 +0,0 @@
/*
* Copyright 2010-2015 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 org.jetbrains.kotlin.build
import org.jetbrains.kotlin.incremental.LocalFileKotlinClass
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
import org.jetbrains.kotlin.utils.sure
import java.io.File
open class GeneratedFile<Target>(
val target: Target,
val sourceFiles: Collection<File>,
val outputFile: File
)
class GeneratedJvmClass<Target> (
target: Target,
sourceFiles: Collection<File>,
outputFile: File
) : GeneratedFile<Target>(target, sourceFiles, outputFile) {
val outputClass = LocalFileKotlinClass.create(outputFile).sure {
"Couldn't load KotlinClass from $outputFile; it may happen because class doesn't have valid Kotlin annotations"
}
}
fun File.isModuleMappingFile() = extension == ModuleMapping.MAPPING_FILE_EXT && parentFile.name == "META-INF"

View File

@@ -1,131 +0,0 @@
/*
* Copyright 2010-2015 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 org.jetbrains.kotlin.modules
import com.intellij.openapi.util.io.FileUtil.toSystemIndependentName
import com.intellij.openapi.util.text.StringUtil.escapeXml
import org.jetbrains.kotlin.build.JvmSourceRoot
import org.jetbrains.kotlin.cli.common.modules.ModuleXmlParser.*
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.utils.Printer
import java.io.File
class KotlinModuleXmlBuilder {
private val xml = StringBuilder()
private val p = Printer(xml)
private var done = false
init {
openTag(p, MODULES)
}
fun addModule(
moduleName: String,
outputDir: String,
sourceFiles: Iterable<File>,
javaSourceRoots: Iterable<JvmSourceRoot>,
classpathRoots: Iterable<File>,
targetTypeId: String,
isTests: Boolean,
directoriesToFilterOut: Set<File>,
friendDirs: Iterable<File>): KotlinModuleXmlBuilder {
assert(!done) { "Already done" }
p.println("<!-- Module script for ${if (isTests) "tests" else "production"} -->")
p.println("<", MODULE, " ",
NAME, "=\"", escapeXml(moduleName), "\" ",
TYPE, "=\"", escapeXml(targetTypeId), "\" ",
OUTPUT_DIR, "=\"", getEscapedPath(File(outputDir)), "\">")
p.pushIndent()
for (friendDir in friendDirs) {
p.println("<", FRIEND_DIR, " ", PATH, "=\"", getEscapedPath(friendDir), "\"/>")
}
for (sourceFile in sourceFiles) {
p.println("<", SOURCES, " ", PATH, "=\"", getEscapedPath(sourceFile), "\"/>")
}
processJavaSourceRoots(javaSourceRoots)
processClasspath(classpathRoots, directoriesToFilterOut)
closeTag(p, MODULE)
return this
}
private fun processClasspath(
files: Iterable<File>,
directoriesToFilterOut: Set<File>) {
p.println("<!-- Classpath -->")
for (file in files) {
val isOutput = directoriesToFilterOut.contains(file) && !IncrementalCompilation.isEnabled()
if (isOutput) {
// For IDEA's make (incremental compilation) purposes, output directories of the current module and its dependencies
// appear on the class path, so we are at risk of seeing the results of the previous build, i.e. if some class was
// removed in the sources, it may still be there in binaries. Thus, we delete these entries from the classpath.
p.println("<!-- Output directory, commented out -->")
p.println("<!-- ")
p.pushIndent()
}
p.println("<", CLASSPATH, " ", PATH, "=\"", getEscapedPath(file), "\"/>")
if (isOutput) {
p.popIndent()
p.println("-->")
}
}
}
private fun processJavaSourceRoots(roots: Iterable<JvmSourceRoot>) {
p.println("<!-- Java source roots -->")
for (root in roots) {
p.print("<")
p.printWithNoIndent(JAVA_SOURCE_ROOTS, " ", PATH, "=\"", getEscapedPath(root.file), "\"")
if (root.packagePrefix != null) {
p.printWithNoIndent(" ", JAVA_SOURCE_PACKAGE_PREFIX, "=\"", root.packagePrefix, "\"")
}
p.printWithNoIndent("/>")
p.println()
}
}
fun asText(): CharSequence {
if (!done) {
closeTag(p, MODULES)
done = true
}
return xml
}
private fun openTag(p: Printer, tag: String) {
p.println("<$tag>")
p.pushIndent()
}
private fun closeTag(p: Printer, tag: String) {
p.popIndent()
p.println("</$tag>")
}
private fun getEscapedPath(sourceFile: File): String {
return escapeXml(toSystemIndependentName(sourceFile.path))
}
}

202
build.xml
View File

@@ -6,9 +6,6 @@
<!-- Set to false to disable compiler's javadoc generation. Speeds up the build -->
<property name="generate.javadoc" value="true"/>
<!-- Set to false to prevent jarjar and metadata stripping on kotlin-reflect.jar and reflection sources. Use to debug reflection -->
<property name="obfuscate.reflect" value="true"/>
<property name="max.heap.size.for.forked.jvm" value="1024m"/>
<property name="bootstrap.home" value="${basedir}/dependencies/bootstrap-compiler"/>
@@ -489,6 +486,7 @@
<fileset dir="${output}/classes/compiler"/>
<fileset dir="${output}/builtins">
<include name="kotlin/**"/>
<exclude name="kotlin/internal/**"/>
</fileset>
<fileset dir="${basedir}/core/descriptor.loader.java/src" includes="META-INF/services/**"/>
<fileset dir="${basedir}/compiler/frontend.java/src" includes="META-INF/services/**"/>
@@ -552,7 +550,6 @@
source="${java.target}" target="${java.target}">
<withKotlin modulename="kotlin-compiler"/>
<skip pattern="kotlin/jvm/internal/.*"/>
<skip pattern="kotlin/Metadata"/>
<src refid="compilerSources.path"/>
<classpath refid="classpath"/>
</javac2>
@@ -603,51 +600,6 @@
</jar>
</target>
<target name="kotlin-build-common">
<cleandir dir="${output}/classes/kotlin-build-common"/>
<javac2 destdir="${output}/classes/kotlin-build-common" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false"
source="${java.target}" target="${java.target}">
<withKotlin modulename="kotlin-build-common"/>
<skip pattern="kotlin/jvm/internal/.*"/>
<src>
<pathelement path="build-common/src"/>
</src>
<classpath>
<pathelement path="${bootstrap.runtime}"/>
<pathelement path="${bootstrap.reflect}"/>
<pathelement path="${idea.sdk}/lib/util.jar"/>
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
</classpath>
</javac2>
<jar destfile="${kotlin-home}/lib/kotlin-build-common.jar">
<fileset dir="${output}/classes/kotlin-build-common"/>
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
<manifest>
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.build.common}"/>
<attribute name="Implementation-Version" value="${build.number}"/>
</manifest>
</jar>
<jar jarfile="${output}/kotlin-build-common-sources.jar">
<fileset dir="build-common/src"/>
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
<manifest>
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.build.common.sources}"/>
<attribute name="Implementation-Version" value="${build.number}"/>
</manifest>
</jar>
</target>
<target name="daemon-client">
<cleandir dir="${output}/classes/daemon-client"/>
@@ -667,14 +619,6 @@
<fileset dir="${output}/classes/daemon-client"/>
<zipfileset src="${dependencies.dir}/native-platform-uberjar.jar" includes="**" />
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
<manifest>
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.daemon-client}"/>
<attribute name="Implementation-Version" value="${build.number}"/>
</manifest>
</jar>
</target>
@@ -683,7 +627,6 @@
<javac2 destdir="${output}/classes/android-compiler-plugin" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
<withKotlin modulename="kotlin-android-compiler-plugin"/>
<skip pattern="kotlin/jvm/internal/.*"/>
<skip pattern="kotlin/Metadata"/>
<src>
<pathelement path="plugins/android-compiler-plugin/src"/>
</src>
@@ -708,7 +651,6 @@
source="${java.target}" target="${java.target}">
<withKotlin modulename="kotlin-ant-tools"/>
<skip pattern="kotlin/jvm/internal/.*"/>
<skip pattern="kotlin/Metadata"/>
<src>
<dirset dir="${basedir}/ant">
<include name="src"/>
@@ -740,6 +682,30 @@
</jar>
</target>
<target name="jdk-annotations">
<jar destfile="${kotlin-home}/lib/kotlin-jdk-annotations.jar">
<manifest>
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.jdk.annotations}"/>
<attribute name="Implementation-Version" value="${build.number}"/>
</manifest>
</jar>
</target>
<target name="android-sdk-annotations">
<jar destfile="${kotlin-home}/lib/kotlin-android-sdk-annotations.jar">
<manifest>
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.android.sdk.annotations}"/>
<attribute name="Implementation-Version" value="${build.number}"/>
</manifest>
</jar>
</target>
<macrodef name="new-kotlinc">
<attribute name="output"/>
<attribute name="moduleName"/>
@@ -781,13 +747,11 @@
<arg value="${toString:classpath.path}"/>
<arg value="-module-name"/>
<arg value="@{moduleName}"/>
<arg value="-Xallow-kotlin-package"/>
</java>
<javac2 srcdir="${toString:src.dirset}" destdir="@{output}" debug="true" debuglevel="lines,vars,source"
includeAntRuntime="false" source="${java.target}" target="${java.target}">
<skip pattern="kotlin/jvm/internal/.*"/>
<skip pattern="kotlin/Metadata"/>
<classpath>
<path refid="classpath.path"/>
<!-- Include @{output} here for Java compiler to resolve symbols from Kotlin sources -->
@@ -834,7 +798,7 @@
</target>
<target name="stdlib">
<new-kotlinc output="${output}/classes/stdlib" moduleName="kotlin-stdlib">
<new-kotlinc output="${output}/classes/stdlib" moduleName="kotlin-stdlib" additionalOptions="-Xmultifile-facades-open">
<src>
<include name="libraries/stdlib/src"/>
</src>
@@ -844,8 +808,8 @@
</new-kotlinc>
</target>
<target name="kotlin-test">
<new-kotlinc output="${output}/classes/kotlin-test" moduleName="kotlin-test">
<target name="kotlin.test">
<new-kotlinc output="${output}/classes/kotlin.test" moduleName="kotlin-test">
<src>
<include name="libraries/kotlin.test/shared/src/main/kotlin" />
<include name="libraries/kotlin.test/shared/src/main/kotlin.jvm" />
@@ -856,12 +820,6 @@
<pathelement path="libraries/lib/junit-4.11.jar"/>
</class-path>
</new-kotlinc>
<pack-runtime-jar jar-name="kotlin-test.jar" implementation-title="${manifest.impl.title.kotlin.test}">
<jar-content>
<fileset dir="${output}/classes/kotlin-test" includes="**/*" excludes="kotlin/internal/OnlyInputTypes*,kotlin/internal"/>
</jar-content>
</pack-runtime-jar>
</target>
<target name="core">
@@ -926,6 +884,7 @@
<fileset dir="${output}/classes/stdlib"/>
<zipfileset dir="${output}/builtins">
<include name="kotlin/**"/>
<exclude name="kotlin/internal/**"/>
<!-- TODO: load metadata from @KotlinClass annotation in KotlinBuiltIns on JVM and restore this exclusion -->
<!-- exclude name="kotlin/reflect/**"/ -->
</zipfileset>
@@ -949,46 +908,31 @@
</jar>
<delete file="${output}/kotlin-reflect-jarjar.jar" failonerror="false"/>
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="dependencies/jarjar.jar"/>
<jarjar jarfile="${output}/kotlin-reflect-jarjar.jar" filesonly="true" filesetmanifest="merge">
<zipfileset src="${output}/kotlin-reflect-before-jarjar.jar"/>
<rule pattern="org.jetbrains.kotlin.**" result="kotlin.reflect.jvm.internal.impl.@1"/>
<rule pattern="com.google.protobuf.**" result="kotlin.reflect.jvm.internal.impl.com.google.protobuf.@1"/>
<rule pattern="javax.inject.**" result="kotlin.reflect.jvm.internal.impl.javax.inject.@1"/>
</jarjar>
<sequential if:true="${obfuscate.reflect}">
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="dependencies/jarjar.jar"/>
<jarjar jarfile="${output}/kotlin-reflect-jarjar.jar" filesonly="true" filesetmanifest="merge">
<zipfileset src="${output}/kotlin-reflect-before-jarjar.jar"/>
<rule pattern="org.jetbrains.kotlin.**" result="kotlin.reflect.jvm.internal.impl.@1"/>
<rule pattern="com.google.protobuf.**" result="kotlin.reflect.jvm.internal.impl.com.google.protobuf.@1"/>
<rule pattern="javax.inject.**" result="kotlin.reflect.jvm.internal.impl.javax.inject.@1"/>
</jarjar>
<kotlinc src="${basedir}/generators/infrastructure/strip-kotlin-annotations.kts" output="">
<compilerarg value="-script"/>
<compilerarg value="kotlin/jvm/internal/.*|kotlin/Metadata"/> <!-- Annotations to strip -->
<compilerarg value="kotlin/reflect/jvm/internal/impl/.*"/> <!-- Classes to strip from -->
<compilerarg value="${output}/kotlin-reflect-jarjar.jar"/>
<compilerarg value="${kotlin-home}/lib/kotlin-reflect.jar"/>
<classpath>
<pathelement location="${idea.sdk}/lib/asm-all.jar"/>
</classpath>
</kotlinc>
</sequential>
<sequential unless:true="${obfuscate.reflect}">
<echo message="Obfuscation of kotlin-reflect is disabled"/>
<copy file="${output}/kotlin-reflect-before-jarjar.jar" tofile="${output}/kotlin-reflect-jarjar.jar" overwrite="true"/>
<copy file="${output}/kotlin-reflect-before-jarjar.jar" tofile="${kotlin-home}/lib/kotlin-reflect.jar" overwrite="true"/>
</sequential>
<kotlinc src="${basedir}/generators/infrastructure/strip-kotlin-annotations.kts" output="">
<compilerarg value="-script"/>
<compilerarg value="kotlin/jvm/internal/.*"/> <!-- Annotations to strip -->
<compilerarg value="kotlin/reflect/jvm/internal/impl/.*"/> <!-- Classes to strip from -->
<compilerarg value="${output}/kotlin-reflect-jarjar.jar"/>
<compilerarg value="${kotlin-home}/lib/kotlin-reflect.jar"/>
<classpath>
<pathelement location="${idea.sdk}/lib/asm-all.jar"/>
</classpath>
</kotlinc>
</target>
<target name="pack-runtime-sources">
<!-- Rename packages in the sources of reflection impl (core) -->
<delete dir="${output}/core.src" failonerror="false"/>
<local name="runtime.sources.base.dir"/>
<condition property="runtime.sources.base.dir"
value="${output}/core.src/kotlin/reflect/jvm/internal/impl"
else="${output}/core.src/org/jetbrains/kotlin">
<istrue value="${obfuscate.reflect}"/>
</condition>
<copy todir="${runtime.sources.base.dir}">
<copy todir="${output}/core.src/kotlin/reflect/jvm/internal/impl">
<fileset dir="core">
<include name="descriptor.loader.java/src/**"/>
<include name="descriptors/src/**"/>
@@ -998,13 +942,9 @@
</fileset>
<cutdirsmapper dirs="5"/> <!-- module/src/org/jetbrains/kotlin -->
</copy>
<sequential if:true="${obfuscate.reflect}">
<!-- Rename packages in the sources of reflection impl (core) -->
<replaceregexp match="org\.jetbrains\.kotlin" replace="kotlin.reflect.jvm.internal.impl" flags="g">
<fileset dir="${output}/core.src"/>
</replaceregexp>
</sequential>
<replaceregexp match="org\.jetbrains\.kotlin" replace="kotlin.reflect.jvm.internal.impl" flags="g">
<fileset dir="${output}/core.src"/>
</replaceregexp>
<pack-runtime-jar jar-name="kotlin-runtime-sources.jar" implementation-title="${manifest.impl.title.kotlin.jvm.runtime.sources}">
<jar-content>
@@ -1026,15 +966,23 @@
</pack-runtime-jar>
</target>
<target name="pack-kotlin-test">
<pack-runtime-jar jar-name="kotlin-test.jar" implementation-title="${manifest.impl.title.kotlin.test}">
<jar-content>
<fileset dir="${output}/classes/kotlin.test" includes="**/*" excludes="kotlin/internal/OnlyInputTypes*,kotlin/internal"/>
</jar-content>
</pack-runtime-jar>
</target>
<target name="runtime"
depends="builtins,stdlib,kotlin-test,core,reflection,pack-runtime,pack-runtime-sources,mock-runtime-for-test"/>
depends="builtins,stdlib,core,reflection,pack-runtime,pack-runtime-sources"/>
<target name="dist"
depends="clean,init,prepare-dist,preloader,runner,serialize-builtins,compiler,compiler-sources,kotlin-build-common,ant-tools,runtime,kotlin-js-stdlib,android-compiler-plugin,daemon-client"
depends="clean,init,prepare-dist,preloader,runner,serialize-builtins,compiler,compiler-sources,ant-tools,jdk-annotations,android-sdk-annotations,runtime,kotlin.test,pack-kotlin-test,kotlin-js-stdlib,android-compiler-plugin,daemon-client"
description="Builds redistributables from sources"/>
<target name="dist-quick"
depends="clean,init,prepare-dist,preloader,serialize-builtins,compiler-quick,ant-tools,runtime,kotlin-js-stdlib,android-compiler-plugin"
depends="clean,init,prepare-dist,preloader,serialize-builtins,compiler-quick,ant-tools,jdk-annotations,android-sdk-annotations,runtime,kotlin.test,pack-kotlin-test,kotlin-js-stdlib,android-compiler-plugin"
description="Builds everything, but classes are reused from project out dir, doesn't run proguard and javadoc"/>
<target name="dist-quick-compiler-only"
@@ -1056,7 +1004,6 @@
source="${java.target}" target="${java.target}">
<withKotlin modulename="kotlin-for-upsource"/>
<skip pattern="kotlin/jvm/internal/.*"/>
<skip pattern="kotlin/Metadata"/>
<src>
<dirset dir="${basedir}/idea/ide-common" includes="src"/>
<dirset dir="${basedir}/idea/idea-analysis" includes="src"/>
@@ -1077,6 +1024,7 @@
<fileset dir="${output}/classes/compiler"/>
<fileset dir="${output}/builtins">
<include name="kotlin/**"/>
<exclude name="kotlin/internal/**"/>
</fileset>
<fileset dir="${basedir}/core/descriptor.loader.java/src" includes="META-INF/services/**"/>
<fileset dir="${basedir}/compiler/frontend.java/src" includes="META-INF/services/**"/>
@@ -1126,28 +1074,6 @@
</zip>
</target>
<target name="mock-runtime-for-test">
<delete dir="${output}/mock-runtime-src" failonerror="false"/>
<mkdir dir="${output}/mock-runtime-src"/>
<copy file="${basedir}/libraries/stdlib/src/kotlin/util/Standard.kt" todir="${output}/mock-runtime-src"/>
<copy file="${basedir}/libraries/stdlib/src/kotlin/internal/Annotations.kt" todir="${output}/mock-runtime-src"/>
<new-kotlinc output="${output}/classes/mock-runtime" moduleName="kotlin-stdlib">
<src>
<include name="dist/mock-runtime-src"/>
</src>
<class-path>
<pathelement path="${output}/classes/builtins"/>
</class-path>
</new-kotlinc>
<pack-runtime-jar jar-dir="${output}" jar-name="kotlin-mock-runtime-for-test.jar" implementation-title="Kotlin Mock Runtime">
<jar-content>
<fileset dir="${output}/classes/mock-runtime"/>
</jar-content>
</pack-runtime-jar>
</target>
<target name="build-bootstrap-artifacts" depends="dist,zip-compiler"/>
<target name="build-artifacts" depends="dist,zip-compiler,kotlin-for-upsource,zip-test-data"/>

View File

@@ -27,14 +27,15 @@ import org.jetbrains.kotlin.types.isDynamic
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
import java.util.Comparator
object CodegenUtilKt {
public object CodegenUtilKt {
// class Foo : Bar by baz
// descriptor = Foo
// toInterface = Bar
// delegateExpressionType = typeof(baz)
// return Map<member of Foo, corresponding member of typeOf(baz)>
@JvmStatic fun getDelegates(
@JvmStatic
public fun getDelegates(
descriptor: ClassDescriptor,
toInterface: ClassDescriptor,
delegateExpressionType: KotlinType? = null
@@ -66,7 +67,7 @@ object CodegenUtilKt {
}
else null
}
assert(actualDelegates.size <= 1) { "Many delegates found for $delegatingMember: $actualDelegates" }
assert(actualDelegates.size() <= 1) { "Many delegates found for $delegatingMember: $actualDelegates" }
actualDelegates.firstOrNull()
}

View File

@@ -19,22 +19,22 @@ package org.jetbrains.kotlin.backend.common.bridges
import org.jetbrains.kotlin.utils.DFS
import java.util.HashSet
interface FunctionHandle {
val isDeclaration: Boolean
val isAbstract: Boolean
public interface FunctionHandle {
public val isDeclaration: Boolean
public val isAbstract: Boolean
fun getOverridden(): Iterable<FunctionHandle>
public fun getOverridden(): Iterable<FunctionHandle>
}
data class Bridge<Signature>(
val from: Signature,
val to: Signature
public data class Bridge<Signature>(
public val from: Signature,
public val to: Signature
) {
override fun toString() = "$from -> $to"
}
fun <Function : FunctionHandle, Signature> generateBridges(
public fun <Function : FunctionHandle, Signature> generateBridges(
function: Function,
signature: (Function) -> Signature
): Set<Bridge<Signature>> {
@@ -69,7 +69,7 @@ fun <Function : FunctionHandle, Signature> generateBridges(
return bridgesToGenerate.map { Bridge(it, method) }.toSet()
}
fun <Function : FunctionHandle> findAllReachableDeclarations(function: Function): MutableSet<Function> {
public fun <Function : FunctionHandle> findAllReachableDeclarations(function: Function): MutableSet<Function> {
val collector = object : DFS.NodeHandlerWithListResult<Function, Function>() {
override fun afterChildren(current: Function) {
if (current.isDeclaration) {
@@ -86,7 +86,7 @@ fun <Function : FunctionHandle> findAllReachableDeclarations(function: Function)
* Given a concrete function, finds an implementation (a concrete declaration) of this function in the supertypes.
* The implementation is guaranteed to exist because if it wouldn't, the given function would've been abstract
*/
fun <Function : FunctionHandle> findConcreteSuperDeclaration(function: Function): Function {
public fun <Function : FunctionHandle> findConcreteSuperDeclaration(function: Function): Function {
require(!function.isAbstract, { "Only concrete functions have implementations: $function" })
if (function.isDeclaration) return function
@@ -109,7 +109,7 @@ fun <Function : FunctionHandle> findConcreteSuperDeclaration(function: Function)
result.removeAll(toRemove)
val concreteRelevantDeclarations = result.filter { !it.isAbstract }
if (concreteRelevantDeclarations.size != 1) {
if (concreteRelevantDeclarations.size() != 1) {
error("Concrete fake override $function should have exactly one concrete super-declaration: $concreteRelevantDeclarations")
}

View File

@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.OverrideResolver
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
fun <Signature> generateBridgesForFunctionDescriptor(
public fun <Signature> generateBridgesForFunctionDescriptor(
descriptor: FunctionDescriptor,
signature: (FunctionDescriptor) -> Signature
): Set<Bridge<Signature>> {
@@ -47,16 +47,16 @@ fun <Signature> generateBridgesForFunctionDescriptor(
* can generate a bridge near an implementation (of course, in case it has a super-declaration with a different signature). Ultimately this
* eases the process of determining what bridges are already generated in our supertypes and need to be inherited, not regenerated.
*/
data class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : FunctionHandle {
private val overridden = descriptor.overriddenDescriptors.map { DescriptorBasedFunctionHandle(it.original) }
public data class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : FunctionHandle {
private val overridden = descriptor.getOverriddenDescriptors().map { DescriptorBasedFunctionHandle(it.getOriginal()) }
override val isDeclaration: Boolean =
descriptor.kind.isReal ||
descriptor.getKind().isReal() ||
findTraitImplementation(descriptor) != null
override val isAbstract: Boolean =
descriptor.modality == Modality.ABSTRACT ||
DescriptorUtils.isInterface(descriptor.containingDeclaration)
descriptor.getModality() == Modality.ABSTRACT ||
DescriptorUtils.isInterface(descriptor.getContainingDeclaration())
override fun getOverridden() = overridden
}
@@ -67,14 +67,14 @@ data class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : F
* trait implementation should be generated into the class containing the fake override; or null if the given function is not a fake
* override of any trait implementation or such method was already generated into the superclass or is a method from Any.
*/
fun findTraitImplementation(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
if (descriptor.kind.isReal) return null
public fun findTraitImplementation(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
if (descriptor.getKind().isReal()) return null
if (isOrOverridesSynthesized(descriptor)) return null
val implementation = findImplementationFromInterface(descriptor) ?: return null
val immediateConcreteSuper = firstSuperMethodFromKotlin(descriptor, implementation) ?: return null
if (!DescriptorUtils.isInterface(immediateConcreteSuper.containingDeclaration)) {
if (!DescriptorUtils.isInterface(immediateConcreteSuper.getContainingDeclaration())) {
// If this implementation is already generated into the superclass, we need not generate it again, it'll be inherited
return null
}
@@ -86,13 +86,14 @@ fun findTraitImplementation(descriptor: CallableMemberDescriptor): CallableMembe
* Given a fake override, returns an overridden non-abstract function from an interface which is the actual implementation of this function
* that should be called when the given fake override is called.
*/
fun findImplementationFromInterface(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
public fun findImplementationFromInterface(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
val overridden = OverrideResolver.getOverriddenDeclarations(descriptor)
val filtered = OverrideResolver.filterOutOverridden(overridden)
val result = filtered.firstOrNull { it.modality != Modality.ABSTRACT } ?: return null
val result = filtered.firstOrNull { it.getModality() != Modality.ABSTRACT } ?: return null
if (DescriptorUtils.isClassOrEnumClass(result.containingDeclaration)) return null
val container = result.getContainingDeclaration()
if (DescriptorUtils.isClass(container) || DescriptorUtils.isEnumClass(container)) return null
return result
}
@@ -102,12 +103,12 @@ fun findImplementationFromInterface(descriptor: CallableMemberDescriptor): Calla
* returns the first immediate super function of the given fake override which overrides that implementation.
* The returned function should be called from TImpl-bridges generated for the given fake override.
*/
fun firstSuperMethodFromKotlin(
public fun firstSuperMethodFromKotlin(
descriptor: CallableMemberDescriptor,
implementation: CallableMemberDescriptor
): CallableMemberDescriptor? {
return descriptor.overriddenDescriptors.firstOrNull { overridden ->
overridden.modality != Modality.ABSTRACT &&
return descriptor.getOverriddenDescriptors().firstOrNull { overridden ->
overridden.getModality() != Modality.ABSTRACT &&
(overridden == implementation || OverrideResolver.overrides(overridden, implementation))
}
}

View File

@@ -18,24 +18,24 @@ package org.jetbrains.kotlin.backend.common.output
import java.io.File
interface OutputFileCollection {
fun get(relativePath: String): OutputFile?
fun asList(): List<OutputFile>
public interface OutputFileCollection {
public fun get(relativePath: String): OutputFile?
public fun asList(): List<OutputFile>
}
class SimpleOutputFileCollection(private val outputFiles: List<OutputFile>) : OutputFileCollection {
public class SimpleOutputFileCollection(private val outputFiles: List<OutputFile>) : OutputFileCollection {
override fun get(relativePath: String): OutputFile? = outputFiles.firstOrNull { it.relativePath == relativePath }
override fun asList(): List<OutputFile> = outputFiles
}
interface OutputFile {
val relativePath: String
val sourceFiles: List<File>
fun asByteArray(): ByteArray
fun asText(): String
public interface OutputFile {
public val relativePath: String
public val sourceFiles: List<File>
public fun asByteArray(): ByteArray
public fun asText(): String
}
class SimpleOutputFile(
public class SimpleOutputFile(
override val sourceFiles: List<File>,
override val relativePath: String,
private val content: String
@@ -46,7 +46,7 @@ class SimpleOutputFile(
override fun toString() = "$relativePath (compiled from $sourceFiles)"
}
class SimpleOutputBinaryFile(
public class SimpleOutputBinaryFile(
override val sourceFiles: List<File>,
override val relativePath: String,
private val content: ByteArray

View File

@@ -24,18 +24,18 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import java.util.*
open class AbstractAccessorForFunctionDescriptor(
open public class AbstractAccessorForFunctionDescriptor(
containingDeclaration: DeclarationDescriptor,
name: Name
) : SimpleFunctionDescriptorImpl(containingDeclaration, null, Annotations.EMPTY,
name, CallableMemberDescriptor.Kind.DECLARATION, SourceElement.NO_SOURCE) {
protected fun copyTypeParameters(descriptor: FunctionDescriptor): List<TypeParameterDescriptor> = descriptor.typeParameters.map {
protected fun copyTypeParameters(descriptor: FunctionDescriptor): List<TypeParameterDescriptor> = descriptor.getTypeParameters().map {
val copy = TypeParameterDescriptorImpl.createForFurtherModification(
this, it.annotations, it.isReified,
it.variance, it.name,
it.index, SourceElement.NO_SOURCE)
for (upperBound in it.upperBounds) {
this, it.getAnnotations(), it.isReified(),
it.getVariance(), it.getName(),
it.getIndex(), SourceElement.NO_SOURCE)
for (upperBound in it.getUpperBounds()) {
copy.addUpperBound(upperBound)
}
copy.setInitialized()
@@ -43,5 +43,5 @@ open class AbstractAccessorForFunctionDescriptor(
}
protected fun copyValueParameters(descriptor: FunctionDescriptor): List<ValueParameterDescriptor> =
descriptor.valueParameters.map { it.copy(this, it.name) }
descriptor.getValueParameters().map { it.copy(this, it.getName()) }
}

View File

@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSubstitutor
class AccessorForConstructorDescriptor(
public class AccessorForConstructorDescriptor(
private val calleeDescriptor: ConstructorDescriptor,
containingDeclaration: DeclarationDescriptor,
private val superCallTarget: ClassDescriptor?

View File

@@ -108,16 +108,6 @@ public abstract class AnnotationCodegen {
"Inconsistent target list for lambda annotation: " + applicableTargets + " on " + annotated;
continue;
}
if (annotated instanceof ClassDescriptor
&& !applicableTargets.contains(KotlinTarget.CLASS)
&& !applicableTargets.contains(KotlinTarget.ANNOTATION_CLASS)) {
ClassDescriptor classDescriptor = (ClassDescriptor) annotated;
if (classDescriptor.getVisibility() == Visibilities.LOCAL) {
assert applicableTargets.contains(KotlinTarget.EXPRESSION) :
"Inconsistent target list for object literal annotation: " + applicableTargets + " on " + annotated;
continue;
}
}
String descriptor = genAnnotation(annotation);
if (descriptor != null) {

View File

@@ -31,16 +31,16 @@ abstract class ArgumentGenerator {
*
* @see kotlin.reflect.jvm.internal.KCallableImpl.callBy
*/
open fun generate(valueArgumentsByIndex: List<ResolvedValueArgument>, actualArgs: List<ResolvedValueArgument>): DefaultCallArgs {
assert(valueArgumentsByIndex.size == actualArgs.size) {
"Value arguments collection should have same size, but ${valueArgumentsByIndex.size} != ${actualArgs.size}"
open fun generate(valueArgumentsByIndex: List<ResolvedValueArgument>, actualArgs: List<ResolvedValueArgument>): DefaultCallMask {
assert(valueArgumentsByIndex.size() == actualArgs.size()) {
"Value arguments collection should have same size, but ${valueArgumentsByIndex.size()} != ${actualArgs.size()}"
}
val arg2Index = valueArgumentsByIndex.mapToIndex()
val actualArgsWithDeclIndex = actualArgs.filter { it !is DefaultValueArgument }.map {
ArgumentAndDeclIndex(it, arg2Index[it]!!)
}.toMutableList()
}.toArrayList()
valueArgumentsByIndex.withIndex().forEach {
if (it.value is DefaultValueArgument) {
@@ -48,7 +48,7 @@ abstract class ArgumentGenerator {
}
}
val defaultArgs = DefaultCallArgs(valueArgumentsByIndex.size)
val masks = DefaultCallMask(valueArgumentsByIndex.size())
for (argumentWithDeclIndex in actualArgsWithDeclIndex) {
val argument = argumentWithDeclIndex.arg
@@ -59,7 +59,7 @@ abstract class ArgumentGenerator {
generateExpression(declIndex, argument)
}
is DefaultValueArgument -> {
defaultArgs.mark(declIndex)
masks.mark(declIndex)
generateDefault(declIndex, argument)
}
is VarargValueArgument -> {
@@ -73,7 +73,7 @@ abstract class ArgumentGenerator {
reorderArgumentsIfNeeded(actualArgsWithDeclIndex)
return defaultArgs
return masks
}
protected open fun generateExpression(i: Int, argument: ExpressionValueArgument) {

View File

@@ -61,10 +61,11 @@ import java.util.Set;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isBoolean;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveClass;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_SYNTHETIC_CLASS;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
import static org.jetbrains.kotlin.types.TypeUtils.isNullableType;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -256,7 +257,8 @@ public class AsmUtil {
Classes in byte code should be public or package private
*/
public static int getVisibilityAccessFlagForClass(ClassDescriptor descriptor) {
if (descriptor.getVisibility() == Visibilities.PUBLIC ||
if (DescriptorUtils.isTopLevelDeclaration(descriptor) ||
descriptor.getVisibility() == Visibilities.PUBLIC ||
// TODO: should be package private, but for now Kotlin's reflection can't access members of such classes
descriptor.getVisibility() == Visibilities.LOCAL ||
descriptor.getVisibility() == Visibilities.INTERNAL) {
@@ -266,7 +268,7 @@ public class AsmUtil {
}
public static int getVisibilityAccessFlagForAnonymous(@NotNull ClassDescriptor descriptor) {
return InlineUtil.isInlineOrContainingInline(descriptor.getContainingDeclaration()) ? ACC_PUBLIC : NO_FLAG_PACKAGE_PRIVATE;
return InlineUtil.isInline(descriptor.getContainingDeclaration()) ? ACC_PUBLIC : NO_FLAG_PACKAGE_PRIVATE;
}
public static int calculateInnerClassAccessFlags(@NotNull ClassDescriptor innerClass) {
@@ -297,6 +299,9 @@ public class AsmUtil {
public static int getDeprecatedAccessFlag(@NotNull MemberDescriptor descriptor) {
if (descriptor instanceof PropertyAccessorDescriptor) {
if (((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty().isConst()) {
return ACC_DEPRECATED;
}
return KotlinBuiltIns.isDeprecated(descriptor)
? ACC_DEPRECATED
: getDeprecatedAccessFlag(((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty());
@@ -321,8 +326,6 @@ public class AsmUtil {
DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration();
Visibility memberVisibility = memberDescriptor.getVisibility();
if (AnnotationUtilKt.isInlineOnly(memberDescriptor)) return ACC_PRIVATE;
if (memberVisibility == Visibilities.LOCAL && memberDescriptor instanceof CallableMemberDescriptor) {
return ACC_PUBLIC;
}
@@ -539,7 +542,7 @@ public class AsmUtil {
if (opToken == KtTokens.EXCLEQ || opToken == KtTokens.EXCLEQEQEQ) {
genInvertBoolean(v);
}
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -678,17 +681,28 @@ public class AsmUtil {
}
public static boolean isInstancePropertyWithStaticBackingField(@NotNull PropertyDescriptor propertyDescriptor) {
return propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
isObject(propertyDescriptor.getContainingDeclaration());
if (propertyDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
return false;
}
DeclarationDescriptor container = propertyDescriptor.getContainingDeclaration();
return isNonCompanionObject(container) ||
isPropertyWithBackingFieldInOuterClass(propertyDescriptor) ||
(isCompanionObject(container) && isInterface(container.getContainingDeclaration()));
}
public static int getVisibilityForBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) {
public static boolean isPropertyWithBackingFieldInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
return propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
isCompanionObjectWithBackingFieldsInOuter(propertyDescriptor.getContainingDeclaration());
}
public static int getVisibilityForSpecialPropertyBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) {
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
if (isDelegate || isExtensionProperty) {
return ACC_PRIVATE;
}
else {
return propertyDescriptor.isLateInit() || isConstOrHasJvmFieldAnnotation(propertyDescriptor)
return areBothAccessorDefault(propertyDescriptor)
? getVisibilityAccessFlag(descriptorForVisibility(propertyDescriptor))
: ACC_PRIVATE;
}
@@ -704,10 +718,27 @@ public class AsmUtil {
}
public static boolean isPropertyWithBackingFieldCopyInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
DeclarationDescriptor propertyContainer = propertyDescriptor.getContainingDeclaration();
return propertyDescriptor.isConst()
return !propertyDescriptor.isVar()
&& !isExtensionProperty
&& isCompanionObject(propertyContainer) && isInterface(propertyContainer.getContainingDeclaration())
&& getVisibilityForBackingField(propertyDescriptor, false) == ACC_PUBLIC;
&& areBothAccessorDefault(propertyDescriptor)
&& getVisibilityForSpecialPropertyBackingField(propertyDescriptor, false) == ACC_PUBLIC;
}
public static boolean isCompanionObjectWithBackingFieldsInOuter(@NotNull DeclarationDescriptor companionObject) {
DeclarationDescriptor containingClass = companionObject.getContainingDeclaration();
return isCompanionObject(companionObject) && (isClass(containingClass) || isEnumClass(containingClass));
}
private static boolean areBothAccessorDefault(@NotNull PropertyDescriptor propertyDescriptor) {
return isAccessorWithEmptyBody(propertyDescriptor.getGetter())
&& (!propertyDescriptor.isVar() || isAccessorWithEmptyBody(propertyDescriptor.getSetter()));
}
private static boolean isAccessorWithEmptyBody(@Nullable PropertyAccessorDescriptor accessorDescriptor) {
return accessorDescriptor == null || !accessorDescriptor.hasBody();
}
public static Type comparisonOperandType(Type left, Type right) {
@@ -780,6 +811,13 @@ public class AsmUtil {
}
}
public static void writeKotlinSyntheticClassAnnotation(@NotNull ClassBuilder v, @NotNull GenerationState state) {
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(KOTLIN_SYNTHETIC_CLASS), true);
JvmCodegenUtil.writeAbiVersion(av);
JvmCodegenUtil.writeModuleName(av, state);
av.visitEnd();
}
public static void writeAnnotationData(
@NotNull AnnotationVisitor av,
@NotNull DescriptorSerializer serializer,
@@ -787,19 +825,31 @@ public class AsmUtil {
) {
byte[] bytes = serializer.serialize(message);
AnnotationVisitor data = av.visitArray(JvmAnnotationNames.METADATA_DATA_FIELD_NAME);
JvmCodegenUtil.writeAbiVersion(av);
AnnotationVisitor data = av.visitArray(JvmAnnotationNames.DATA_FIELD_NAME);
for (String string : BitEncoding.encodeBytes(bytes)) {
data.visit(null, string);
}
data.visitEnd();
AnnotationVisitor strings = av.visitArray(JvmAnnotationNames.METADATA_STRINGS_FIELD_NAME);
AnnotationVisitor strings = av.visitArray(JvmAnnotationNames.STRINGS_FIELD_NAME);
for (String string : ((JvmStringTable) serializer.getStringTable()).getStrings()) {
strings.visit(null, string);
}
strings.visitEnd();
}
@NotNull
public static String asmDescByFqNameWithoutInnerClasses(@NotNull FqName fqName) {
return asmTypeByFqNameWithoutInnerClasses(fqName).getDescriptor();
}
@NotNull
public static String shortNameByAsmType(@NotNull Type type) {
String internalName = type.getInternalName();
int lastSlash = internalName.lastIndexOf('/');
return lastSlash < 0 ? internalName : internalName.substring(lastSlash + 1);
}
@NotNull
public static Type asmTypeByFqNameWithoutInnerClasses(@NotNull FqName fqName) {
return Type.getObjectType(internalNameByFqNameWithoutInnerClasses(fqName));

View File

@@ -147,8 +147,8 @@ open class BranchedValue(
}, IFEQ)
}
fun cmp(opToken: IElementType, operandType: Type, left: StackValue, right: StackValue): StackValue =
if (operandType.sort == Type.OBJECT)
public fun cmp(opToken: IElementType, operandType: Type, left: StackValue, right: StackValue): StackValue =
if (operandType.getSort() == Type.OBJECT)
ObjectCompare(opToken, operandType, left, right)
else
NumberCompare(opToken, operandType, left, right)

View File

@@ -51,15 +51,15 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
@NotNull
@Override
public DefaultCallArgs generate(
public DefaultCallMask generate(
@NotNull List<? extends ResolvedValueArgument> valueArgumentsByIndex,
@NotNull List<? extends ResolvedValueArgument> valueArgs
) {
boolean shouldMarkLineNumbers = this.codegen.isShouldMarkLineNumbers();
this.codegen.setShouldMarkLineNumbers(false);
DefaultCallArgs defaultArgs = super.generate(valueArgumentsByIndex, valueArgs);
DefaultCallMask masks = super.generate(valueArgumentsByIndex, valueArgs);
this.codegen.setShouldMarkLineNumbers(shouldMarkLineNumbers);
return defaultArgs;
return masks;
}
@Override
@@ -75,9 +75,10 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
@Override
protected void generateDefault(int i, @NotNull DefaultValueArgument argument) {
ValueParameterDescriptor parameter = valueParameters.get(i);
Type type = valueParameterTypes.get(i);
pushDefaultValueOnStack(type, codegen.v);
callGenerator.afterParameterPut(type, null, i);
callGenerator.afterParameterPut(type, null, parameter, i);
}
@Override
@@ -85,7 +86,7 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
ValueParameterDescriptor parameter = valueParameters.get(i);
Type type = valueParameterTypes.get(i);
codegen.genVarargs(argument, parameter.getType());
callGenerator.afterParameterPut(type, null, i);
callGenerator.afterParameterPut(type, null, parameter, i);
}
@Override

View File

@@ -46,6 +46,7 @@ abstract class CallGenerator {
override fun afterParameterPut(
type: Type,
stackValue: StackValue?,
valueParameterDescriptor: ValueParameterDescriptor,
parameterIndex: Int) {
}
@@ -69,7 +70,7 @@ abstract class CallGenerator {
}
override fun putValueIfNeeded(
parameterType: Type, value: StackValue) {
valueParameterDescriptor: ValueParameterDescriptor?, parameterType: Type, value: StackValue) {
value.put(value.type, codegen.v)
}
@@ -112,6 +113,7 @@ abstract class CallGenerator {
abstract fun afterParameterPut(
type: Type,
stackValue: StackValue?,
valueParameterDescriptor: ValueParameterDescriptor,
parameterIndex: Int)
abstract fun genValueAndPut(
@@ -121,6 +123,7 @@ abstract class CallGenerator {
parameterIndex: Int)
abstract fun putValueIfNeeded(
valueParameterDescriptor: ValueParameterDescriptor?,
parameterType: Type,
value: StackValue)

View File

@@ -20,32 +20,32 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
interface Callable {
val owner: Type
public interface Callable {
public val owner: Type
val dispatchReceiverType: Type?
public val dispatchReceiverType: Type?
val extensionReceiverType: Type?
public val extensionReceiverType: Type?
val generateCalleeType: Type?
public val generateCalleeType: Type?
val valueParameterTypes: List<Type>
public val valueParameterTypes: List<Type>
val parameterTypes: Array<Type>
public val parameterTypes: Array<Type>
val returnType: Type
public val returnType: Type
fun genInvokeInstruction(v: InstructionAdapter)
public fun genInvokeInstruction(v: InstructionAdapter)
fun isStaticCall(): Boolean
public fun isStaticCall(): Boolean
fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, codegen: ExpressionCodegen): StackValue {
public fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, codegen: ExpressionCodegen): StackValue {
return StackValue.functionCall(returnType) {
codegen.invokeMethodWithArguments(this, resolvedCall, receiver)
}
}
fun afterReceiverGeneration(v: InstructionAdapter) {
public fun afterReceiverGeneration(v: InstructionAdapter) {
}
}

View File

@@ -27,7 +27,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.commons.Method
import org.jetbrains.org.objectweb.asm.util.Printer
class CallableMethod(
public class CallableMethod(
override val owner: Type,
private val defaultImplOwner: Type?,
private val defaultMethodDesc: String,
@@ -37,47 +37,48 @@ class CallableMethod(
override val extensionReceiverType: Type?,
override val generateCalleeType: Type?
) : Callable {
fun getValueParameters(): List<JvmMethodParameterSignature> =
signature.valueParameters
public fun getValueParameters(): List<JvmMethodParameterSignature> =
signature.getValueParameters()
override val valueParameterTypes: List<Type>
get() = signature.valueParameters.filter { it.kind == JvmMethodParameterKind.VALUE }.map { it.asmType }
get() = signature.getValueParameters().filter { it.getKind() == JvmMethodParameterKind.VALUE }.map { it.getAsmType() }
fun getAsmMethod(): Method =
signature.asmMethod
public fun getAsmMethod(): Method =
signature.getAsmMethod()
override val parameterTypes: Array<Type>
get() = getAsmMethod().argumentTypes
get() = getAsmMethod().getArgumentTypes()
override fun genInvokeInstruction(v: InstructionAdapter) {
v.visitMethodInsn(invokeOpcode, owner.internalName, getAsmMethod().name, getAsmMethod().descriptor)
public override fun genInvokeInstruction(v: InstructionAdapter) {
v.visitMethodInsn(invokeOpcode, owner.getInternalName(), getAsmMethod().getName(), getAsmMethod().getDescriptor())
}
fun genInvokeDefaultInstruction(v: InstructionAdapter) {
public fun genInvokeDefaultInstruction(v: InstructionAdapter) {
if (defaultImplOwner == null) {
throw IllegalStateException()
}
val method = getAsmMethod()
if ("<init>".equals(method.name)) {
v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner.internalName, "<init>", defaultMethodDesc, false)
if ("<init>".equals(method.getName())) {
v.aconst(null)
v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner.getInternalName(), "<init>", defaultMethodDesc, false)
}
else {
v.visitMethodInsn(INVOKESTATIC, defaultImplOwner.internalName,
method.name + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, defaultMethodDesc, false)
v.visitMethodInsn(INVOKESTATIC, defaultImplOwner.getInternalName(),
method.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, defaultMethodDesc, false)
StackValue.coerce(Type.getReturnType(defaultMethodDesc), Type.getReturnType(signature.asmMethod.descriptor), v)
}
}
override val returnType: Type
get() = signature.returnType
get() = signature.getReturnType()
override fun isStaticCall(): Boolean =
invokeOpcode == INVOKESTATIC
override fun toString(): String =
"${Printer.OPCODES[invokeOpcode]} ${owner.internalName}.$signature"
"${Printer.OPCODES[invokeOpcode]} ${owner.getInternalName()}.$signature"
}

View File

@@ -22,14 +22,14 @@ import com.intellij.psi.PsiFile;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.DataOutputStream;
import kotlin.collections.CollectionsKt;
import kotlin.CollectionsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
import org.jetbrains.kotlin.load.kotlin.PackageParts;
import org.jetbrains.kotlin.name.FqName;
@@ -123,7 +123,7 @@ public class ClassFileFactory implements OutputFileCollection {
try {
ByteArrayOutputStream moduleMapping = new ByteArrayOutputStream(4096);
DataOutputStream dataOutStream = new DataOutputStream(moduleMapping);
int[] version = JvmMetadataVersion.INSTANCE.toArray();
int[] version = JvmAbi.VERSION.toArray();
dataOutStream.writeInt(version.length);
for (int number : version) {
dataOutStream.writeInt(number);
@@ -286,23 +286,13 @@ public class ClassFileFactory implements OutputFileCollection {
@NotNull
@Override
public byte[] asByteArray() {
try {
return generators.get(relativeClassFilePath).asBytes(builderFactory);
}
catch (RuntimeException e) {
throw new RuntimeException("Error generating class file " + this.toString() + ": " + e.getMessage(), e);
}
return generators.get(relativeClassFilePath).asBytes(builderFactory);
}
@NotNull
@Override
public String asText() {
try {
return generators.get(relativeClassFilePath).asText(builderFactory);
}
catch (RuntimeException e) {
throw new RuntimeException("Error generating class file " + this.toString() + ": " + e.getMessage(), e);
}
return generators.get(relativeClassFilePath).asText(builderFactory);
}
@NotNull

View File

@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.RawSignature
import org.jetbrains.org.objectweb.asm.FieldVisitor
import org.jetbrains.org.objectweb.asm.MethodVisitor
abstract class ClassNameCollectionClassBuilderFactory(
public abstract class ClassNameCollectionClassBuilderFactory(
delegate: ClassBuilderFactory
) : DelegatingClassBuilderFactory(delegate) {

View File

@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.codegen;
import com.google.common.collect.Lists;
import com.intellij.util.ArrayUtil;
import kotlin.CollectionsKt;
import kotlin.Unit;
import kotlin.collections.CollectionsKt;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -34,7 +34,7 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.psi.KtElement;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.serialization.ProtoBuf;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
import org.jetbrains.kotlin.util.OperatorNameConventions;
import org.jetbrains.kotlin.utils.FunctionsKt;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type;
@@ -59,6 +60,7 @@ import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.ExpressionCodegen.generateClassLiteralReference;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.writeModuleName;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.asmTypeForAnonymousClass;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
@@ -195,7 +197,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
erasedInterfaceFunction.getValueParameters(), erasedInterfaceFunction.getReturnType(),
Modality.OPEN, erasedInterfaceFunction.getVisibility());
DescriptorUtilsKt.setSingleOverridden(descriptorForBridges, erasedInterfaceFunction);
descriptorForBridges.addOverriddenDescriptor(erasedInterfaceFunction);
functionCodegen.generateBridges(descriptorForBridges);
}
@@ -210,26 +212,27 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
this.constructor = generateConstructor();
if (isConst(closure)) {
generateConstInstance(asmType, asmType);
generateConstInstance(asmType, asmType, FunctionsKt.<InstructionAdapter>doNothing());
}
genClosureFields(closure, v, typeMapper);
}
@Override
protected void generateKotlinMetadataAnnotation() {
final DescriptorSerializer serializer =
DescriptorSerializer.createForLambda(new JvmSerializerExtension(v.getSerializationBindings(), state));
protected void generateKotlinAnnotation() {
writeKotlinSyntheticClassAnnotation(v, state);
final ProtoBuf.Function functionProto = serializer.functionProto(funDescriptor).build();
DescriptorSerializer serializer =
DescriptorSerializer.createForLambda(
new JvmSerializerExtension(v.getSerializationBindings(), typeMapper, state.getUseTypeTableInSerializer())
);
WriteAnnotationUtilKt.writeKotlinMetadata(v, KotlinClassHeader.Kind.SYNTHETIC_CLASS, new Function1<AnnotationVisitor, Unit>() {
@Override
public Unit invoke(AnnotationVisitor av) {
writeAnnotationData(av, serializer, functionProto);
return Unit.INSTANCE;
}
});
ProtoBuf.Function functionProto = serializer.functionProto(funDescriptor).build();
AnnotationVisitor av = v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_FUNCTION), true);
writeAnnotationData(av, serializer, functionProto);
writeModuleName(av, state);
av.visitEnd();
}
@Override
@@ -256,7 +259,13 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
}
return Unit.INSTANCE;
if (functionReferenceTarget != null) {
if (!"true".equalsIgnoreCase(System.getProperty("kotlin.jvm.optimize.callable.references"))) {
v.invokestatic(REFLECTION, "function", Type.getMethodDescriptor(K_FUNCTION, FUNCTION_REFERENCE), false);
}
}
return Unit.INSTANCE$;
}
}
);

View File

@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider
import org.jetbrains.kotlin.psi.KtFile
class CodegenFileClassesProvider : JvmFileClassesProvider {
override fun getFileClassInfo(file: KtFile): JvmFileClassInfo =
public class CodegenFileClassesProvider : JvmFileClassesProvider {
override public fun getFileClassInfo(file: KtFile): JvmFileClassInfo =
JvmFileClassUtil.getFileClassInfoNoResolve(file)
}

View File

@@ -65,14 +65,14 @@ class CollectionStubMethodGenerator(
val (child, typeParameters) = createSyntheticSubclass()
// If the original class has any type parameters, we copied them and now we need to substitute types of the newly created type
// parameters as arguments for the type parameters of the original class
val parentType = newType(descriptor, typeParameters.map { TypeProjectionImpl(it.defaultType) })
val parentType = newType(descriptor, typeParameters.map { TypeProjectionImpl(it.getDefaultType()) })
// Now we need to determine the arguments which should be substituted for the MutableCollection super class. To do that,
// we look for type arguments which were substituted in the inheritance of the original class from Collection and use them
// to construct the needed MutableCollection type. Since getAllSupertypes() may return several types which correspond to the
// Collection class descriptor, we find the most specific one (which is guaranteed to exist by front-end)
val readOnlyCollectionType = TypeUtils.getAllSupertypes(parentType).findMostSpecificTypeForClass(readOnlyClass)
val mutableCollectionType = newType(mutableClass, readOnlyCollectionType.arguments)
val mutableCollectionType = newType(mutableClass, readOnlyCollectionType.getArguments())
child.addSupertype(parentType)
child.addSupertype(mutableCollectionType)
@@ -81,10 +81,10 @@ class CollectionStubMethodGenerator(
// Bind fake overrides and for each fake override originated from the MutableCollection, save its signature to generate a stub
// or save its descriptor to generate all the needed bridges
for (method in findFakeOverridesForMethodsFromMutableCollection(child, mutableClass)) {
if (method.modality == Modality.ABSTRACT) {
if (method.getModality() == Modality.ABSTRACT) {
// If the fake override is abstract and it's _declared_ as abstract in the class, skip it because the method is already
// present in the bytecode (abstract) and we don't want a duplicate signature error
if (method.findOverriddenFromDirectSuperClass(descriptor)?.kind == DECLARATION) continue
if (method.findOverriddenFromDirectSuperClass(descriptor)?.getKind() == DECLARATION) continue
// Otherwise we can safely generate the stub with the substituted signature
val signature = method.signature()
@@ -160,18 +160,18 @@ class CollectionStubMethodGenerator(
val collectionClasses = with(descriptor.builtIns) {
listOf(
pair(collection, mutableCollection),
pair(set, mutableSet),
pair(list, mutableList),
pair(map, mutableMap),
pair(mapEntry, mutableMapEntry),
pair(iterable, mutableIterable),
pair(iterator, mutableIterator),
pair(listIterator, mutableListIterator)
pair(getCollection(), getMutableCollection()),
pair(getSet(), getMutableSet()),
pair(getList(), getMutableList()),
pair(getMap(), getMutableMap()),
pair(getMapEntry(), getMutableMapEntry()),
pair(getIterable(), getMutableIterable()),
pair(getIterator(), getMutableIterator()),
pair(getListIterator(), getMutableListIterator())
)
}
val allSuperClasses = TypeUtils.getAllSupertypes(descriptor.defaultType).classes().toHashSet()
val allSuperClasses = TypeUtils.getAllSupertypes(descriptor.getDefaultType()).classes().toHashSet()
val ourSuperCollectionClasses = collectionClasses.filter { pair ->
pair.readOnlyClass in allSuperClasses && pair.mutableClass !in allSuperClasses
@@ -180,13 +180,13 @@ class CollectionStubMethodGenerator(
// Filter out built-in classes which are overridden by other built-in classes in the list, to avoid duplicating methods.
val redundantClasses = ourSuperCollectionClasses.flatMapTo(HashSet<ClassDescriptor>()) { pair ->
pair.readOnlyClass.typeConstructor.supertypes.classes()
pair.readOnlyClass.getTypeConstructor().getSupertypes().classes()
}
return ourSuperCollectionClasses.filter { klass -> klass.readOnlyClass !in redundantClasses }
}
private fun Collection<KotlinType>.classes(): Collection<ClassDescriptor> =
this.map { it.constructor.declarationDescriptor as ClassDescriptor }
this.map { it.getConstructor().getDeclarationDescriptor() as ClassDescriptor }
private fun findFakeOverridesForMethodsFromMutableCollection(
klass: ClassDescriptor,
@@ -212,9 +212,9 @@ class CollectionStubMethodGenerator(
}
private fun Collection<KotlinType>.findMostSpecificTypeForClass(klass: ClassDescriptor): KotlinType {
val types = this.filter { it.constructor.declarationDescriptor == klass }
val types = this.filter { it.getConstructor().getDeclarationDescriptor() == klass }
if (types.isEmpty()) error("No supertype of $klass in $this")
if (types.size == 1) return types.first()
if (types.size() == 1) return types.first()
// Find the first type in the list such that it's a subtype of every other type in that list
return types.first { type ->
types.all { other -> KotlinTypeChecker.DEFAULT.isSubtypeOf(type, other) }
@@ -222,19 +222,19 @@ class CollectionStubMethodGenerator(
}
private fun createSyntheticSubclass(): Pair<MutableClassDescriptor, List<TypeParameterDescriptor>> {
val child = MutableClassDescriptor(descriptor.containingDeclaration, ClassKind.CLASS, false,
Name.special("<synthetic inheritor of ${descriptor.name}>"), descriptor.source)
child.modality = Modality.FINAL
child.visibility = Visibilities.PUBLIC
val typeParameters = descriptor.typeConstructor.parameters
val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size)
val child = MutableClassDescriptor(descriptor.getContainingDeclaration(), ClassKind.CLASS, false,
Name.special("<synthetic inheritor of ${descriptor.getName()}>"), descriptor.getSource())
child.setModality(Modality.FINAL)
child.setVisibility(Visibilities.PUBLIC)
val typeParameters = descriptor.getTypeConstructor().getParameters()
val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size())
DescriptorSubstitutor.substituteTypeParameters(typeParameters, TypeSubstitution.EMPTY, child, newTypeParameters)
child.setTypeParameterDescriptors(typeParameters)
return Pair(child, newTypeParameters)
}
private fun FunctionDescriptor.findOverriddenFromDirectSuperClass(classDescriptor: ClassDescriptor): FunctionDescriptor? {
return this.overriddenDescriptors.firstOrNull { it.containingDeclaration == classDescriptor }
return this.getOverriddenDescriptors().firstOrNull { it.getContainingDeclaration() == classDescriptor }
}
private fun newType(classDescriptor: ClassDescriptor, typeArguments: List<TypeProjection>): KotlinType {
@@ -246,13 +246,13 @@ class CollectionStubMethodGenerator(
private fun generateMethodStub(signature: JvmMethodSignature, synthetic: Boolean) {
// TODO: investigate if it makes sense to generate abstract stubs in traits
var access = ACC_PUBLIC
if (descriptor.kind == ClassKind.INTERFACE) access = access or ACC_ABSTRACT
if (descriptor.getKind() == ClassKind.INTERFACE) access = access or ACC_ABSTRACT
if (synthetic) access = access or ACC_SYNTHETIC
val asmMethod = signature.asmMethod
val genericSignature = if (synthetic) null else signature.genericsSignature
val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, asmMethod.name, asmMethod.descriptor, genericSignature, null)
if (descriptor.kind != ClassKind.INTERFACE) {
val asmMethod = signature.getAsmMethod()
val genericSignature = if (synthetic) null else signature.getGenericsSignature()
val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, asmMethod.getName(), asmMethod.getDescriptor(), genericSignature, null)
if (descriptor.getKind() != ClassKind.INTERFACE) {
mv.visitCode()
AsmUtil.genThrow(InstructionAdapter(mv), "java/lang/UnsupportedOperationException", "Mutating immutable collection")
FunctionCodegen.endVisit(mv, "built-in stub for $signature", null)

View File

@@ -16,11 +16,10 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.org.objectweb.asm.Type
import java.util.*
class DefaultCallArgs(val size: Int) {
class DefaultCallMask(val size: Int) {
val bits: BitSet = BitSet(size)
@@ -51,15 +50,10 @@ class DefaultCallArgs(val size: Int) {
return masks
}
fun generateOnStackIfNeeded(callGenerator: CallGenerator, isConstructor: Boolean): Boolean {
public fun generateOnStackIfNeeded(callGenerator: CallGenerator): Boolean {
val toInts = toInts()
if (!toInts.isEmpty()) {
for (mask in toInts) {
callGenerator.putValueIfNeeded(Type.INT_TYPE, StackValue.constant(mask, Type.INT_TYPE))
}
val parameterType = if (isConstructor) AsmTypes.DEFAULT_CONSTRUCTOR_MARKER else AsmTypes.OBJECT_TYPE
callGenerator.putValueIfNeeded(parameterType, StackValue.constant(null, parameterType))
for (mask in toInts) {
callGenerator.putValueIfNeeded(null, Type.INT_TYPE, StackValue.constant(mask, Type.INT_TYPE))
}
return toInts.isNotEmpty();
}

View File

@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmOverloadsAnnotation
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
@@ -34,7 +33,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
* Generates Java overloads for functions and constructors that have the default
* parameter values substituted.
*/
class DefaultParameterValueSubstitutor(val state: GenerationState) {
public class DefaultParameterValueSubstitutor(val state: GenerationState) {
/**
* If all of the parameters of the specified constructor declare default values,
* generates a no-argument constructor that passes default values for all arguments.
@@ -119,23 +118,22 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
val typeMapper = state.typeMapper
val isStatic = AsmUtil.isStaticMethod(contextKind, functionDescriptor)
val flags = AsmUtil.getVisibilityAccessFlag(functionDescriptor) or (if (isStatic) Opcodes.ACC_STATIC else 0)
val remainingParameters = getRemainingParameters(functionDescriptor.original, substituteCount)
val remainingParameters = getRemainingParameters(functionDescriptor.getOriginal(), substituteCount)
val signature = typeMapper.mapSignature(functionDescriptor, contextKind, remainingParameters)
val mv = classBuilder.newMethod(OtherOrigin(methodElement, functionDescriptor), flags,
signature.asmMethod.name,
signature.asmMethod.descriptor,
signature.genericsSignature,
signature.getAsmMethod().getName(),
signature.getAsmMethod().getDescriptor(),
signature.getGenericsSignature(),
FunctionCodegen.getThrownExceptions(functionDescriptor, typeMapper))
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, signature.returnType)
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, signature.getReturnType())
remainingParameters.withIndex().forEach {
val annotationCodegen = AnnotationCodegen.forParameter(it.index, mv, typeMapper)
annotationCodegen.genAnnotations(it.value, signature.valueParameters[it.index].asmType)
annotationCodegen.genAnnotations(it.value, signature.getValueParameters()[it.index].getAsmType())
}
if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) {
FunctionCodegen.generateLocalVariablesForParameters(mv, signature, null, Label(), Label(), remainingParameters, isStatic)
mv.visitEnd()
return
}
@@ -144,23 +142,20 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
val v = InstructionAdapter(mv)
mv.visitCode()
val methodBegin = Label()
mv.visitLabel(methodBegin)
val methodOwner = typeMapper.mapToCallableMethod(delegateFunctionDescriptor, false).owner
if (!isStatic) {
val thisIndex = frameMap.enterTemp(AsmTypes.OBJECT_TYPE)
v.load(thisIndex, methodOwner) // Load this on stack
}
else {
val delegateOwner = delegateFunctionDescriptor.containingDeclaration
if (delegateOwner is ClassDescriptor && delegateOwner.isCompanionObject) {
val delegateOwner = delegateFunctionDescriptor.getContainingDeclaration()
if (delegateOwner is ClassDescriptor && delegateOwner.isCompanionObject()) {
val singletonValue = StackValue.singleton(delegateOwner, typeMapper)
singletonValue.put(singletonValue.type, v);
}
}
val receiver = functionDescriptor.extensionReceiverParameter
val receiver = functionDescriptor.getExtensionReceiverParameter()
if (receiver != null) {
val receiverType = typeMapper.mapType(receiver)
val receiverIndex = frameMap.enter(receiver, receiverType)
@@ -172,8 +167,8 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
var mask = 0
val masks = arrayListOf<Int>()
for (parameterDescriptor in functionDescriptor.valueParameters) {
val paramType = typeMapper.mapType(parameterDescriptor.type)
for (parameterDescriptor in functionDescriptor.getValueParameters()) {
val paramType = typeMapper.mapType(parameterDescriptor.getType())
if (parameterDescriptor in remainingParameters) {
val index = frameMap.getIndex(parameterDescriptor)
StackValue.local(index, paramType).put(paramType, v)
@@ -189,57 +184,50 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
}
}
masks.add(mask)
for (m in masks) {
v.iconst(m)
}
// for default constructors: just marks default constructor (see DEFAULT_CONSTRUCTOR_MARKER)
// for default methods: contains MethodHandle for super calls ('null' cause not super call)
v.aconst(null)
// constructors with default arguments has last synthetic argument of specific type
if (functionDescriptor is ConstructorDescriptor) {
v.aconst(null)
}
val defaultMethod = typeMapper.mapDefaultMethod(delegateFunctionDescriptor, contextKind)
if (functionDescriptor is ConstructorDescriptor) {
v.invokespecial(methodOwner.internalName, defaultMethod.name, defaultMethod.descriptor, false)
v.invokespecial(methodOwner.getInternalName(), defaultMethod.getName(), defaultMethod.getDescriptor(), false)
}
else {
v.invokestatic(methodOwner.internalName, defaultMethod.name, defaultMethod.descriptor, false)
v.invokestatic(methodOwner.getInternalName(), defaultMethod.getName(), defaultMethod.getDescriptor(), false)
}
v.areturn(signature.returnType)
val methodEnd = Label()
mv.visitLabel(methodEnd)
FunctionCodegen.generateLocalVariablesForParameters(mv, signature, null, methodBegin, methodEnd,
remainingParameters, isStatic)
v.areturn(signature.getReturnType())
FunctionCodegen.endVisit(mv, null, methodElement)
}
private fun getRemainingParameters(functionDescriptor: FunctionDescriptor,
substituteCount: Int): List<ValueParameterDescriptor> {
var remainingCount = functionDescriptor.countDefaultParameters() - substituteCount
return functionDescriptor.valueParameters.filter { !it.declaresDefaultValue() || --remainingCount >= 0 }
return functionDescriptor.getValueParameters().filter { !it.declaresDefaultValue() || --remainingCount >= 0 }
}
private fun isEmptyConstructorNeeded(constructorDescriptor: ConstructorDescriptor, classOrObject: KtClassOrObject): Boolean {
val classDescriptor = constructorDescriptor.containingDeclaration
if (classDescriptor.kind != ClassKind.CLASS) return false
val classDescriptor = constructorDescriptor.getContainingDeclaration()
if (classDescriptor.getKind() != ClassKind.CLASS) return false
if (classOrObject.isLocal()) return false
if (CodegenBinding.canHaveOuter(state.bindingContext, classDescriptor)) return false
if (Visibilities.isPrivate(classDescriptor.visibility) || Visibilities.isPrivate(constructorDescriptor.visibility))
if (Visibilities.isPrivate(classDescriptor.getVisibility()) || Visibilities.isPrivate(constructorDescriptor.getVisibility()))
return false
if (constructorDescriptor.valueParameters.isEmpty()) return false
if (constructorDescriptor.getValueParameters().isEmpty()) return false
if (classOrObject is KtClass && hasSecondaryConstructorsWithNoParameters(classOrObject)) return false
return constructorDescriptor.valueParameters.all { it.declaresDefaultValue() }
return constructorDescriptor.getValueParameters().all { it.declaresDefaultValue() }
}
private fun hasSecondaryConstructorsWithNoParameters(klass: KtClass) =
klass.getSecondaryConstructors().any { it.valueParameters.isEmpty() }
klass.getSecondaryConstructors().any { it.getValueParameters().isEmpty() }
}

View File

@@ -25,18 +25,18 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.RawSignature
import org.jetbrains.org.objectweb.asm.FieldVisitor
import org.jetbrains.org.objectweb.asm.MethodVisitor
abstract class DelegatingClassBuilderFactory(
public abstract class DelegatingClassBuilderFactory(
protected val delegate: ClassBuilderFactory
) : ClassBuilderFactory by delegate {
abstract override fun newClassBuilder(origin: JvmDeclarationOrigin): DelegatingClassBuilder
override fun asBytes(builder: ClassBuilder?): ByteArray? {
public override fun asBytes(builder: ClassBuilder?): ByteArray? {
return delegate.asBytes((builder as DelegatingClassBuilder).getDelegate())
}
override fun asText(builder: ClassBuilder?): String? {
public override fun asText(builder: ClassBuilder?): String? {
return delegate.asText((builder as DelegatingClassBuilder).getDelegate())
}
}

View File

@@ -24,9 +24,8 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.Stack;
import kotlin.Pair;
import kotlin.CollectionsKt;
import kotlin.Unit;
import kotlin.collections.CollectionsKt;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -40,6 +39,7 @@ import org.jetbrains.kotlin.codegen.inline.*;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethod;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicPropertyGetter;
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics;
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsnsKt;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState;
@@ -54,7 +54,6 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
import org.jetbrains.kotlin.jvm.bindingContextSlices.BindingContextSlicesKt;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
@@ -83,7 +82,6 @@ import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeProjection;
import org.jetbrains.kotlin.types.TypeUtils;
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Opcodes;
@@ -94,13 +92,15 @@ import java.util.*;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isInt;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.couldUseDirectAccessToProperty;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
import static org.jetbrains.kotlin.resolve.BindingContext.*;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isObject;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionExpression;
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -480,7 +480,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
markLineNumber(expression, isStatement);
v.mark(end);
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -1066,7 +1066,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
Type asmLoopRangeType = asmType(loopRangeType);
Collection<PropertyDescriptor> incrementProp =
loopRangeType.getMemberScope().getContributedVariables(Name.identifier("step"), NoLookupLocation.FROM_BACKEND);
loopRangeType.getMemberScope().getContributedVariables(Name.identifier("increment"), NoLookupLocation.FROM_BACKEND);
assert incrementProp.size() == 1 : loopRangeType + " " + incrementProp.size();
incrementType = asmType(incrementProp.iterator().next().getType());
@@ -1246,9 +1246,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
if (compileTimeValue == null) {
return null;
}
if (compileTimeValue.getUsesNonConstValAsConstant()) return null;
KotlinType expectedType = bindingContext.getType(expression);
return compileTimeValue.toConstantValue(expectedType);
}
@@ -1297,7 +1294,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -1436,7 +1433,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
JvmMethodSignature constructor = typeMapper.mapSignature(SamCodegenUtil.resolveSamAdapter(constructorDescriptor));
v.invokespecial(type.getInternalName(), "<init>", constructor.getAsmMethod().getDescriptor(), false);
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -1554,7 +1551,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
for (Function<StackValue, Void> task : Lists.reverse(leaveTasks)) {
task.fun(value);
}
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -2121,8 +2118,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
FieldAccessorKind fieldAccessorKind = FieldAccessorKind.NORMAL;
boolean isBackingFieldInClassCompanion = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
if (isBackingFieldInClassCompanion && (forceField || propertyDescriptor.isConst() && Visibilities.isPrivate(propertyDescriptor.getVisibility()))) {
boolean isBackingFieldInClassCompanion = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
if (isBackingFieldInClassCompanion && forceField) {
fieldAccessorKind = FieldAccessorKind.IN_CLASS_COMPANION;
}
else if (syntheticBackingField && context.getFirstCrossInlineOrNonInlineContext().getParentContext().getContextDescriptor() != containingDeclaration) {
@@ -2145,7 +2142,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
PropertyDescriptor originalPropertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor);
if (fieldAccessorKind != FieldAccessorKind.NORMAL) {
int flags = AsmUtil.getVisibilityForBackingField(propertyDescriptor, isDelegatedProperty);
int flags = AsmUtil.getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegatedProperty);
skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || skipAccessorsForPrivateFieldInOuterClass;
if (!skipPropertyAccessors) {
//noinspection ConstantConditions
@@ -2171,7 +2168,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
propertyDescriptor = context.accessibleDescriptor(propertyDescriptor, superCallTarget);
PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
if (getter != null && !isConstOrHasJvmFieldAnnotation(propertyDescriptor)) {
if (getter != null && !hasJvmFieldAnnotation(propertyDescriptor)) {
callableGetter = typeMapper.mapToCallableMethod(getter, isSuper);
}
}
@@ -2180,7 +2177,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
if (setter != null &&
!couldUseDirectAccessToProperty(propertyDescriptor, false, isDelegatedProperty, context) &&
!isConstOrHasJvmFieldAnnotation(propertyDescriptor)) {
!hasJvmFieldAnnotation(propertyDescriptor)) {
callableSetter = typeMapper.mapToCallableMethod(setter, isSuper);
}
}
@@ -2217,11 +2214,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
StackValue receiver
) {
Type type = typeMapper.mapType(propertyDescriptor.getOriginal().getType());
CallableMethod callableGetter =
typeMapper.mapToCallableMethod(context.accessibleDescriptor(propertyDescriptor.getGetMethod(), null), false);
CallableMethod callableGetter = typeMapper.mapToCallableMethod(propertyDescriptor.getGetMethod(), false);
FunctionDescriptor setMethod = propertyDescriptor.getSetMethod();
CallableMethod callableSetter =
setMethod != null ? typeMapper.mapToCallableMethod(context.accessibleDescriptor(setMethod, null), false) : null;
CallableMethod callableSetter = setMethod != null ? typeMapper.mapToCallableMethod(setMethod, false) : null;
return StackValue.property(propertyDescriptor, null, type, false, null, callableGetter, callableSetter, state, receiver);
}
@@ -2384,8 +2379,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
@NotNull CallGenerator callGenerator,
@NotNull ArgumentGenerator argumentGenerator
) {
boolean isConstructor = resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor;
if (!isConstructor) { // otherwise already
if (!(resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor)) { // otherwise already
receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod);
receiver.put(receiver.type, v);
callableMethod.afterReceiverGeneration(v);
@@ -2396,7 +2390,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
assert valueArguments != null : "Failed to arrange value arguments by index: " + resolvedCall.getResultingDescriptor();
DefaultCallArgs defaultArgs =
DefaultCallMask masks =
argumentGenerator.generate(valueArguments, new ArrayList<ResolvedValueArgument>(resolvedCall.getValueArguments().values()));
if (tailRecursionCodegen.isTailRecursion(resolvedCall)) {
@@ -2404,14 +2398,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return;
}
boolean defaultMaskWasGenerated = defaultArgs.generateOnStackIfNeeded(callGenerator, isConstructor);
boolean defaultMaskWasGenerated = masks.generateOnStackIfNeeded(callGenerator);
// Extra constructor marker argument
if (callableMethod instanceof CallableMethod) {
List<JvmMethodParameterSignature> callableParameters = ((CallableMethod) callableMethod).getValueParameters();
for (JvmMethodParameterSignature parameter: callableParameters) {
if (parameter.getKind() == JvmMethodParameterKind.CONSTRUCTOR_MARKER) {
callGenerator.putValueIfNeeded(parameter.getAsmType(), StackValue.constant(null, parameter.getAsmType()));
callGenerator.putValueIfNeeded(null, parameter.getAsmType(), StackValue.constant(null, parameter.getAsmType()));
}
}
}
@@ -2426,77 +2420,60 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
@NotNull
private CallGenerator getOrCreateCallGenerator(
protected CallGenerator getOrCreateCallGenerator(
@NotNull CallableDescriptor descriptor,
@Nullable KtElement callElement,
@Nullable TypeParameterMappings typeParameterMappings,
boolean isDefaultCompilation
@Nullable ReifiedTypeParameterMappings reifiedTypeParameterMappings
) {
if (callElement == null) return defaultCallGenerator;
// We should inline callable containing reified type parameters even if inline is disabled
// because they may contain something to reify and straight call will probably fail at runtime
boolean isInline = (state.isInlineEnabled() || InlineUtil.containsReifiedTypeParameters(descriptor)) &&
(InlineUtil.isInline(descriptor) || InlineUtil.isArrayConstructorWithLambda(descriptor));
InlineUtil.isInline(descriptor);
if (!isInline) return defaultCallGenerator;
FunctionDescriptor original = DescriptorUtils.unwrapFakeOverride((FunctionDescriptor) descriptor.getOriginal());
return new InlineCodegen(this, state, original, callElement, typeParameterMappings, isDefaultCompilation);
SimpleFunctionDescriptor original = DescriptorUtils.unwrapFakeOverride((SimpleFunctionDescriptor) descriptor.getOriginal());
return new InlineCodegen(this, state, original, callElement, reifiedTypeParameterMappings);
}
@NotNull
protected CallGenerator getOrCreateCallGeneratorForDefaultImplBody(@NotNull FunctionDescriptor descriptor, @Nullable KtNamedFunction function) {
return getOrCreateCallGenerator(descriptor, function, null, true);
public CallGenerator getOrCreateCallGenerator(@NotNull FunctionDescriptor descriptor, @Nullable KtNamedFunction function) {
return getOrCreateCallGenerator(descriptor, function, null);
}
@NotNull
CallGenerator getOrCreateCallGenerator(@NotNull ResolvedCall<?> resolvedCall) {
private CallGenerator getOrCreateCallGenerator(@NotNull ResolvedCall<?> resolvedCall) {
Map<TypeParameterDescriptor, KotlinType> typeArguments = resolvedCall.getTypeArguments();
TypeParameterMappings mappings = new TypeParameterMappings();
ReifiedTypeParameterMappings mappings = new ReifiedTypeParameterMappings();
for (Map.Entry<TypeParameterDescriptor, KotlinType> entry : typeArguments.entrySet()) {
TypeParameterDescriptor key = entry.getKey();
if (!key.isReified()) continue;
KotlinType type = entry.getValue();
boolean isReified = key.isReified() || InlineUtil.isArrayConstructorWithLambda(resolvedCall.getResultingDescriptor());
Pair<TypeParameterDescriptor, ReificationArgument> typeParameterAndReificationArgument = extractReificationArgument(type);
if (typeParameterAndReificationArgument == null) {
KotlinType approximatedType = CapturedTypeApproximationKt.approximateCapturedTypes(entry.getValue()).getUpper();
TypeParameterDescriptor parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type);
if (parameterDescriptor == null) {
// type is not generic
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE);
Type asmType = typeMapper.mapTypeParameter(approximatedType, signatureWriter);
Type asmType = typeMapper.mapTypeParameter(type, signatureWriter);
mappings.addParameterMappingToType(
key.getName().getIdentifier(), approximatedType, asmType, signatureWriter.toString(), isReified
key.getName().getIdentifier(),
type,
asmType,
signatureWriter.toString()
);
}
else {
mappings.addParameterMappingForFurtherReification(
key.getName().getIdentifier(), type, typeParameterAndReificationArgument.getSecond(), isReified
);
mappings.addParameterMappingToNewParameter(
key.getName().getIdentifier(), type,
parameterDescriptor.getName().getIdentifier());
}
}
return getOrCreateCallGenerator(
resolvedCall.getResultingDescriptor(), resolvedCall.getCall().getCallElement(), mappings, false);
}
@Nullable
private static Pair<TypeParameterDescriptor, ReificationArgument> extractReificationArgument(@NotNull KotlinType type) {
int arrayDepth = 0;
boolean isNullable = type.isMarkedNullable();
while (KotlinBuiltIns.isArray(type)) {
arrayDepth++;
type = type.getArguments().get(0).getType();
}
TypeParameterDescriptor parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type);
if (parameterDescriptor == null) return null;
return new Pair<TypeParameterDescriptor, ReificationArgument>(
parameterDescriptor,
new ReificationArgument(parameterDescriptor.getName().asString(), isNullable, arrayDepth));
resolvedCall.getResultingDescriptor(), resolvedCall.getCall().getCallElement(), mappings
);
}
@NotNull
@@ -2752,17 +2729,19 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
VariableDescriptor variableDescriptor = bindingContext.get(VARIABLE, expression);
if (variableDescriptor != null) {
return generatePropertyReference(expression, variableDescriptor, resolvedCall);
return generatePropertyReference(expression, variableDescriptor, (VariableDescriptor) resolvedCall.getResultingDescriptor(),
resolvedCall.getDispatchReceiver());
}
throw new UnsupportedOperationException("Unsupported callable reference expression: " + expression.getText());
}
@NotNull
private StackValue generatePropertyReference(
public StackValue generatePropertyReference(
@NotNull KtElement element,
@NotNull VariableDescriptor variableDescriptor,
@NotNull ResolvedCall<?> resolvedCall
@NotNull VariableDescriptor target,
@Nullable ReceiverValue dispatchReceiver
) {
ClassDescriptor classDescriptor = CodegenBinding.anonymousClassForCallable(bindingContext, variableDescriptor);
@@ -2774,7 +2753,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
PropertyReferenceCodegen codegen = new PropertyReferenceCodegen(
state, parentCodegen, context.intoAnonymousClass(classDescriptor, this, OwnerKind.IMPLEMENTATION),
element, classBuilder, resolvedCall
element, classBuilder, classDescriptor, target, dispatchReceiver
);
codegen.generate();
@@ -2799,13 +2778,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
"Non-reified type parameter under ::class should be rejected by type checker: " + typeParameterDescriptor;
assert codegen != null :
"Reference to member of reified type should be rejected by type checker " + typeParameterDescriptor;
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.JAVA_CLASS);
codegen.putReifierMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME);
}
putJavaLangClassInstance(v, classAsmType);
wrapJavaClassIntoKClass(v);
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -3264,7 +3243,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
value.store(StackValue.onStack(storeType), v, true);
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -3348,7 +3327,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
Type type = expressionType(expression);
if (type.getSort() == Type.ARRAY) {
//noinspection ConstantConditions
return generateNewArray(expression, bindingContext.getType(expression), resolvedCall);
return generateNewArray(expression, bindingContext.getType(expression));
}
return generateConstructorCall(resolvedCall, type);
@@ -3389,38 +3368,33 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
CallableMethod method = typeMapper.mapToCallableMethod(constructor, false);
invokeMethodWithArguments(method, resolvedCall, StackValue.none());
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
public StackValue generateNewArray(
@NotNull KtCallExpression expression, @NotNull final KotlinType arrayType, @NotNull ResolvedCall<?> resolvedCall
) {
List<KtValueArgument> args = expression.getValueArguments();
assert args.size() == 1 || args.size() == 2 : "Unknown constructor called: " + args.size() + " arguments";
public StackValue generateNewArray(@NotNull KtCallExpression expression, @NotNull final KotlinType arrayType) {
assert expression.getValueArguments().size() == 1 : "Size argument expected";
if (args.size() == 1) {
final KtExpression sizeExpression = args.get(0).getArgumentExpression();
return StackValue.operation(typeMapper.mapType(arrayType), new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
gen(sizeExpression, Type.INT_TYPE);
newArrayInstruction(arrayType);
return Unit.INSTANCE;
}
});
}
final KtExpression sizeExpression = expression.getValueArguments().get(0).getArgumentExpression();
Type type = typeMapper.mapType(arrayType);
return invokeFunction(resolvedCall, StackValue.none());
return StackValue.operation(type, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
gen(sizeExpression, Type.INT_TYPE);
newArrayInstruction(arrayType);
return Unit.INSTANCE$;
}
});
}
public void newArrayInstruction(@NotNull KotlinType arrayType) {
if (KotlinBuiltIns.isArray(arrayType)) {
KotlinType elementJetType = arrayType.getArguments().get(0).getType();
putReifiedOperationMarkerIfTypeIsReifiedParameter(
putReifierMarkerIfTypeIsReifiedParameter(
elementJetType,
ReifiedTypeInliner.OperationKind.NEW_ARRAY
ReifiedTypeInliner.NEW_ARRAY_MARKER_METHOD_NAME
);
v.newarray(boxType(asmType(elementJetType)));
}
@@ -3487,6 +3461,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
ResolvedCall<FunctionDescriptor> resolvedCall = isGetter ? resolvedGetCall : resolvedSetCall;
assert resolvedCall != null : "couldn't find resolved call: " + expression.getText();
ArgumentGenerator argumentGenerator = new CallBasedArgumentGenerator(
this, defaultCallGenerator, resolvedCall.getResultingDescriptor().getValueParameters(), callable.getValueParameterTypes()
);
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
assert valueArguments != null : "Failed to arrange value arguments by index: " + operationDescriptor;
@@ -3497,7 +3475,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
return new StackValue.CollectionElementReceiver(
callable, receiver, resolvedGetCall, resolvedSetCall, isGetter, this, valueArguments
callable, receiver, resolvedGetCall, resolvedSetCall, isGetter, this, argumentGenerator, valueArguments
);
}
@@ -3645,7 +3623,7 @@ The "returned" value of try expression with no finally is either the last expres
if (finallyBlock != null) {
blockStackElements.pop();
}
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -3693,19 +3671,23 @@ The "returned" value of try expression with no finally is either the last expres
StackValue.putUnitInstance(v);
}
boolean safeAs = opToken == KtTokens.AS_SAFE;
Type type = boxType(asmType(rightType));
if (TypeUtils.isReifiedTypeParameter(rightType)) {
putReifiedOperationMarkerIfTypeIsReifiedParameter(rightType,
safeAs ? ReifiedTypeInliner.OperationKind.SAFE_AS
: ReifiedTypeInliner.OperationKind.AS);
v.checkcast(type);
return Unit.INSTANCE;
if (opToken != KtTokens.AS_SAFE) {
if (!TypeUtils.isNullableType(rightType) && !TypeUtils.isReifiedTypeParameter(rightType)) {
CodegenUtilKt.generateNullCheckForNonSafeAs(v, rightType);
}
}
else {
v.dup();
generateInstanceOfInstruction(rightType);
Label ok = new Label();
v.ifne(ok);
v.pop();
v.aconst(null);
v.mark(ok);
}
CodegenUtilKt.generateAsCast(v, rightType, type, safeAs);
return Unit.INSTANCE;
generateCheckCastInstruction(rightType, opToken == KtTokens.AS_SAFE);
return Unit.INSTANCE$;
}
});
}
@@ -3743,11 +3725,11 @@ The "returned" value of try expression with no finally is either the last expres
private StackValue generateIsCheck(StackValue expressionToMatch, KtTypeReference typeReference, boolean negated) {
KotlinType jetType = bindingContext.get(TYPE, typeReference);
markStartLineNumber(typeReference);
StackValue value = generateIsCheck(expressionToMatch, jetType, false);
StackValue value = generateInstanceOf(expressionToMatch, jetType, false);
return negated ? StackValue.not(value) : value;
}
private StackValue generateIsCheck(final StackValue expressionToGen, final KotlinType kotlinType, final boolean leaveExpressionOnStack) {
private StackValue generateInstanceOf(final StackValue expressionToGen, final KotlinType kotlinType, final boolean leaveExpressionOnStack) {
return StackValue.operation(Type.BOOLEAN_TYPE, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
@@ -3755,35 +3737,46 @@ The "returned" value of try expression with no finally is either the last expres
if (leaveExpressionOnStack) {
v.dup();
}
Type type = boxType(asmType(kotlinType));
if (TypeUtils.isReifiedTypeParameter(kotlinType)) {
putReifiedOperationMarkerIfTypeIsReifiedParameter(kotlinType, ReifiedTypeInliner.OperationKind.IS);
v.instanceOf(type);
return null;
}
CodegenUtilKt.generateIsCheck(v, kotlinType, type);
CodegenUtilKt.generateIsCheck(v, kotlinType.isMarkedNullable() && !TypeUtils.isReifiedTypeParameter(kotlinType), new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
generateInstanceOfInstruction(kotlinType);
return Unit.INSTANCE;
}
});
return null;
}
});
}
public void putReifiedOperationMarkerIfTypeIsReifiedParameter(
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind
) {
Pair<TypeParameterDescriptor, ReificationArgument> typeParameterAndReificationArgument = extractReificationArgument(type);
if (typeParameterAndReificationArgument != null && typeParameterAndReificationArgument.getFirst().isReified()) {
TypeParameterDescriptor typeParameterDescriptor = typeParameterAndReificationArgument.getFirst();
private void generateInstanceOfInstruction(@NotNull KotlinType jetType) {
Type type = boxType(asmType(jetType));
putReifierMarkerIfTypeIsReifiedParameter(jetType, ReifiedTypeInliner.INSTANCEOF_MARKER_METHOD_NAME);
TypeIntrinsics.instanceOf(v, jetType, type);
}
@NotNull
private StackValue generateCheckCastInstruction(@NotNull KotlinType jetType, boolean safeAs) {
Type type = boxType(asmType(jetType));
putReifierMarkerIfTypeIsReifiedParameter(jetType,
safeAs ? ReifiedTypeInliner.SAFE_CHECKCAST_MARKER_METHOD_NAME
: ReifiedTypeInliner.CHECKCAST_MARKER_METHOD_NAME);
TypeIntrinsics.checkcast(v, jetType, type, safeAs);
return StackValue.onStack(type);
}
public void putReifierMarkerIfTypeIsReifiedParameter(@NotNull KotlinType type, @NotNull String markerMethodName) {
TypeParameterDescriptor typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type);
if (typeParameterDescriptor != null && typeParameterDescriptor.isReified()) {
if (typeParameterDescriptor.getContainingDeclaration() != context.getContextDescriptor()) {
parentCodegen.getReifiedTypeParametersUsages().
addUsedReifiedParameter(typeParameterDescriptor.getName().asString());
}
v.iconst(operationKind.getId());
v.visitLdcInsn(typeParameterAndReificationArgument.getSecond().asString());
boolean putNullableFlag = ReifiedTypeInliner.isNullableMarkerInstruction(markerMethodName) && type.isMarkedNullable();
v.visitLdcInsn(typeParameterDescriptor.getName().asString() + (putNullableFlag ? "?" : ""));
v.invokestatic(
IntrinsicMethods.INTRINSICS_CLASS_NAME, ReifiedTypeInliner.REIFIED_OPERATION_MARKER_METHOD_NAME,
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, Type.getType(String.class)), false
IntrinsicMethods.INTRINSICS_CLASS_NAME, markerMethodName,
Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class)), false
);
}
}
@@ -3811,7 +3804,7 @@ The "returned" value of try expression with no finally is either the last expres
);
if (switchCodegen != null) {
switchCodegen.generate();
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
int subjectLocal = expr != null ? myFrameMap.enterTemp(subjectType) : -1;

View File

@@ -33,12 +33,17 @@ public class FieldInfo {
@NotNull
public static FieldInfo createForSingleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper) {
return createForSingleton(classDescriptor, typeMapper, false);
}
@NotNull
public static FieldInfo createForSingleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper, boolean oldSingleton) {
if (!classDescriptor.getKind().isSingleton() || DescriptorUtils.isEnumEntry(classDescriptor)) {
throw new UnsupportedOperationException("Can't create singleton field for class: " + classDescriptor);
}
if (isNonCompanionObject(classDescriptor) || COMPANION_OBJECT_MAPPING.hasMappingToObject(classDescriptor)) {
return createSingletonViaInstance(classDescriptor, typeMapper);
return createSingletonViaInstance(classDescriptor, typeMapper, oldSingleton);
}
else {
ClassDescriptor ownerDescriptor = DescriptorUtils.getParentOfType(classDescriptor, ClassDescriptor.class);
@@ -51,10 +56,11 @@ public class FieldInfo {
@NotNull
public static FieldInfo createSingletonViaInstance(
@NotNull ClassDescriptor classDescriptor,
@NotNull JetTypeMapper typeMapper
@NotNull JetTypeMapper typeMapper,
boolean oldSingleton
) {
Type type = typeMapper.mapType(classDescriptor);
return new FieldInfo(type, type, JvmAbi.INSTANCE_FIELD, true);
return new FieldInfo(type, type, oldSingleton ? JvmAbi.DEPRECATED_INSTANCE_FIELD : JvmAbi.INSTANCE_FIELD, true);
}
@NotNull

View File

@@ -47,7 +47,7 @@ public class FrameMap {
myVarSizes.remove(descriptor);
int oldIndex = myVarIndex.remove(descriptor);
if (oldIndex != myMaxIndex) {
throw new IllegalStateException("Descriptor can be left only if it is last: " + descriptor);
throw new IllegalStateException("descriptor can be left only if it is last");
}
return oldIndex;
}

View File

@@ -21,14 +21,15 @@ import com.intellij.psi.PsiElement;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import kotlin.text.StringsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.bridges.Bridge;
import org.jetbrains.kotlin.backend.common.bridges.ImplKt;
import org.jetbrains.kotlin.codegen.annotation.AnnotatedWithOnlyTargetedAnnotations;
import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics;
import org.jetbrains.kotlin.codegen.optimization.OptimizationMethodVisitor;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
@@ -39,6 +40,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers;
import org.jetbrains.kotlin.load.kotlin.nativeDeclarations.NativeKt;
import org.jetbrains.kotlin.name.FqName;
@@ -58,7 +60,10 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeUtils;
import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method;
import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor;
@@ -72,12 +77,11 @@ import java.util.Set;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNullableAny;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getSuperClassDescriptor;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -157,7 +161,7 @@ public class FunctionCodegen {
int flags = getMethodAsmFlags(functionDescriptor, contextKind);
boolean isNative = NativeKt.hasNativeAnnotation(functionDescriptor);
if (isNative && owner instanceof MultifileClassFacadeContext) {
if (isNative && owner instanceof DelegatingFacadeContext) {
// Native methods are only defined in facades and do not need package part implementations
return;
}
@@ -168,6 +172,10 @@ public class FunctionCodegen {
jvmSignature.getGenericsSignature(),
getThrownExceptions(functionDescriptor, typeMapper));
String implClassName = CodegenContextUtil.getImplementationClassShortName(owner);
if (implClassName != null) {
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, functionDescriptor, implClassName);
}
if (CodegenContextUtil.isImplClassOwner(owner)) {
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, functionDescriptor, asmMethod);
}
@@ -229,6 +237,22 @@ public class FunctionCodegen {
else {
annotationCodegen.genAnnotations(functionDescriptor, asmMethod.getReturnType());
}
writePackageFacadeMethodAnnotationsIfNeeded(mv);
}
private void writePackageFacadeMethodAnnotationsIfNeeded(MethodVisitor mv) {
if (owner instanceof PackageFacadeContext) {
PackageFacadeContext packageFacadeContext = (PackageFacadeContext) owner;
Type delegateToClassType = packageFacadeContext.getPublicFacadeType();
if (delegateToClassType != null) {
String className = delegateToClassType.getClassName();
AnnotationVisitor
av = mv.visitAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_DELEGATED_METHOD), true);
av.visit(JvmAnnotationNames.IMPLEMENTATION_CLASS_NAME_FIELD_NAME, className);
av.visitEnd();
}
}
}
private void generateParameterAnnotations(
@@ -249,6 +273,9 @@ public class FunctionCodegen {
if (kind == JvmMethodParameterKind.VALUE) {
ValueParameterDescriptor parameter = iterator.next();
if (parameter.getIndex() != i) {
v.getSerializationBindings().put(INDEX_FOR_VALUE_PARAMETER, parameter, i);
}
AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, typeMapper);
if (functionDescriptor instanceof PropertySetterDescriptor) {
@@ -337,8 +364,8 @@ public class FunctionCodegen {
int functionFakeIndex = -1;
int lambdaFakeIndex = -1;
if (context.getParentContext() instanceof MultifileClassFacadeContext) {
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (MultifileClassFacadeContext) context.getParentContext());
if (context.getParentContext() instanceof DelegatingFacadeContext) {
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (DelegatingFacadeContext) context.getParentContext());
methodEnd = new Label();
}
else {
@@ -400,24 +427,11 @@ public class FunctionCodegen {
@NotNull Label methodEnd,
@NotNull OwnerKind ownerKind
) {
generateLocalVariablesForParameters(mv, jvmMethodSignature, thisType, methodBegin, methodEnd,
functionDescriptor.getValueParameters(),
AsmUtil.isStaticMethod(ownerKind, functionDescriptor));
}
public static void generateLocalVariablesForParameters(
@NotNull MethodVisitor mv,
@NotNull JvmMethodSignature jvmMethodSignature,
@Nullable Type thisType,
@NotNull Label methodBegin,
@NotNull Label methodEnd,
Collection<ValueParameterDescriptor> valueParameters,
boolean isStatic
) {
Iterator<ValueParameterDescriptor> valueParameterIterator = valueParameters.iterator();
Iterator<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters().iterator();
List<JvmMethodParameterSignature> params = jvmMethodSignature.getValueParameters();
int shift = 0;
boolean isStatic = AsmUtil.isStaticMethod(ownerKind, functionDescriptor);
if (!isStatic) {
//add this
if (thisType != null) {
@@ -435,7 +449,7 @@ public class FunctionCodegen {
String parameterName;
if (kind == JvmMethodParameterKind.VALUE) {
ValueParameterDescriptor parameter = valueParameterIterator.next();
ValueParameterDescriptor parameter = valueParameters.next();
parameterName = parameter.getName().asString();
}
else {
@@ -454,9 +468,9 @@ public class FunctionCodegen {
private static void generateFacadeDelegateMethodBody(
@NotNull MethodVisitor mv,
@NotNull Method asmMethod,
@NotNull MultifileClassFacadeContext context
@NotNull DelegatingFacadeContext context
) {
generateDelegateToMethodBody(true, mv, asmMethod, context.getFilePartType().getInternalName());
generateDelegateToMethodBody(true, mv, asmMethod, context.getDelegateToClassType().getInternalName());
}
private static void generateDelegateToMethodBody(
@@ -679,14 +693,14 @@ public class FunctionCodegen {
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, defaultMethod.getReturnType());
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
if (this.owner instanceof MultifileClassFacadeContext) {
if (this.owner instanceof DelegatingFacadeContext) {
mv.visitCode();
generateFacadeDelegateMethodBody(mv, defaultMethod, (MultifileClassFacadeContext) this.owner);
generateFacadeDelegateMethodBody(mv, defaultMethod, (DelegatingFacadeContext) this.owner);
endVisit(mv, "default method delegation", getSourceFromDescriptor(functionDescriptor));
}
else {
mv.visitCode();
generateDefaultImplBody(owner, functionDescriptor, mv, loadStrategy, function, memberCodegen, defaultMethod);
generateDefaultImplBody(owner, functionDescriptor, mv, loadStrategy, function, memberCodegen);
endVisit(mv, "default method", getSourceFromDescriptor(functionDescriptor));
}
}
@@ -698,8 +712,7 @@ public class FunctionCodegen {
@NotNull MethodVisitor mv,
@NotNull DefaultParameterValueLoader loadStrategy,
@Nullable KtNamedFunction function,
@NotNull MemberCodegen<?> parentCodegen,
@NotNull Method defaultMethod
@NotNull MemberCodegen<?> parentCodegen
) {
GenerationState state = parentCodegen.state;
JvmMethodSignature signature = state.getTypeMapper().mapSignature(functionDescriptor, methodContext.getContextKind());
@@ -709,10 +722,7 @@ public class FunctionCodegen {
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, signature.getReturnType(), methodContext, state, parentCodegen);
CallGenerator generator = codegen.getOrCreateCallGeneratorForDefaultImplBody(functionDescriptor, function);
InstructionAdapter iv = new InstructionAdapter(mv);
genDefaultSuperCallCheckIfNeeded(iv, defaultMethod);
CallGenerator generator = codegen.getOrCreateCallGenerator(functionDescriptor, function);
loadExplicitArgumentsOnStack(OBJECT_TYPE, isStatic, signature, generator);
@@ -723,6 +733,8 @@ public class FunctionCodegen {
capturedArgumentsCount++;
}
InstructionAdapter iv = new InstructionAdapter(mv);
int maskIndex = 0;
List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
for (int index = 0; index < valueParameters.size(); index++) {
@@ -745,7 +757,7 @@ public class FunctionCodegen {
iv.mark(loadArg);
}
generator.putValueIfNeeded(type, StackValue.local(parameterIndex, type));
generator.putValueIfNeeded(parameterDescriptor, type, StackValue.local(parameterIndex, type));
}
CallableMethod method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false);
@@ -755,22 +767,6 @@ public class FunctionCodegen {
iv.areturn(signature.getReturnType());
}
private static void genDefaultSuperCallCheckIfNeeded(@NotNull InstructionAdapter iv, @NotNull Method defaultMethod) {
String defaultMethodName = defaultMethod.getName();
if ("<init>".equals(defaultMethodName)) {
return;
}
Label end = new Label();
int handleIndex = (Type.getArgumentsAndReturnSizes(defaultMethod.getDescriptor()) >> 2) - 2; /*-1 for this, and -1 for handle*/
iv.load(handleIndex, OBJECT_TYPE);
iv.ifnull(end);
AsmUtil.genThrow(iv,
"java/lang/UnsupportedOperationException",
"Super calls with default arguments not supported in this target, function: " +
StringsKt.substringBeforeLast(defaultMethodName, JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, defaultMethodName));
iv.visitLabel(end);
}
@NotNull
private static FrameMap createFrameMap(
@NotNull GenerationState state,
@@ -810,14 +806,14 @@ public class FunctionCodegen {
) {
int var = 0;
if (!isStatic) {
callGenerator.putValueIfNeeded(ownerType, StackValue.local(var, ownerType));
callGenerator.putValueIfNeeded(null, ownerType, StackValue.local(var, ownerType));
var += ownerType.getSize();
}
for (JvmMethodParameterSignature parameterSignature : signature.getValueParameters()) {
if (parameterSignature.getKind() != JvmMethodParameterKind.VALUE) {
Type type = parameterSignature.getAsmType();
callGenerator.putValueIfNeeded(type, StackValue.local(var, type));
callGenerator.putValueIfNeeded(null, type, StackValue.local(var, type));
var += type.getSize();
}
}
@@ -913,7 +909,13 @@ public class FunctionCodegen {
iv.ifnonnull(afterBarrier);
}
else {
CodegenUtilKt.generateIsCheck(iv, kotlinType, boxType(delegateParameterType));
CodegenUtilKt.generateIsCheck(iv, kotlinType.isMarkedNullable(), new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
TypeIntrinsics.instanceOf(adapter, kotlinType, boxType(delegateParameterType));
return Unit.INSTANCE;
}
});
iv.ifne(afterBarrier);
}
@@ -945,7 +947,7 @@ public class FunctionCodegen {
@NotNull MethodContext context,
@NotNull MemberCodegen<?> parentCodegen
) {
Method delegateToMethod = typeMapper.mapToCallableMethod(delegatedTo, /* superCall = */ false).getAsmMethod();
Method delegateToMethod = typeMapper.mapSignature(delegatedTo).getAsmMethod();
Method delegateMethod = typeMapper.mapSignature(delegateFunction).getAsmMethod();
Type[] argTypes = delegateMethod.getArgumentTypes();

View File

@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.codegen;
import kotlin.collections.CollectionsKt;
import kotlin.CollectionsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.state.GenerationState;
@@ -110,7 +110,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
if (referencedFunction instanceof ConstructorDescriptor) {
if (returnType.getSort() == Type.ARRAY) {
//noinspection ConstantConditions
result = codegen.generateNewArray(fakeExpression, referencedFunction.getReturnType(), fakeResolvedCall);
result = codegen.generateNewArray(fakeExpression, referencedFunction.getReturnType());
}
else {
result = codegen.generateConstructorCall(fakeResolvedCall, returnType);

View File

@@ -19,8 +19,8 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.psi.PsiElement;
import com.intellij.util.ArrayUtil;
import kotlin.CollectionsKt;
import kotlin.Unit;
import kotlin.collections.CollectionsKt;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1;
import kotlin.jvm.functions.Function2;
@@ -41,9 +41,8 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
@@ -63,8 +62,8 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
import org.jetbrains.kotlin.serialization.ProtoBuf;
import org.jetbrains.kotlin.types.KotlinType;
@@ -75,7 +74,6 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.*;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
@@ -247,19 +245,26 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
@Override
protected void generateKotlinMetadataAnnotation() {
final DescriptorSerializer serializer =
DescriptorSerializer.create(descriptor, new JvmSerializerExtension(v.getSerializationBindings(), state));
protected void generateKotlinAnnotation() {
if (!isTopLevelOrInnerClass(descriptor)) {
AnnotationVisitor av = v.getVisitor().visitAnnotation(
asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_LOCAL_CLASS), true
);
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray());
av.visitEnd();
}
final ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
DescriptorSerializer serializer =
DescriptorSerializer.create(descriptor, new JvmSerializerExtension(
v.getSerializationBindings(), typeMapper, state.getUseTypeTableInSerializer()
));
WriteAnnotationUtilKt.writeKotlinMetadata(v, KotlinClassHeader.Kind.CLASS, new Function1<AnnotationVisitor, Unit>() {
@Override
public Unit invoke(AnnotationVisitor av) {
writeAnnotationData(av, serializer, classProto);
return Unit.INSTANCE;
}
});
ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
AnnotationVisitor av = v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_CLASS), true);
writeAnnotationData(av, serializer, classProto);
writeModuleName(av, state);
av.visitEnd();
}
private void writeEnclosingMethod() {
@@ -274,25 +279,25 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
private static final Map<FqName, String> KOTLIN_MARKER_INTERFACES = new HashMap<FqName, String>();
private static final Map<String, String> KOTLIN_MARKER_INTERFACES = new HashMap<String, String>();
static {
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.iterator, "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.iterable, "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.collection, "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.list, "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.listIterator, "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.set, "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.map, "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mapEntry, "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put("kotlin.Iterator", "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put("kotlin.Iterable", "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put("kotlin.Collection", "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put("kotlin.List", "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put("kotlin.ListIterator", "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put("kotlin.Set", "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put("kotlin.Map", "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put("kotlin.Map.Entry", "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableIterator, "kotlin/jvm/internal/markers/KMutableIterator");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableIterable, "kotlin/jvm/internal/markers/KMutableIterable");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableCollection, "kotlin/jvm/internal/markers/KMutableCollection");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableList, "kotlin/jvm/internal/markers/KMutableList");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableListIterator, "kotlin/jvm/internal/markers/KMutableListIterator");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableSet, "kotlin/jvm/internal/markers/KMutableSet");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableMap, "kotlin/jvm/internal/markers/KMutableMap");
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableMapEntry, "kotlin/jvm/internal/markers/KMutableMap$Entry");
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableIterator", "kotlin/jvm/internal/markers/KMutableIterator");
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableIterable", "kotlin/jvm/internal/markers/KMutableIterable");
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableCollection", "kotlin/jvm/internal/markers/KMutableCollection");
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableList", "kotlin/jvm/internal/markers/KMutableList");
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableListIterator", "kotlin/jvm/internal/markers/KMutableListIterator");
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableSet", "kotlin/jvm/internal/markers/KMutableSet");
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableMap", "kotlin/jvm/internal/markers/KMutableMap");
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableMap.MutableEntry", "kotlin/jvm/internal/markers/KMutableMap$Entry");
}
@NotNull
@@ -322,7 +327,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
String jvmInterfaceInternalName = jvmInterfaceType.getInternalName();
superInterfaces.add(jvmInterfaceInternalName);
FqName kotlinInterfaceName = DescriptorUtils.getFqName(supertype.getConstructor().getDeclarationDescriptor()).toSafe();
String kotlinInterfaceName = DescriptorUtils.getFqName(supertype.getConstructor().getDeclarationDescriptor()).asString();
String kotlinMarkerInterfaceInternalName = KOTLIN_MARKER_INTERFACES.get(kotlinInterfaceName);
if (kotlinMarkerInterfaceInternalName != null) {
kotlinMarkerInterfaces.add(kotlinMarkerInterfaceInternalName);
@@ -835,16 +840,22 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
private void generateFieldForSingleton() {
if (isEnumEntry(descriptor) || isCompanionObject(descriptor)) return;
if (isEnumEntry(descriptor)) return;
if (isNonCompanionObject(descriptor)) {
boolean isCompanionObject = isCompanionObject(descriptor);
if (isNonCompanionObject(descriptor) || isCompanionObject) {
StackValue.Field field = StackValue.singletonViaInstance(descriptor, typeMapper);
v.newField(JvmDeclarationOriginKt.OtherOrigin(myClass),
ACC_PUBLIC | ACC_STATIC | ACC_FINAL,
ACC_PUBLIC | ACC_STATIC | ACC_FINAL | (isCompanionObject ? ACC_DEPRECATED : 0),
field.name, field.type.getDescriptor(), null, null);
if (isNonCompanionObject(descriptor)) {
StackValue.Field oldField = StackValue.oldSingleton(descriptor, typeMapper);
v.newField(JvmDeclarationOriginKt.OtherOrigin(myClass), ACC_PUBLIC | ACC_STATIC | ACC_FINAL | ACC_DEPRECATED, oldField.name, oldField.type.getDescriptor(), null, null);
}
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
// Invoke the object constructor but ignore the result because INSTANCE will be initialized in the first line of <init>
// Invoke the object constructor but ignore the result because INSTANCE$ will be initialized in the first line of <init>
InstructionAdapter v = createOrGetClInitCodegen().v;
markLineNumberForElement(element, v);
v.anew(classAsmType);
@@ -863,6 +874,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
StackValue.Field field = StackValue.singleton(companionObjectDescriptor, typeMapper);
v.newField(JvmDeclarationOriginKt.OtherOrigin(companionObject), ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null);
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
if (!isCompanionObjectWithBackingFieldsInOuter(companionObjectDescriptor)) {
generateCompanionObjectInitializer(companionObjectDescriptor);
}
}
private void generateCompanionObjectBackingFieldCopies() {
@@ -872,7 +889,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
PropertyDescriptor property = info.descriptor;
Type type = typeMapper.mapType(property);
int modifiers = ACC_STATIC | ACC_FINAL | ACC_PUBLIC;
int modifiers = ACC_STATIC | ACC_FINAL | ACC_PUBLIC | (property.isConst() ? 0 : ACC_DEPRECATED);
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.Synthetic(DescriptorToSourceUtils.descriptorToDeclaration(property), property),
modifiers, context.getFieldName(property, false),
type.getDescriptor(), typeMapper.mapFieldSignature(property.getType(), property),
@@ -914,13 +931,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateCompanionObjectInitializer(@NotNull ClassDescriptor companionObject) {
ExpressionCodegen codegen = createOrGetClInitCodegen();
FunctionDescriptor constructor = (FunctionDescriptor) context.accessibleDescriptor(
CollectionsKt.single(companionObject.getConstructors()), /* superCallExpression = */ null
);
generateMethodCallTo(constructor, null, codegen.v);
StackValue instance = StackValue.onStack(typeMapper.mapClass(companionObject));
StackValue.singleton(companionObject, typeMapper).store(instance, codegen.v, true);
//TODO: uncomment when DEPRECATED INSTANCE is removed
//FunctionDescriptor constructor = (FunctionDescriptor) context.accessibleDescriptor(
// CollectionsKt.single(companionObject.getConstructors()), /* superCallExpression = */ null
//);
//generateMethodCallTo(constructor, null, codegen.v);
//StackValue instance = StackValue.onStack(typeMapper.mapClass(companionObject));
StackValue.singleton(companionObject, typeMapper).store(StackValue.singletonViaInstance(companionObject, typeMapper), codegen.v, true);
}
private void generatePrimaryConstructor(final DelegationFieldsInfo delegationFieldsInfo) {
@@ -990,8 +1007,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor,
getDelegationConstructorCall(bindingContext, constructorDescriptor));
if (isNonCompanionObject(descriptor)) {
if (isObject(descriptor)) {
StackValue.singletonViaInstance(descriptor, typeMapper).store(StackValue.LOCAL_0, iv);
if (isNonCompanionObject(descriptor)) {
StackValue.oldSingleton(descriptor, typeMapper).store(StackValue.LOCAL_0, iv);
}
}
for (KtSuperTypeListEntry specifier : myClass.getSuperTypeListEntries()) {
@@ -1015,13 +1035,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
curParam++;
}
if (isCompanionObject(descriptor)) {
ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
parentCodegen.generateCompanionObjectInitializer(descriptor);
}
if (JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
if (isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
final ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
parentCodegen.generateCompanionObjectInitializer(descriptor);
generateInitializers(new Function0<ExpressionCodegen>() {
@Override
public ExpressionCodegen invoke() {

View File

@@ -23,29 +23,29 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
class InlineCycleReporter(val diagnostics: DiagnosticSink) {
public class InlineCycleReporter(val diagnostics: DiagnosticSink) {
val processingFunctions = linkedMapOf<PsiElement, CallableDescriptor>()
fun enterIntoInlining(call: ResolvedCall<*>?): Boolean {
public fun enterIntoInlining(call: ResolvedCall<*>?): Boolean {
//null call for default method inlining
if (call != null) {
val callElement = call.call.callElement
val callElement = call.getCall().getCallElement()
if (processingFunctions.contains(callElement)) {
val cycle = processingFunctions.asSequence().dropWhile { it.key != callElement }
val cycle = processingFunctions.asSequence().dropWhile { it.getKey() != callElement }
cycle.forEach {
diagnostics.report(Errors.INLINE_CALL_CYCLE.on(it.key, it.value))
diagnostics.report(Errors.INLINE_CALL_CYCLE.on(it.getKey(), it.getValue()))
}
return false
}
processingFunctions.put(callElement, call.resultingDescriptor.original)
processingFunctions.put(callElement, call.getResultingDescriptor().getOriginal())
}
return true
}
fun exitFromInliningOf(call: ResolvedCall<*>?) {
public fun exitFromInliningOf(call: ResolvedCall<*>?) {
if (call != null) {
val callElement = call.call.callElement
val callElement = call.getCall().getCallElement()
processingFunctions.remove(callElement)
}
}

View File

@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_INTERFACE_DEFAULT_IMPLS
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtClassOrObject
@@ -37,7 +39,7 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes.*
import java.util.*
class InterfaceImplBodyCodegen(
public class InterfaceImplBodyCodegen(
aClass: KtClassOrObject,
context: ClassContext,
v: ClassBuilder,
@@ -53,7 +55,7 @@ class InterfaceImplBodyCodegen(
typeMapper.mapDefaultImpls(descriptor).internalName,
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY
)
v.visitSource(myClass.containingFile.name, null)
v.visitSource(myClass.getContainingFile().getName(), null)
}
override fun classForInnerClassRecord(): ClassDescriptor? {
@@ -68,12 +70,12 @@ class InterfaceImplBodyCodegen(
}
override fun generateSyntheticParts() {
for (memberDescriptor in descriptor.defaultType.memberScope.getContributedDescriptors()) {
for (memberDescriptor in descriptor.getDefaultType().getMemberScope().getContributedDescriptors()) {
if (memberDescriptor !is CallableMemberDescriptor) continue
if (memberDescriptor.kind.isReal) continue
if (memberDescriptor.visibility == Visibilities.INVISIBLE_FAKE) continue
if (memberDescriptor.modality == Modality.ABSTRACT) continue
if (memberDescriptor.getKind().isReal()) continue
if (memberDescriptor.getVisibility() == Visibilities.INVISIBLE_FAKE) continue
if (memberDescriptor.getModality() == Modality.ABSTRACT) continue
val implementation = findImplementationFromInterface(memberDescriptor) ?: continue
@@ -81,7 +83,7 @@ class InterfaceImplBodyCodegen(
if (implementation is JavaMethodDescriptor) continue
// We create a copy of the function with kind = DECLARATION so that FunctionCodegen will generate its body
val copy = memberDescriptor.copy(memberDescriptor.containingDeclaration, Modality.OPEN, memberDescriptor.visibility,
val copy = memberDescriptor.copy(memberDescriptor.getContainingDeclaration(), Modality.OPEN, memberDescriptor.getVisibility(),
CallableMemberDescriptor.Kind.DECLARATION, true)
if (memberDescriptor is FunctionDescriptor) {
@@ -89,13 +91,13 @@ class InterfaceImplBodyCodegen(
}
else if (memberDescriptor is PropertyDescriptor) {
implementation as PropertyDescriptor
val getter = (copy as PropertyDescriptor).getter
val implGetter = implementation.getter
val getter = (copy as PropertyDescriptor).getGetter()
val implGetter = implementation.getGetter()
if (getter != null && implGetter != null) {
generateDelegationToSuperTraitImpl(getter, implGetter)
}
val setter = copy.setter
val implSetter = implementation.setter
val setter = copy.getSetter()
val implSetter = implementation.getSetter()
if (setter != null && implSetter != null) {
generateDelegationToSuperTraitImpl(setter, implSetter)
}
@@ -119,10 +121,10 @@ class InterfaceImplBodyCodegen(
val iv = codegen.v
val method = typeMapper.mapToCallableMethod(delegateTo, true)
val myParameters = signature.valueParameters
val myParameters = signature.getValueParameters()
val calleeParameters = method.getValueParameters()
if (myParameters.size != calleeParameters.size) {
if (myParameters.size() != calleeParameters.size()) {
throw AssertionError(
"Method from super interface has a different signature.\n" +
"This method:\n%s\n%s\n%s\nSuper method:\n%s\n%s\n%s".format(
@@ -134,22 +136,25 @@ class InterfaceImplBodyCodegen(
var k = 0
val it = calleeParameters.iterator()
for (parameter in myParameters) {
val type = parameter.asmType
StackValue.local(k, type).put(it.next().asmType, iv)
k += type.size
val type = parameter.getAsmType()
StackValue.local(k, type).put(it.next().getAsmType(), iv)
k += type.getSize()
}
method.genInvokeInstruction(iv)
StackValue.coerce(method.returnType, signature.returnType, iv)
iv.areturn(signature.returnType)
StackValue.coerce(method.returnType, signature.getReturnType(), iv)
iv.areturn(signature.getReturnType())
}
})
}
override fun generateKotlinMetadataAnnotation() {
override fun generateKotlinAnnotation() {
(v as InterfaceImplClassBuilder).stopCounting()
writeSyntheticClassMetadata(v);
val av = v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(KOTLIN_INTERFACE_DEFAULT_IMPLS), true)
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray())
av.visitEnd()
AsmUtil.writeKotlinSyntheticClassAnnotation(v, state)
}
override fun done() {

View File

@@ -18,9 +18,9 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import kotlin.collections.CollectionsKt;
import kotlin.CollectionsKt;
import kotlin.StringsKt;
import kotlin.jvm.functions.Function1;
import kotlin.text.StringsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
@@ -28,8 +28,11 @@ import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.context.FacadePartWithSourceFile;
import org.jetbrains.kotlin.codegen.context.MethodContext;
import org.jetbrains.kotlin.codegen.context.RootContext;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.kotlin.ModuleMapping;
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityUtilsKt;
import org.jetbrains.kotlin.psi.KtFile;
@@ -41,12 +44,12 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
import java.io.File;
import static org.jetbrains.kotlin.descriptors.Modality.ABSTRACT;
import static org.jetbrains.kotlin.descriptors.Modality.FINAL;
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
public class JvmCodegenUtil {
@@ -127,10 +130,6 @@ public class JvmCodegenUtil {
);
}
public static boolean isConstOrHasJvmFieldAnnotation(@NotNull PropertyDescriptor propertyDescriptor) {
return propertyDescriptor.isConst() || hasJvmFieldAnnotation(propertyDescriptor);
}
public static boolean couldUseDirectAccessToProperty(
@NotNull PropertyDescriptor property,
boolean forGetter,
@@ -217,4 +216,18 @@ public class JvmCodegenUtil {
public static String getMappingFileName(@NotNull String moduleName) {
return "META-INF/" + moduleName + "." + ModuleMapping.MAPPING_FILE_EXT;
}
public static void writeAbiVersion(@NotNull AnnotationVisitor av) {
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray());
// TODO: drop after some time
av.visit(JvmAnnotationNames.OLD_ABI_VERSION_FIELD_NAME, 32);
}
public static void writeModuleName(@NotNull AnnotationVisitor av, @NotNull GenerationState state) {
String name = state.getModuleName();
if (!name.equals(JvmAbi.DEFAULT_MODULE_NAME)) {
av.visit(JvmAnnotationNames.MODULE_NAME_FIELD_NAME, name);
}
}
}

View File

@@ -40,7 +40,7 @@ public class JvmRuntimeTypes {
public JvmRuntimeTypes() {
ModuleDescriptorImpl module = TargetPlatformKt.createModule(
JvmPlatform.INSTANCE,
JvmPlatform.INSTANCE$,
Name.special("<jvm functions impl>"),
LockBasedStorageManager.NO_LOCKS
);

View File

@@ -79,14 +79,15 @@ class JvmStaticGenerator(
}
companion object {
@JvmStatic fun createStaticFunctionDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.correspondingProperty else descriptor
@JvmStatic
public fun createStaticFunctionDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.getCorrespondingProperty() else descriptor
val copies = CodegenUtil.copyFunctions(
memberDescriptor,
memberDescriptor,
descriptor.containingDeclaration.containingDeclaration,
descriptor.modality,
descriptor.visibility,
descriptor.getContainingDeclaration().getContainingDeclaration(),
descriptor.getModality(),
descriptor.getVisibility(),
CallableMemberDescriptor.Kind.SYNTHESIZED,
false
)

View File

@@ -18,7 +18,9 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.psi.PsiElement;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.CodegenUtil;
@@ -44,6 +46,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
import org.jetbrains.kotlin.storage.NotNullLazyValue;
@@ -119,7 +122,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
generateSyntheticParts();
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
generateKotlinMetadataAnnotation();
generateKotlinAnnotation();
}
done();
@@ -132,7 +135,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
protected void generateSyntheticParts() {
}
protected abstract void generateKotlinMetadataAnnotation();
protected abstract void generateKotlinAnnotation();
@Nullable
protected ClassDescriptor classForInnerClassRecord() {
@@ -302,7 +305,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
if (outermost instanceof ClassContext) {
return typeMapper.mapType(((ClassContext) outermost).getContextDescriptor());
}
else if (outermost instanceof MultifileClassFacadeContext || outermost instanceof DelegatingToPartContext) {
else if (outermost instanceof DelegatingFacadeContext || outermost instanceof DelegatingToPartContext) {
Type implementationOwnerType = CodegenContextUtil.getImplementationOwnerClassType(outermost);
if (implementationOwnerType != null) {
return implementationOwnerType;
@@ -495,23 +498,37 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
iv.dup();
iv.iconst(i);
int receiverCount = (property.getDispatchReceiverParameter() != null ? 1 : 0) +
(property.getExtensionReceiverParameter() != null ? 1 : 0);
Type implType = property.isVar() ? MUTABLE_PROPERTY_REFERENCE_IMPL[receiverCount] : PROPERTY_REFERENCE_IMPL[receiverCount];
iv.anew(implType);
iv.dup();
// TODO: generate the container once and save to a local field instead (KT-10495)
ClosureCodegen.generateCallableReferenceDeclarationContainer(iv, property, state);
iv.aconst(property.getName().asString());
iv.aconst(PropertyReferenceCodegen.getPropertyReferenceSignature(property, state));
iv.invokespecial(
implType.getInternalName(), "<init>",
Type.getMethodDescriptor(Type.VOID_TYPE, K_DECLARATION_CONTAINER_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE), false
);
Method wrapper = PropertyReferenceCodegen.getWrapperMethodForPropertyReference(property, receiverCount);
iv.invokestatic(REFLECTION, wrapper.getName(), wrapper.getDescriptor(), false);
StackValue value;
// TODO: remove this option and always generate PropertyReferenceNImpl creation
if ("true".equalsIgnoreCase(System.getProperty("kotlin.jvm.optimize.delegated.properties"))) {
int receiverCount = (property.getDispatchReceiverParameter() != null ? 1 : 0) +
(property.getExtensionReceiverParameter() != null ? 1 : 0);
Type implType = property.isVar() ? MUTABLE_PROPERTY_REFERENCE_IMPL[receiverCount] : PROPERTY_REFERENCE_IMPL[receiverCount];
iv.anew(implType);
iv.dup();
// TODO: generate the container once and save to a local field instead
ClosureCodegen.generateCallableReferenceDeclarationContainer(iv, property, state);
iv.aconst(property.getName().asString());
iv.aconst(PropertyReferenceCodegen.getPropertyReferenceSignature(property, state));
iv.invokespecial(
implType.getInternalName(), "<init>",
Type.getMethodDescriptor(Type.VOID_TYPE, K_DECLARATION_CONTAINER_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE), false
);
value = StackValue.onStack(implType);
Method wrapper = PropertyReferenceCodegen.getWrapperMethodForPropertyReference(property, receiverCount);
iv.invokestatic(REFLECTION, wrapper.getName(), wrapper.getDescriptor(), false);
}
else {
ReceiverParameterDescriptor dispatchReceiver = property.getDispatchReceiverParameter();
StackValue.onStack(implType).put(K_PROPERTY_TYPE, iv);
//noinspection ConstantConditions
value = createOrGetClInitCodegen().generatePropertyReference(
delegatedProperties.get(i).getDelegate(), property, property,
dispatchReceiver != null ? new TransientReceiver(dispatchReceiver.getType()) : null
);
}
value.put(K_PROPERTY_TYPE, iv);
iv.astore(K_PROPERTY_TYPE);
}
@@ -550,17 +567,20 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
return sourceMapper;
}
protected void generateConstInstance(@NotNull Type thisAsmType, @NotNull Type fieldAsmType) {
v.newField(
JvmDeclarationOriginKt.OtherOrigin(element), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD,
fieldAsmType.getDescriptor(), null, null
);
protected void generateConstInstance(
@NotNull Type thisAsmType,
@NotNull Type fieldAsmType,
@NotNull Function1<InstructionAdapter, Unit> initialization
) {
v.newField(JvmDeclarationOriginKt.OtherOrigin(element), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD, fieldAsmType.getDescriptor(),
null, null);
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
InstructionAdapter iv = createOrGetClInitCodegen().v;
iv.anew(thisAsmType);
iv.dup();
iv.invokespecial(thisAsmType.getInternalName(), "<init>", "()V", false);
initialization.invoke(iv);
iv.putstatic(thisAsmType.getInternalName(), JvmAbi.INSTANCE_FIELD, fieldAsmType.getDescriptor());
}
}
@@ -601,13 +621,12 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
@Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
boolean syntheticBackingField = accessor instanceof AccessorForPropertyBackingFieldFromLocal;
boolean forceFieldForCompanionProperty = JvmAbi.isPropertyWithBackingFieldInOuterClass(original) &&
!isCompanionObject(accessor.getContainingDeclaration());
boolean forceField = forceFieldForCompanionProperty ||
boolean forceField = (AsmUtil.isPropertyWithBackingFieldInOuterClass(original) &&
!isCompanionObject(accessor.getContainingDeclaration())) ||
syntheticBackingField ||
original.getVisibility() == JavaVisibilities.PROTECTED_STATIC_VISIBILITY;
StackValue property = codegen.intermediateValueForProperty(
original, forceField, syntheticBackingField, accessor.getSuperCallTarget(), forceFieldForCompanionProperty, StackValue.none()
original, forceField, syntheticBackingField, accessor.getSuperCallTarget(), true, StackValue.none()
);
InstructionAdapter iv = codegen.v;
@@ -653,7 +672,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
}
}
protected StackValue generateMethodCallTo(
private StackValue generateMethodCallTo(
@NotNull FunctionDescriptor functionDescriptor,
@Nullable FunctionDescriptor accessorDescriptor,
@NotNull InstructionAdapter iv

View File

@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.PackageParts
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
@@ -55,9 +54,9 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import java.util.*
class MultifileClassCodegen(
public class MultifileClassCodegen(
private val state: GenerationState,
val files: Collection<KtFile>,
public val files: Collection<KtFile>,
private val facadeFqName: FqName
) {
private val facadeClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(facadeFqName)
@@ -75,7 +74,7 @@ class MultifileClassCodegen(
private fun getDeserializedCallables(compiledPackageFragment: PackageFragmentDescriptor) =
compiledPackageFragment.getMemberScope().getContributedDescriptors(DescriptorKindFilter.CALLABLES, MemberScope.ALL_NAME_FILTER).filterIsInstance<DeserializedCallableMemberDescriptor>()
val packageParts = PackageParts(facadeFqName.parent().asString())
public val packageParts = PackageParts(facadeFqName.parent().asString())
private val classBuilder = ClassBuilderOnDemand {
val originFile = files.firstOrNull()
@@ -104,7 +103,7 @@ class MultifileClassCodegen(
classBuilder
}
fun generate(errorHandler: CompilationErrorHandler) {
public fun generate(errorHandler: CompilationErrorHandler) {
val generateCallableMemberTasks = HashMap<CallableMemberDescriptor, () -> Unit>()
val partFqNames = arrayListOf<FqName>()
@@ -112,7 +111,7 @@ class MultifileClassCodegen(
generateDelegatesToPreviouslyCompiledParts(generateCallableMemberTasks, partFqNames)
if (!partFqNames.isEmpty()) {
if (!generateCallableMemberTasks.isEmpty()) {
generateMultifileFacadeClass(generateCallableMemberTasks, partFqNames)
}
}
@@ -153,7 +152,7 @@ class MultifileClassCodegen(
writeKotlinMultifileFacadeAnnotationIfNeeded(partFqNames)
}
fun generateClassOrObject(classOrObject: KtClassOrObject, packagePartContext: FieldOwnerContext<PackageFragmentDescriptor>) {
public fun generateClassOrObject(classOrObject: KtClassOrObject, packagePartContext: FieldOwnerContext<PackageFragmentDescriptor>) {
MemberCodegen.genClassOrObject(packagePartContext, classOrObject, state, null)
}
@@ -212,8 +211,7 @@ class MultifileClassCodegen(
if (declaration is KtNamedFunction || declaration is KtProperty) {
val descriptor = state.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
assert(descriptor is CallableMemberDescriptor) { "Expected callable member, was " + descriptor + " for " + declaration.text }
if (!Visibilities.isPrivate((descriptor as CallableMemberDescriptor).visibility)
&& AsmUtil.getVisibilityAccessFlag(descriptor) != Opcodes.ACC_PRIVATE) {
if (!Visibilities.isPrivate((descriptor as CallableMemberDescriptor).visibility)) {
generateCallableMemberTasks.put(descriptor, { memberCodegen.genFunctionOrProperty(declaration) })
}
}
@@ -273,23 +271,28 @@ class MultifileClassCodegen(
if (state.classBuilderMode != ClassBuilderMode.FULL) return
if (files.any { it.isScript }) return
writeKotlinMetadata(classBuilder, KotlinClassHeader.Kind.MULTIFILE_CLASS) { av ->
val arv = av.visitArray(JvmAnnotationNames.METADATA_DATA_FIELD_NAME)
for (internalName in partFqNames.map(AsmUtil::internalNameByFqNameWithoutInnerClasses).sorted()) {
arv.visit(null, internalName)
}
arv.visitEnd()
val av = classBuilder.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS), true)
JvmCodegenUtil.writeAbiVersion(av)
JvmCodegenUtil.writeModuleName(av, state)
val partInternalNames = partFqNames.map { JvmClassName.byFqNameWithoutInnerClasses(it).internalName }.sorted()
val arv = av.visitArray(JvmAnnotationNames.FILE_PART_CLASS_NAMES_FIELD_NAME)
for (internalName in partInternalNames) {
arv.visit(null, internalName)
}
arv.visitEnd()
av.visitEnd()
}
private fun createCodegenForPartOfMultifileFacade(facadeContext: FieldOwnerContext<*>): MemberCodegen<KtFile> =
object : MemberCodegen<KtFile>(state, null, facadeContext, null, classBuilder) {
override fun generateDeclaration() = throw UnsupportedOperationException()
override fun generateBody() = throw UnsupportedOperationException()
override fun generateKotlinMetadataAnnotation() = throw UnsupportedOperationException()
override fun generateKotlinAnnotation() = throw UnsupportedOperationException()
}
fun done() {
public fun done() {
classBuilder.done()
}
@@ -309,7 +312,7 @@ class MultifileClassCodegen(
fragments.add(fragment)
}
}
if (fragments.size > 1) {
if (fragments.size() > 1) {
throw IllegalStateException("More than one package fragment, files: $files | fragments: $fragments")
}
return fragments.firstOrNull()

View File

@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtProperty
@@ -32,7 +31,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import java.util.*
class MultifileClassPartCodegen(
public class MultifileClassPartCodegen(
v: ClassBuilder,
file: KtFile,
private val filePartType: Type,
@@ -69,7 +68,7 @@ class MultifileClassPartCodegen(
}
}
override fun generateKotlinMetadataAnnotation() {
override fun generateKotlinAnnotation() {
val members = ArrayList<DeclarationDescriptor>()
for (declaration in element.declarations) {
when (declaration) {
@@ -84,13 +83,17 @@ class MultifileClassPartCodegen(
}
}
val serializer = DescriptorSerializer.createTopLevel(JvmSerializerExtension(v.serializationBindings, state))
val bindings = v.serializationBindings
val serializer = DescriptorSerializer.createTopLevel(
JvmSerializerExtension(bindings, state.typeMapper, state.useTypeTableInSerializer)
)
val packageProto = serializer.packagePartProto(members).build()
writeKotlinMetadata(v, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART) { av ->
AsmUtil.writeAnnotationData(av, serializer, packageProto)
av.visit(JvmAnnotationNames.METADATA_MULTIFILE_CLASS_NAME_FIELD_NAME, multifileClassType.internalName)
}
val av = v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS_PART), true)
AsmUtil.writeAnnotationData(av, serializer, packageProto)
av.visit(JvmAnnotationNames.MULTIFILE_CLASS_NAME_FIELD_NAME, multifileClassType.internalName)
av.visitEnd()
}
override fun generateSyntheticParts() {

View File

@@ -17,12 +17,11 @@
package org.jetbrains.kotlin.codegen;
import com.intellij.util.ArrayUtil;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.annotation.AnnotatedSimple;
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
@@ -31,7 +30,7 @@ import org.jetbrains.kotlin.descriptors.VariableDescriptor;
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl;
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
@@ -42,7 +41,9 @@ import org.jetbrains.org.objectweb.asm.Type;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses;
import static org.jetbrains.kotlin.codegen.AsmUtil.writeAnnotationData;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.writeModuleName;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class PackagePartCodegen extends MemberCodegen<KtFile> {
@@ -106,7 +107,7 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
}
@Override
protected void generateKotlinMetadataAnnotation() {
protected void generateKotlinAnnotation() {
List<DeclarationDescriptor> members = new ArrayList<DeclarationDescriptor>();
for (KtDeclaration declaration : element.getDeclarations()) {
if (declaration instanceof KtNamedFunction) {
@@ -118,17 +119,17 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
}
}
final DescriptorSerializer serializer =
DescriptorSerializer.createTopLevel(new JvmSerializerExtension(v.getSerializationBindings(), state));
final ProtoBuf.Package packageProto = serializer.packagePartProto(members).build();
JvmSerializationBindings bindings = v.getSerializationBindings();
WriteAnnotationUtilKt.writeKotlinMetadata(v, KotlinClassHeader.Kind.FILE_FACADE, new Function1<AnnotationVisitor, Unit>() {
@Override
public Unit invoke(AnnotationVisitor av) {
writeAnnotationData(av, serializer, packageProto);
return Unit.INSTANCE;
}
});
DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(new JvmSerializerExtension(
bindings, state.getTypeMapper(), state.getUseTypeTableInSerializer()
));
ProtoBuf.Package packageProto = serializer.packagePartProto(members).build();
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_FILE_FACADE), true);
writeAnnotationData(av, serializer, packageProto);
writeModuleName(av, state);
av.visitEnd();
}
@Override

View File

@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.codegen;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
@@ -55,22 +54,15 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.getDeprecatedAccessFlag;
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityForBackingField;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.FIELD_FOR_PROPERTY;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.K_PROPERTY_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class PropertyCodegen {
private static Logger LOG = Logger.getInstance(PropertyCodegen.class);
private final GenerationState state;
private final ClassBuilder v;
private final FunctionCodegen functionCodegen;
@@ -98,18 +90,14 @@ public class PropertyCodegen {
public void gen(@NotNull KtProperty property) {
VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, property);
if (!(variableDescriptor instanceof PropertyDescriptor)) {
String problem = "Property " + property.getName() + " should have a property descriptor: " + variableDescriptor;
LOG.error(problem, PsiUtilsKt.getElementTextWithContext(property));
throw new AssertionError(problem);
}
assert variableDescriptor instanceof PropertyDescriptor : "Property " + property.getText() + " should have a property descriptor: " + variableDescriptor;
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variableDescriptor;
gen(property, propertyDescriptor, property.getGetter(), property.getSetter());
}
public void generateInPackageFacade(@NotNull DeserializedPropertyDescriptor deserializedProperty) {
assert context instanceof MultifileClassFacadeContext : "should be called only for generating facade: " + context;
assert context instanceof DelegatingFacadeContext : "should be called only for generating facade: " + context;
gen(null, deserializedProperty, null, null);
}
@@ -122,7 +110,12 @@ public class PropertyCodegen {
assert kind == OwnerKind.PACKAGE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.DEFAULT_IMPLS
: "Generating property with a wrong kind (" + kind + "): " + descriptor;
if (isBackingFieldOwner(descriptor)) {
String implClassName = CodegenContextUtil.getImplementationClassShortName(context);
if (implClassName != null) {
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, descriptor, implClassName);
}
if (CodegenContextUtil.isImplClassOwner(context)) {
assert declaration != null : "Declaration is null for different context: " + context;
genBackingFieldAndAnnotations(declaration, descriptor, false);
@@ -136,27 +129,18 @@ public class PropertyCodegen {
}
}
private boolean isBackingFieldOwner(@NotNull PropertyDescriptor descriptor) {
if (descriptor.isConst()) {
return !(context instanceof MultifileClassPartContext);
}
return CodegenContextUtil.isImplClassOwner(context);
}
private void genBackingFieldAndAnnotations(@NotNull KtNamedDeclaration declaration, @NotNull PropertyDescriptor descriptor, boolean isParameter) {
boolean hasBackingField = hasBackingField(declaration, descriptor);
boolean hasDelegate = declaration instanceof KtProperty && ((KtProperty) declaration).hasDelegate();
AnnotationSplitter annotationSplitter =
AnnotationSplitter.create(LockBasedStorageManager.NO_LOCKS,
descriptor.getAnnotations(),
AnnotationSplitter.getTargetSet(isParameter, descriptor.isVar(), hasBackingField, hasDelegate));
AnnotationSplitter.getTargetSet(isParameter, descriptor.isVar(), hasBackingField));
Annotations fieldAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.FIELD);
Annotations delegateAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD);
Annotations propertyAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY);
generateBackingField(declaration, descriptor, fieldAnnotations, delegateAnnotations);
generateBackingField(declaration, descriptor, fieldAnnotations);
generateSyntheticMethodIfNeeded(descriptor, propertyAnnotations);
}
@@ -171,7 +155,7 @@ public class PropertyCodegen {
@NotNull PropertyDescriptor descriptor,
@Nullable KtPropertyAccessor accessor
) {
if (isConstOrHasJvmFieldAnnotation(descriptor)) return false;
if (hasJvmFieldAnnotation(descriptor)) return false;
boolean isDefaultAccessor = accessor == null || !accessor.hasBody();
@@ -245,18 +229,17 @@ public class PropertyCodegen {
private boolean generateBackingField(
@NotNull KtNamedDeclaration p,
@NotNull PropertyDescriptor descriptor,
@NotNull Annotations backingFieldAnnotations,
@NotNull Annotations delegateAnnotations
@NotNull Annotations annotations
) {
if (isJvmInterface(descriptor.getContainingDeclaration()) || kind == OwnerKind.DEFAULT_IMPLS) {
return false;
}
if (p instanceof KtProperty && ((KtProperty) p).hasDelegate()) {
generatePropertyDelegateAccess((KtProperty) p, descriptor, delegateAnnotations);
generatePropertyDelegateAccess((KtProperty) p, descriptor, annotations);
}
else if (Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor))) {
generateBackingFieldAccess(p, descriptor, backingFieldAnnotations);
generateBackingFieldAccess(p, descriptor, annotations);
}
else {
return false;
@@ -282,6 +265,10 @@ public class PropertyCodegen {
mv.visitInsn(Opcodes.RETURN);
mv.visitEnd();
}
else {
Type tImplType = typeMapper.mapDefaultImpls((ClassDescriptor) context.getContextDescriptor());
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, descriptor, shortNameByAsmType(tImplType));
}
if (kind != OwnerKind.DEFAULT_IMPLS) {
v.getSerializationBindings().put(SYNTHETIC_METHOD_FOR_PROPERTY, descriptor, new Method(name, desc));
@@ -320,17 +307,46 @@ public class PropertyCodegen {
ClassBuilder builder = v;
boolean hasJvmFieldAnnotation = hasJvmFieldAnnotation(propertyDescriptor);
FieldOwnerContext backingFieldContext = context;
boolean takeVisibilityFromDescriptor = propertyDescriptor.isLateInit() || propertyDescriptor.isConst();
if (AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor) ) {
modifiers |= ACC_STATIC;
if (JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
if (takeVisibilityFromDescriptor) {
modifiers |= getVisibilityAccessFlag(propertyDescriptor);
}
else if (hasJvmFieldAnnotation && !isDelegate) {
modifiers |= getDefaultVisibilityFlag(propertyDescriptor.getVisibility());
}
else {
modifiers |= getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegate);
}
if (AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
ImplementationBodyCodegen codegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
builder = codegen.v;
backingFieldContext = codegen.context;
v.getSerializationBindings().put(STATIC_FIELD_IN_OUTER_CLASS, propertyDescriptor);
}
if (isObject(propertyDescriptor.getContainingDeclaration()) &&
!hasJvmFieldAnnotation &&
!propertyDescriptor.isConst() &&
(modifiers & ACC_PRIVATE) == 0) {
modifiers |= ACC_DEPRECATED;
}
}
modifiers |= getVisibilityForBackingField(propertyDescriptor, isDelegate);
else if (takeVisibilityFromDescriptor) {
modifiers |= getVisibilityAccessFlag(propertyDescriptor);
}
else if (!isDelegate && hasJvmFieldAnnotation) {
modifiers |= getDefaultVisibilityFlag(propertyDescriptor.getVisibility());
}
else {
modifiers |= ACC_PRIVATE;
}
if (AsmUtil.isPropertyWithBackingFieldCopyInOuterClass(propertyDescriptor)) {
ImplementationBodyCodegen parentBodyCodegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
@@ -345,8 +361,7 @@ public class PropertyCodegen {
typeMapper.mapFieldSignature(jetType, propertyDescriptor), defaultValue);
Annotated fieldAnnotated = new AnnotatedWithFakeAnnotations(propertyDescriptor, annotations);
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(
fieldAnnotated, type, isDelegate ? AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD : AnnotationUseSiteTarget.FIELD);
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(fieldAnnotated, type, AnnotationUseSiteTarget.FIELD);
}
private void generatePropertyDelegateAccess(KtProperty p, PropertyDescriptor propertyDescriptor, Annotations annotations) {

View File

@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.codegen.AsmUtil.method
import org.jetbrains.kotlin.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation
import org.jetbrains.kotlin.codegen.context.ClassContext
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.*
@@ -27,30 +28,31 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.PropertyImportedFromObject
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.utils.sure
import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.commons.Method
class PropertyReferenceCodegen(
public class PropertyReferenceCodegen(
state: GenerationState,
parentCodegen: MemberCodegen<*>,
context: ClassContext,
expression: KtElement,
classBuilder: ClassBuilder,
resolvedCall: ResolvedCall<*>
private val classDescriptor: ClassDescriptor,
private val target: VariableDescriptor,
dispatchReceiver: ReceiverValue?
) : MemberCodegen<KtElement>(state, parentCodegen, context, expression, classBuilder) {
private val classDescriptor = context.contextDescriptor
private val asmType = typeMapper.mapClass(classDescriptor)
private val target = resolvedCall.resultingDescriptor as VariableDescriptor
private val dispatchReceiverType = resolvedCall.dispatchReceiver?.type
private val dispatchReceiverType = dispatchReceiver?.type
private val extensionReceiverType = target.extensionReceiverParameter?.type
private val receiverCount =
@@ -67,22 +69,26 @@ class PropertyReferenceCodegen(
element,
V1_6,
ACC_FINAL or ACC_SUPER or AsmUtil.getVisibilityAccessFlagForAnonymous(classDescriptor),
asmType.internalName,
asmType.getInternalName(),
null,
superAsmType.internalName,
superAsmType.getInternalName(),
emptyArray()
)
v.visitSource(element.containingFile.name, null)
v.visitSource(element.getContainingFile().getName(), null)
}
// TODO: ImplementationBodyCodegen.markLineNumberForSyntheticFunction?
override fun generateBody() {
generateConstInstance(asmType, wrapperMethod.returnType)
generateConstInstance(asmType, wrapperMethod.getReturnType()) { iv ->
if (!"true".equals(System.getProperty("kotlin.jvm.optimize.callable.references"), ignoreCase = true)) {
iv.invokestatic(REFLECTION, wrapperMethod.getName(), wrapperMethod.getDescriptor(), false)
}
}
generateMethod("property reference init", 0, method("<init>", Type.VOID_TYPE)) {
load(0, OBJECT_TYPE)
invokespecial(superAsmType.internalName, "<init>", "()V", false)
invokespecial(superAsmType.getInternalName(), "<init>", "()V", false)
}
generateMethod("property reference getOwner", ACC_PUBLIC, method("getOwner", K_DECLARATION_CONTAINER_TYPE)) {
@@ -90,7 +96,7 @@ class PropertyReferenceCodegen(
}
generateMethod("property reference getName", ACC_PUBLIC, method("getName", JAVA_STRING_TYPE)) {
aconst(target.name.asString())
aconst(target.getName().asString())
}
generateMethod("property reference getSignature", ACC_PUBLIC, method("getSignature", JAVA_STRING_TYPE)) {
@@ -107,11 +113,11 @@ class PropertyReferenceCodegen(
// return type and value parameter types. However, it's created only to be able to use
// ExpressionCodegen#intermediateValueForProperty, which is poorly coupled with everything else.
val fakeDescriptor = SimpleFunctionDescriptorImpl.create(
classDescriptor, Annotations.EMPTY, Name.identifier(method.name), CallableMemberDescriptor.Kind.DECLARATION,
classDescriptor, Annotations.EMPTY, Name.identifier(method.getName()), CallableMemberDescriptor.Kind.DECLARATION,
SourceElement.NO_SOURCE
)
fakeDescriptor.initialize(null, classDescriptor.thisAsReceiverParameter, emptyList(), emptyList(),
classDescriptor.builtIns.anyType, Modality.OPEN, Visibilities.PUBLIC)
fakeDescriptor.initialize(null, classDescriptor.getThisAsReceiverParameter(), emptyList(), emptyList(),
classDescriptor.builtIns.getAnyType(), Modality.OPEN, Visibilities.PUBLIC)
val fakeCodegen = ExpressionCodegen(
this, FrameMap(), OBJECT_TYPE, context.intoFunction(fakeDescriptor), state, this@PropertyReferenceCodegen
@@ -146,24 +152,24 @@ class PropertyReferenceCodegen(
}
private fun generateMethod(debugString: String, access: Int, method: Method, generate: InstructionAdapter.() -> Unit) {
val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, method.name, method.descriptor, null, null)
val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, method.getName(), method.getDescriptor(), null, null)
if (state.classBuilderMode == ClassBuilderMode.FULL) {
val iv = InstructionAdapter(mv)
iv.visitCode()
iv.generate()
iv.areturn(method.returnType)
iv.areturn(method.getReturnType())
FunctionCodegen.endVisit(mv, debugString, element)
}
}
override fun generateKotlinMetadataAnnotation() {
writeSyntheticClassMetadata(v)
override fun generateKotlinAnnotation() {
writeKotlinSyntheticClassAnnotation(v, state)
}
fun putInstanceOnStack(): StackValue =
StackValue.operation(wrapperMethod.returnType) { iv ->
iv.getstatic(asmType.internalName, JvmAbi.INSTANCE_FIELD, wrapperMethod.returnType.descriptor)
public fun putInstanceOnStack(): StackValue =
StackValue.operation(wrapperMethod.getReturnType()) { iv ->
iv.getstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, wrapperMethod.getReturnType().getDescriptor())
}
companion object {

View File

@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.types.KotlinType;
import java.util.List;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.RANGES_PACKAGE_FQ_NAME;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME;
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitiveNumberClassDescriptor;
public class RangeCodegenUtil {
@@ -53,8 +53,8 @@ public class RangeCodegenUtil {
ImmutableMap.Builder<FqName, PrimitiveType> rangeBuilder = ImmutableMap.builder();
ImmutableMap.Builder<FqName, PrimitiveType> progressionBuilder = ImmutableMap.builder();
for (PrimitiveType primitiveType : supportedRangeTypes()) {
FqName rangeClassFqName = RANGES_PACKAGE_FQ_NAME.child(Name.identifier(primitiveType.getTypeName() + "Range"));
FqName progressionClassFqName = RANGES_PACKAGE_FQ_NAME.child(Name.identifier(primitiveType.getTypeName() + "Progression"));
FqName rangeClassFqName = BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier(primitiveType.getTypeName() + "Range"));
FqName progressionClassFqName = BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier(primitiveType.getTypeName() + "Progression"));
rangeBuilder.put(rangeClassFqName, primitiveType);
progressionBuilder.put(progressionClassFqName, primitiveType);
}

View File

@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.util.OperatorNameConventions;
@@ -40,8 +39,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.Collections;
import static org.jetbrains.kotlin.codegen.AsmUtil.NO_FLAG_PACKAGE_PRIVATE;
import static org.jetbrains.kotlin.codegen.AsmUtil.asmTypeByFqNameWithoutInnerClasses;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -96,7 +94,7 @@ public class SamWrapperCodegen {
);
cv.visitSource(file.getName(), null);
WriteAnnotationUtilKt.writeSyntheticClassMetadata(cv);
writeKotlinSyntheticClassAnnotation(cv, state);
// e.g. ASM type for Function2
Type functionAsmType = typeMapper.mapType(functionType);
@@ -166,7 +164,7 @@ public class SamWrapperCodegen {
originalInterfaceErased.getValueParameters(), originalInterfaceErased.getReturnType(),
Modality.OPEN, originalInterfaceErased.getVisibility());
DescriptorUtilsKt.setSingleOverridden(descriptorForBridges, originalInterfaceErased);
descriptorForBridges.addOverriddenDescriptor(originalInterfaceErased);
codegen.generateBridges(descriptorForBridges);
}

View File

@@ -104,7 +104,7 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
}
@Override
protected void generateKotlinMetadataAnnotation() {
protected void generateKotlinAnnotation() {
// TODO
}

View File

@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.RawSignature
import org.jetbrains.org.objectweb.asm.FieldVisitor
import org.jetbrains.org.objectweb.asm.MethodVisitor
abstract class SignatureCollectingClassBuilderFactory(
public abstract class SignatureCollectingClassBuilderFactory(
delegate: ClassBuilderFactory
) : DelegatingClassBuilderFactory(delegate) {
@@ -67,7 +67,7 @@ abstract class SignatureCollectingClassBuilderFactory(
override fun done() {
for ((signature, elementsAndDescriptors) in signatures.entrySet()) {
if (elementsAndDescriptors.size == 1) continue // no clash
if (elementsAndDescriptors.size() == 1) continue // no clash
handleClashingSignatures(ConflictingJvmDeclarationsData(
classInternalName,
classCreatedFor,

View File

@@ -22,19 +22,19 @@ import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedFunction
data class SourceInfo(val source: String, val pathOrCleanFQN: String, val linesInFile: Int) {
data public class SourceInfo(val source: String, val pathOrCleanFQN: String, val linesInFile: Int) {
companion object {
fun createInfo(element: KtElement?, internalClassName: String): SourceInfo {
assert(element != null) { "Couldn't create source mapper for null element " + internalClassName }
val lineNumbers = CodegenUtil.getLineNumberForElement(element!!.containingFile, true)
assert(lineNumbers != null) { "Couldn't extract line count in " + element.containingFile }
val lineNumbers = CodegenUtil.getLineNumberForElement(element!!.getContainingFile(), true)
assert(lineNumbers != null) { "Couldn't extract line count in " + element.getContainingFile() }
//TODO hack condition for package parts cleaning
val isTopLevel = element is KtFile || (element is KtNamedFunction && element.getParent() is KtFile)
val cleanedClassFqName = if (!isTopLevel) internalClassName else internalClassName.substringBefore('$')
return SourceInfo(element.getContainingKtFile().name, cleanedClassFqName, lineNumbers!!)
return SourceInfo(element.getContainingKtFile().getName(), cleanedClassFqName, lineNumbers!!)
}
}

View File

@@ -17,9 +17,8 @@
package org.jetbrains.kotlin.codegen;
import com.intellij.psi.tree.IElementType;
import kotlin.ArraysKt;
import kotlin.Unit;
import kotlin.collections.ArraysKt;
import kotlin.collections.CollectionsKt;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
@@ -516,9 +515,6 @@ public abstract class StackValue {
dispatchReceiverParameter = extensionReceiverParameter;
extensionReceiverParameter = null;
}
else if (descriptor instanceof SyntheticFieldDescriptor) {
dispatchReceiverParameter = ((SyntheticFieldDescriptor) descriptor).getDispatchReceiverParameterForBackend();
}
boolean hasExtensionReceiver = callExtensionReceiver != null;
StackValue dispatchReceiver = platformStaticCallIfPresent(
@@ -603,7 +599,11 @@ public abstract class StackValue {
}
public static Field singletonViaInstance(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
return field(FieldInfo.createSingletonViaInstance(classDescriptor, typeMapper), none());
return field(FieldInfo.createSingletonViaInstance(classDescriptor, typeMapper, false), none());
}
public static Field oldSingleton(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
return field(FieldInfo.createForSingleton(classDescriptor, typeMapper, true), none());
}
public static StackValue operation(Type type, Function1<InstructionAdapter, Unit> lambda) {
@@ -772,14 +772,13 @@ public abstract class StackValue {
private final Callable callable;
private final boolean isGetter;
private final ExpressionCodegen codegen;
private final ArgumentGenerator argumentGenerator;
private final List<ResolvedValueArgument> valueArguments;
private final FrameMap frame;
private final StackValue receiver;
private final ResolvedCall<FunctionDescriptor> resolvedGetCall;
private final ResolvedCall<FunctionDescriptor> resolvedSetCall;
private DefaultCallArgs defaultArgs;
private CallGenerator callGenerator;
boolean isComplexOperationWithDup;
private DefaultCallMask mask;
public CollectionElementReceiver(
@NotNull Callable callable,
@@ -788,6 +787,7 @@ public abstract class StackValue {
ResolvedCall<FunctionDescriptor> resolvedSetCall,
boolean isGetter,
@NotNull ExpressionCodegen codegen,
ArgumentGenerator argumentGenerator,
List<ResolvedValueArgument> valueArguments
) {
super(OBJECT_TYPE);
@@ -797,6 +797,7 @@ public abstract class StackValue {
this.receiver = receiver;
this.resolvedGetCall = resolvedGetCall;
this.resolvedSetCall = resolvedSetCall;
this.argumentGenerator = argumentGenerator;
this.valueArguments = valueArguments;
this.codegen = codegen;
this.frame = codegen.myFrameMap;
@@ -806,25 +807,8 @@ public abstract class StackValue {
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
ResolvedCall<?> call = isGetter ? resolvedGetCall : resolvedSetCall;
StackValue newReceiver = StackValue.receiver(call, receiver, codegen, callable);
ArgumentGenerator generator = createArgumentGenerator();
newReceiver.put(newReceiver.type, v);
callGenerator.putHiddenParams();
defaultArgs = generator.generate(valueArguments, valueArguments);
}
private ArgumentGenerator createArgumentGenerator() {
assert callGenerator == null :
"'putSelector' and 'createArgumentGenerator' methods should be called once for CollectionElementReceiver: " + callable;
ResolvedCall<FunctionDescriptor> resolvedCall = isGetter ? resolvedGetCall : resolvedSetCall;
assert resolvedCall != null : "Resolved call should be non-null: " + callable;
callGenerator =
!isComplexOperationWithDup ? codegen.getOrCreateCallGenerator(resolvedCall) : codegen.defaultCallGenerator;
return new CallBasedArgumentGenerator(
codegen,
callGenerator,
resolvedCall.getResultingDescriptor().getValueParameters(), callable.getValueParameterTypes()
);
mask = argumentGenerator.generate(valueArguments, valueArguments);
}
@Override
@@ -952,22 +936,14 @@ public abstract class StackValue {
if (getter == null) {
throw new UnsupportedOperationException("no getter specified");
}
CallGenerator callGenerator = getCallGenerator();
CallGenerator callGenerator = codegen.defaultCallGenerator;
callGenerator.genCall(getter, resolvedGetCall, genDefaultMaskIfPresent(callGenerator), codegen);
coerceTo(type, v);
}
private boolean genDefaultMaskIfPresent(CallGenerator callGenerator) {
DefaultCallArgs defaultArgs = ((CollectionElementReceiver) receiver).defaultArgs;
return defaultArgs.generateOnStackIfNeeded(callGenerator, true);
}
private CallGenerator getCallGenerator() {
CallGenerator generator = ((CollectionElementReceiver) receiver).callGenerator;
assert generator != null :
"CollectionElementReceiver should be putted on stack before CollectionElement:" +
" getCall = " + resolvedGetCall + ", setCall = " + resolvedSetCall;
return generator;
DefaultCallMask mask = ((CollectionElementReceiver) receiver).mask;
return mask.generateOnStackIfNeeded(callGenerator);
}
@Override
@@ -1019,13 +995,8 @@ public abstract class StackValue {
Type lastParameterType = ArraysKt.last(setter.getParameterTypes());
coerce(topOfStackType, lastParameterType, v);
getCallGenerator().afterParameterPut(lastParameterType, StackValue.onStack(lastParameterType),
CollectionsKt.getLastIndex(setter.getValueParameterTypes()));
//Convention setter couldn't have default parameters, just getter can have it at last positions
//*Convention setter couldn't have default parameters, just getter can have it at last positions
//We should remove default parameters of getter from stack*/
//Note that it works only for non-inline case
CollectionElementReceiver collectionElementReceiver = (CollectionElementReceiver) receiver;
if (collectionElementReceiver.isGetter) {
List<ResolvedValueArgument> arguments = collectionElementReceiver.valueArguments;
@@ -1040,7 +1011,7 @@ public abstract class StackValue {
}
}
getCallGenerator().genCall(setter, resolvedSetCall, false, codegen);
codegen.defaultCallGenerator.genCall(setter, resolvedSetCall, false, codegen);
Type returnType = setter.getReturnType();
if (returnType != Type.VOID_TYPE) {
pop(v, returnType);
@@ -1171,11 +1142,6 @@ public abstract class StackValue {
else {
coerce(topOfStackType, ArraysKt.last(setter.getParameterTypes()), v);
setter.genInvokeInstruction(v);
Type returnType = setter.getReturnType();
if (returnType != Type.VOID_TYPE) {
pop(v, returnType);
}
}
}
@@ -1567,11 +1533,6 @@ public abstract class StackValue {
super(value.type, value.receiver.canHaveSideEffects());
this.originalValueWithReceiver = value;
this.isReadOperations = isReadOperations;
if (value instanceof CollectionElement) {
if (value.receiver instanceof CollectionElementReceiver) {
((CollectionElementReceiver) value.receiver).isComplexOperationWithDup = true;
}
}
}
@Override

View File

@@ -44,7 +44,7 @@ class CoercionValue(
}
class StackValueWithLeaveTask(
public class StackValueWithLeaveTask(
val stackValue: StackValue,
val leaveTasks: (StackValue) -> Unit
) : StackValue(stackValue.type) {

View File

@@ -22,15 +22,15 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.FqName
interface WrappedAnnotated : Annotated {
val originalAnnotated: Annotated
public interface WrappedAnnotated : Annotated {
public val originalAnnotated: Annotated
}
class AnnotatedWithFakeAnnotations(override val originalAnnotated: Annotated, private val actual: Annotations) : WrappedAnnotated {
public class AnnotatedWithFakeAnnotations(override val originalAnnotated: Annotated, private val actual: Annotations) : WrappedAnnotated {
override fun getAnnotations() = actual
}
class AnnotatedWithOnlyTargetedAnnotations(private val original: Annotated) : Annotated {
public class AnnotatedWithOnlyTargetedAnnotations(private val original: Annotated) : Annotated {
private val annotations: Annotations = UseSiteTargetedAnnotations(original.annotations)
override fun getAnnotations() = annotations
@@ -52,4 +52,4 @@ class AnnotatedWithOnlyTargetedAnnotations(private val original: Annotated) : An
}
}
class AnnotatedSimple(annotations: Annotations) : AnnotatedImpl(annotations)
public class AnnotatedSimple(annotations: Annotations) : AnnotatedImpl(annotations)

View File

@@ -32,18 +32,19 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.callUtil.getParentCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeAsSequence
import org.jetbrains.kotlin.resolve.descriptorUtil.firstOverridden
import org.jetbrains.kotlin.utils.singletonOrEmptyList
import java.util.*
class BridgeForBuiltinSpecial<Signature : Any>(
class BridgeForBuiltinSpecial<Signature>(
val from: Signature, val to: Signature,
val isSpecial: Boolean = false,
val isDelegateToSuper: Boolean = false
)
object BuiltinSpecialBridgesUtil {
@JvmStatic fun <Signature : Any> generateBridgesForBuiltinSpecial(
@JvmStatic
public fun <Signature> generateBridgesForBuiltinSpecial(
function: FunctionDescriptor,
signatureByDescriptor: (FunctionDescriptor) -> Signature
): Set<BridgeForBuiltinSpecial<Signature>> {
@@ -57,39 +58,33 @@ object BuiltinSpecialBridgesUtil {
// e.g. `getSize()I`
val methodItself = signatureByDescriptor(function)
// e.g. `size()I`
val specialBridgeSignature = signatureByDescriptor(overriddenBuiltin)
val overriddenBuiltinSignature = signatureByDescriptor(overriddenBuiltin)
val specialBridgeExists = function.getSpecialBridgeSignatureIfExists(signatureByDescriptor) != null
val specialBridgesSignaturesInSuperClass = function.overriddenTreeAsSequence(useOriginal = true).mapNotNull {
if (it === function) return@mapNotNull null
it.getSpecialBridgeSignatureIfExists(signatureByDescriptor)
}
val isTherePossibleClashWithSpecialBridge =
specialBridgeSignature in specialBridgesSignaturesInSuperClass
|| reachableDeclarations.any { it.modality == Modality.FINAL && signatureByDescriptor(it) == specialBridgeSignature }
val needGenerateSpecialBridge = needGenerateSpecialBridge(
function, reachableDeclarations, overriddenBuiltin, signatureByDescriptor, overriddenBuiltinSignature)
val specialBridge = if (specialBridgeExists && !isTherePossibleClashWithSpecialBridge)
BridgeForBuiltinSpecial(specialBridgeSignature, methodItself, isSpecial = true)
val specialBridge = if (needGenerateSpecialBridge)
BridgeForBuiltinSpecial(overriddenBuiltinSignature, methodItself, isSpecial = true)
else null
val commonBridges = reachableDeclarations.mapTo(LinkedHashSet<Signature>(), signatureByDescriptor)
commonBridges.removeAll(specialBridgesSignaturesInSuperClass + specialBridge?.from.singletonOrEmptyList())
val bridgesToGenerate = reachableDeclarations.mapTo(LinkedHashSet<Signature>(), signatureByDescriptor)
bridgesToGenerate.remove(overriddenBuiltinSignature)
val superImplementationDescriptor = findSuperImplementationForStubDelegation(function, fake)
if (superImplementationDescriptor != null || !fake || functionHandle.isAbstract) {
commonBridges.remove(methodItself)
if (superImplementationDescriptor != null || !fake) {
bridgesToGenerate.remove(methodItself)
}
if (fake) {
for (overridden in function.overriddenDescriptors.map { it.original }) {
if (!DescriptorBasedFunctionHandle(overridden).isAbstract) {
commonBridges.removeAll(findAllReachableDeclarations(overridden).map(signatureByDescriptor))
bridgesToGenerate.removeAll(findAllReachableDeclarations(overridden).map(signatureByDescriptor))
}
}
}
val bridges: MutableSet<BridgeForBuiltinSpecial<Signature>> =
(commonBridges.map { BridgeForBuiltinSpecial(it, specialBridgeSignature) } + specialBridge.singletonOrEmptyList()).toMutableSet()
(bridgesToGenerate.map { BridgeForBuiltinSpecial(it, overriddenBuiltinSignature) } + specialBridge.singletonOrEmptyList()).toMutableSet()
if (superImplementationDescriptor != null) {
bridges.add(BridgeForBuiltinSpecial(methodItself, signatureByDescriptor(superImplementationDescriptor), isDelegateToSuper = true))
@@ -98,7 +93,8 @@ object BuiltinSpecialBridgesUtil {
return bridges
}
@JvmStatic fun <Signature : Any> FunctionDescriptor.shouldHaveTypeSafeBarrier(
@JvmStatic
public fun <Signature> FunctionDescriptor.shouldHaveTypeSafeBarrier(
signatureByDescriptor: (FunctionDescriptor) -> Signature
): Boolean {
if (BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(this) == null) return false
@@ -120,27 +116,34 @@ private fun findSuperImplementationForStubDelegation(function: FunctionDescripto
private fun findAllReachableDeclarations(functionDescriptor: FunctionDescriptor): MutableSet<FunctionDescriptor> =
findAllReachableDeclarations(DescriptorBasedFunctionHandle(functionDescriptor)).map { it.descriptor }.toMutableSet()
private fun <Signature> CallableMemberDescriptor.getSpecialBridgeSignatureIfExists(
signatureByDescriptor: (FunctionDescriptor) -> Signature
): Signature? {
// Ignore itself and non-functions (may be assertion)
if (this !is FunctionDescriptor) return null
private fun <Signature> needGenerateSpecialBridge(
functionDescriptor: FunctionDescriptor,
reachableDeclarations: Collection<FunctionDescriptor>,
specialCallableDescriptor: CallableMemberDescriptor,
signatureByDescriptor: (FunctionDescriptor) -> Signature,
overriddenBuiltinSignature: Signature
): Boolean {
if (signatureByDescriptor(functionDescriptor) == overriddenBuiltinSignature) return false
if (specialCallableDescriptor.modality == Modality.FINAL) return false
// Only Kotlin classes can have special bridges
if (containingDeclaration is JavaClassDescriptor || DescriptorUtils.isInterface(containingDeclaration)) return null
// Is there Kotlin superclass that already has generated special bridge
if (functionDescriptor.firstOverridden { overridden ->
val originalOverridden = overridden.original
if (overridden === functionDescriptor
|| originalOverridden !is FunctionDescriptor
|| originalOverridden.containingDeclaration is JavaClassDescriptor
|| DescriptorUtils.isInterface(originalOverridden.containingDeclaration)) return@firstOverridden false
// Getting original is necessary here, because we want to determine JVM signature of descriptor as it was declared in containing class
val originalOverridden = original
val overriddenSpecial = originalOverridden.getOverriddenBuiltinReflectingJvmDescriptor() ?: return null
val specialBridgeSignature = signatureByDescriptor(overriddenSpecial)
val overriddenSpecial = originalOverridden.getOverriddenBuiltinReflectingJvmDescriptor()?.original ?: return@firstOverridden false
// Does special bridge has different signature
if (signatureByDescriptor(originalOverridden) == specialBridgeSignature) return null
signatureByDescriptor(originalOverridden) != signatureByDescriptor(overriddenSpecial)
} != null) return false
return specialBridgeSignature
return reachableDeclarations.none { it.modality == Modality.FINAL
&& signatureByDescriptor(it) == overriddenBuiltinSignature }
}
fun isValueArgumentForCallToMethodWithTypeCheckBarrier(
public fun isValueArgumentForCallToMethodWithTypeCheckBarrier(
element: KtElement,
bindingContext: BindingContext
): Boolean {

View File

@@ -47,7 +47,7 @@ private fun List<PackageParts>.addCompiledParts(state: GenerationState): List<Pa
mapping.findPackageParts(qualifier)?.run { parts.remove(name) }
}
return (this + mapping.packageFqName2Parts.values)
return (this + mapping.packageFqName2Parts.values())
.groupBy { it.packageFqName }
.map {
val (packageFqName, packageParts) = it

View File

@@ -18,28 +18,24 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
fun generateIsCheck(
v: InstructionAdapter,
kotlinType: KotlinType,
asmType: Type
isNullable: Boolean,
generateInstanceOfInstruction: (InstructionAdapter) -> Unit
) {
if (TypeUtils.isNullableType(kotlinType)) {
if (isNullable) {
val nope = Label()
val end = Label()
@@ -48,8 +44,7 @@ fun generateIsCheck(
ifnull(nope)
TypeIntrinsics.instanceOf(this, kotlinType, asmType)
generateInstanceOfInstruction(this)
goTo(end)
mark(nope)
@@ -60,37 +55,11 @@ fun generateIsCheck(
}
}
else {
TypeIntrinsics.instanceOf(v, kotlinType, asmType)
generateInstanceOfInstruction(v)
}
}
fun generateAsCast(
v: InstructionAdapter,
kotlinType: KotlinType,
asmType: Type,
isSafe: Boolean
) {
if (!isSafe) {
if (!TypeUtils.isNullableType(kotlinType)) {
generateNullCheckForNonSafeAs(v, kotlinType)
}
}
else {
with(v) {
dup()
TypeIntrinsics.instanceOf(v, kotlinType, asmType)
val ok = Label()
ifne(ok)
pop()
aconst(null)
mark(ok)
}
}
TypeIntrinsics.checkcast(v, kotlinType, asmType, isSafe)
}
private fun generateNullCheckForNonSafeAs(
fun generateNullCheckForNonSafeAs(
v: InstructionAdapter,
type: KotlinType
) {
@@ -103,7 +72,7 @@ private fun generateNullCheckForNonSafeAs(
}
}
fun SpecialSignatureInfo.replaceValueParametersIn(sourceSignature: String?): String?
public fun SpecialSignatureInfo.replaceValueParametersIn(sourceSignature: String?): String?
= valueParametersSignature?.let { sourceSignature?.replace("^\\(.*\\)".toRegex(), "($it)") }
fun populateCompanionBackingFieldNamesToOuterContextIfNeeded(companion: KtObjectDeclaration, outerContext: FieldOwnerContext<*>, state: GenerationState) {
@@ -113,7 +82,7 @@ fun populateCompanionBackingFieldNamesToOuterContextIfNeeded(companion: KtObject
return
}
if (!JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
if (!AsmUtil.isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
return
}
val properties = companion.declarations.filterIsInstance<KtProperty>()

View File

@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.load.java.JavaVisibilities;
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
import org.jetbrains.kotlin.storage.NullableLazyValue;
import org.jetbrains.kotlin.types.KotlinType;
@@ -610,8 +609,6 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
boolean withinInline,
boolean isSuperCall
) {
if (AnnotationUtilKt.isInlineOnly(unwrappedDescriptor)) return false;
return isSuperCall && withinInline ||
(accessFlag & ACC_PRIVATE) != 0 ||
((accessFlag & ACC_PROTECTED) != 0 &&

View File

@@ -16,16 +16,24 @@
package org.jetbrains.kotlin.codegen.context
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.org.objectweb.asm.Type
object CodegenContextUtil {
@JvmStatic fun getImplementationOwnerClassType(owner: CodegenContext<*>): Type? =
public object CodegenContextUtil {
@JvmStatic
public fun getImplementationOwnerClassType(owner: CodegenContext<*>): Type? =
when (owner) {
is MultifileClassFacadeContext -> owner.filePartType
is DelegatingFacadeContext -> owner.delegateToClassType
is DelegatingToPartContext -> owner.implementationOwnerClassType
else -> null
}
@JvmStatic fun isImplClassOwner(owner: CodegenContext<*>): Boolean =
owner !is MultifileClassFacadeContext
}
@JvmStatic
public fun getImplementationClassShortName(owner: CodegenContext<*>): String? =
getImplementationOwnerClassType(owner)?.let { AsmUtil.shortNameByAsmType(it) }
@JvmStatic
public fun isImplClassOwner(owner: CodegenContext<*>): Boolean =
owner !is DelegatingFacadeContext
}

View File

@@ -38,7 +38,7 @@ class DefaultImplsClassContext(
override fun getAccessors(): Collection<AccessorForCallableDescriptor<*>> {
val accessors = super.getAccessors()
val alreadyExistKeys = accessors.map ({ Pair(it.calleeDescriptor, it.superCallTarget) })
val filtered = interfaceContext.accessors.associateByTo(linkedMapOf()) { Pair(it.calleeDescriptor, it.superCallTarget) }.apply { keys -= alreadyExistKeys }
val filtered = interfaceContext.accessors.toMap ({ Pair(it.calleeDescriptor, it.superCallTarget) }, {it}) - alreadyExistKeys
return accessors + filtered.values
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2015 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.
@@ -14,12 +14,12 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.android
package org.jetbrains.kotlin.codegen.context;
import com.intellij.psi.PsiElement
import org.jetbrains.android.facet.AndroidFacet
import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.Type;
fun PsiElement.getAndroidFacetForFile(): AndroidFacet? {
val file = containingFile ?: return null
return AndroidFacet.getInstance(file)
}
public interface DelegatingFacadeContext {
@Nullable
Type getDelegateToClassType();
}

View File

@@ -16,10 +16,11 @@
package org.jetbrains.kotlin.codegen.context;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.org.objectweb.asm.Type;
public class MultifileClassFacadeContext extends MultifileClassContextBase {
public class MultifileClassFacadeContext extends MultifileClassContextBase implements DelegatingFacadeContext {
public MultifileClassFacadeContext(
PackageFragmentDescriptor descriptor,
CodegenContext parent,
@@ -28,4 +29,10 @@ public class MultifileClassFacadeContext extends MultifileClassContextBase {
) {
super(descriptor, parent, multifileClassType, filePartType);
}
@Nullable
@Override
public Type getDelegateToClassType() {
return getFilePartType();
}
}

View File

@@ -25,7 +25,7 @@ import org.jetbrains.org.objectweb.asm.Type;
public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor> implements DelegatingToPartContext, FacadePartWithSourceFile {
private final Type packagePartType;
private final KtFile sourceFile;
@Nullable private KtFile sourceFile;
public PackageContext(
@NotNull PackageFragmentDescriptor contextDescriptor,

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2010-2015 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 org.jetbrains.kotlin.codegen.context;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.org.objectweb.asm.Type;
public class PackageFacadeContext extends PackageContext implements DelegatingFacadeContext {
private final Type publicFacadeType;
public PackageFacadeContext(
@NotNull PackageFragmentDescriptor contextDescriptor,
@NotNull CodegenContext parent,
@NotNull Type packagePartType
) {
this(contextDescriptor, parent, packagePartType, packagePartType);
}
public PackageFacadeContext(
@NotNull PackageFragmentDescriptor contextDescriptor,
@NotNull CodegenContext parent,
@NotNull Type packagePartType,
@NotNull Type publicFacadeType
) {
super(contextDescriptor, parent, packagePartType, null);
this.publicFacadeType = publicFacadeType;
}
@Override
@Nullable
public Type getDelegateToClassType() {
return getPackagePartType();
}
public Type getPublicFacadeType() {
return publicFacadeType;
}
}

View File

@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.codegen.context;
import kotlin.collections.CollectionsKt;
import kotlin.CollectionsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.FieldInfo;

View File

@@ -21,11 +21,11 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
import org.jetbrains.kotlin.resolve.BindingContext
interface ClassBuilderInterceptorExtension {
public interface ClassBuilderInterceptorExtension {
companion object : ProjectExtensionDescriptor<ClassBuilderInterceptorExtension>(
"org.jetbrains.kotlin.classBuilderFactoryInterceptorExtension", ClassBuilderInterceptorExtension::class.java)
fun interceptClassBuilderFactory(
public fun interceptClassBuilderFactory(
interceptedFactory: ClassBuilderFactory,
bindingContext: BindingContext,
diagnostics: DiagnosticSink

View File

@@ -26,28 +26,28 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.descriptors.*
interface ExpressionCodegenExtension {
public interface ExpressionCodegenExtension {
companion object : ProjectExtensionDescriptor<ExpressionCodegenExtension>(
"org.jetbrains.kotlin.expressionCodegenExtension", ExpressionCodegenExtension::class.java)
class Context(
val typeMapper: JetTypeMapper,
val v: InstructionAdapter
public class Context(
public val typeMapper: JetTypeMapper,
public val v: InstructionAdapter
)
/**
* Used for generating custom byte code for the property value obtain. This function has lazy semantics.
* Returns new stack value.
*/
fun applyProperty(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null
public fun applyProperty(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null
/**
* Used for generating custom byte code for the function call. This function has lazy semantics.
* Returns new stack value.
*/
fun applyFunction(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null
public fun applyFunction(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null
fun generateClassSyntheticParts(
public fun generateClassSyntheticParts(
classBuilder: ClassBuilder,
state: GenerationState,
classOrObject: KtClassOrObject,

View File

@@ -88,15 +88,34 @@ public class AnonymousObjectTransformer {
reader.accept(new ClassVisitor(InlineCodegenUtil.API, classBuilder.getVisitor()) {
@Override
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
InlineCodegenUtil.assertVersionNotGreaterThanJava6(version, name);
if (signature != null) {
ReifiedTypeInliner.SignatureReificationResult signatureResult = inliningContext.reifedTypeInliner.reifySignature(signature);
signature = signatureResult.getNewSignature();
transformationResult.getReifiedTypeParametersUsages().mergeAll(signatureResult.getTypeParametersUsages());
}
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public void visitInnerClass(@NotNull String name, String outerName, String innerName, int access) {
public void visitInnerClass(String name, String outerName, String innerName, int access) {
innerClassNodes.add(new InnerClassNode(name, outerName, innerName, access));
}
@Override
public void visitOuterClass(@NotNull String owner, String name, String desc) {
InliningContext parent = inliningContext.getParent();
assert parent != null : "Context for transformer should have parent one: " + inliningContext;
//we don't write owner info for lamdbas and SAMs just only for objects
if (parent.isRoot() || parent.isInliningLambdaRootContext()) {
//TODO: think about writing method info - there is some problem with new constructor desc calculation
super.visitOuterClass(inliningContext.getParent().getClassNameToInline(), null, null);
return;
}
super.visitOuterClass(owner, name, desc);
}
@Override
public MethodVisitor visitMethod(
int access, @NotNull String name, @NotNull String desc, String signature, String[] exceptions
@@ -143,7 +162,7 @@ public class AnonymousObjectTransformer {
}
else {
//seems we can't do any clever mapping cause we don't know any about original class name
sourceMapper = IdenticalSourceMapper.INSTANCE;
sourceMapper = IdenticalSourceMapper.INSTANCE$;
}
if (sourceInfo != null && !InlineCodegenUtil.GENERATE_SMAP) {
classBuilder.visitSource(sourceInfo, debugInfo);
@@ -153,7 +172,7 @@ public class AnonymousObjectTransformer {
if (sourceInfo != null) {
classBuilder.visitSource(sourceInfo, debugInfo);
}
sourceMapper = IdenticalSourceMapper.INSTANCE;
sourceMapper = IdenticalSourceMapper.INSTANCE$;
}
ParametersBuilder allCapturedParamBuilder = ParametersBuilder.newBuilder();
@@ -161,7 +180,7 @@ public class AnonymousObjectTransformer {
List<CapturedParamInfo> additionalFakeParams =
extractParametersMappingAndPatchConstructor(constructor, allCapturedParamBuilder, constructorParamBuilder,
anonymousObjectGen, parentRemapper);
List<MethodVisitor> deferringMethods = new ArrayList<MethodVisitor>();
List<MethodVisitor> deferringMethods = new ArrayList();
for (MethodNode next : methodsToTransform) {
MethodVisitor deferringVisitor = newMethod(classBuilder, next);
@@ -187,24 +206,16 @@ public class AnonymousObjectTransformer {
SourceMapper.Companion.flushToClassBuilder(sourceMapper, classBuilder);
ClassVisitor visitor = classBuilder.getVisitor();
for (InnerClassNode node : innerClassNodes) {
visitor.visitInnerClass(node.name, node.outerName, node.innerName, node.access);
classBuilder.getVisitor().visitInnerClass(node.name, node.outerName, node.innerName, node.access);
}
writeOuterInfo(visitor);
classBuilder.done();
anonymousObjectGen.setNewLambdaType(newLambdaType);
return transformationResult;
}
private void writeOuterInfo(@NotNull ClassVisitor visitor) {
InlineCallSiteInfo info = inliningContext.getCallSiteInfo();
visitor.visitOuterClass(info.getOwnerClassName(), info.getFunctionName(), info.getFunctionDesc());
}
@NotNull
private InlineResult inlineMethodAndUpdateGlobalResult(
@NotNull AnonymousObjectGeneration anonymousObjectGen,
@@ -237,20 +248,9 @@ public class AnonymousObjectTransformer {
parameters, anonymousObjectGen.getCapturedLambdasToInline(),
parentRemapper, isConstructor);
MethodInliner inliner =
new MethodInliner(
sourceNode,
parameters,
inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
remapper,
isSameModule,
"Transformer for " + anonymousObjectGen.getOwnerInternalName(),
sourceMapper,
new InlineCallSiteInfo(
anonymousObjectGen.getOwnerInternalName(),
sourceNode.name,
isConstructor ? anonymousObjectGen.getNewConstructorDescriptor() : sourceNode.desc)
);
MethodInliner inliner = new MethodInliner(sourceNode, parameters, inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
remapper, isSameModule, "Transformer for " + anonymousObjectGen.getOwnerInternalName(),
sourceMapper);
InlineResult result = inliner.doInline(deferringVisitor, new LocalVarRemapper(parameters, 0), false, LabelOwner.NOT_APPLICABLE);
result.getReifiedTypeParametersUsages().mergeAll(typeParametersToReify);
@@ -289,8 +289,6 @@ public class AnonymousObjectTransformer {
}
String constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, descTypes.toArray(new Type[descTypes.size()]));
//TODO for inline method make public class
anonymousObjectGen.setNewConstructorDescriptor(constructorDescriptor);
MethodVisitor constructorVisitor = classBuilder.newMethod(NO_ORIGIN,
AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
"<init>", constructorDescriptor,
@@ -331,6 +329,8 @@ public class AnonymousObjectTransformer {
inlineMethodAndUpdateGlobalResult(anonymousObjectGen, parentRemapper, capturedFieldInitializer, constructor, constructorInlineBuilder, true);
constructorVisitor.visitEnd();
AsmUtil.genClosureFields(TransformationUtilsKt.toNameTypePair(TransformationUtilsKt.filterSkipped(newFieldsWithSkipped)), classBuilder);
//TODO for inline method make public class
anonymousObjectGen.setNewConstructorDescriptor(constructorDescriptor);
}
@NotNull
@@ -348,11 +348,7 @@ public class AnonymousObjectTransformer {
@NotNull
private ClassBuilder createClassBuilder() {
ClassBuilder classBuilder = state.getFactory().newVisitor(NO_ORIGIN, newLambdaType, inliningContext.getRoot().callElement.getContainingFile());
return new RemappingClassBuilder(
classBuilder,
new AsmTypeRemapper(inliningContext.typeRemapper, inliningContext.getRoot().typeParameterMappings == null, transformationResult)
);
return new RemappingClassBuilder(classBuilder, inliningContext.typeRemapper);
}
@NotNull

View File

@@ -1,57 +0,0 @@
/*
* Copyright 2010-2015 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 org.jetbrains.kotlin.codegen.inline
import org.jetbrains.org.objectweb.asm.commons.Remapper
import org.jetbrains.org.objectweb.asm.commons.RemappingSignatureAdapter
import org.jetbrains.org.objectweb.asm.signature.SignatureReader
import org.jetbrains.org.objectweb.asm.signature.SignatureVisitor
class AsmTypeRemapper(val typeRemapper: TypeRemapper, val isDefaultGeneration: Boolean, val result: InlineResult) : Remapper() {
override fun map(type: String): String {
return typeRemapper.map(type)
}
override fun createRemappingSignatureAdapter(v: SignatureVisitor?): SignatureVisitor {
if (isDefaultGeneration) {
return super.createRemappingSignatureAdapter(v);
}
return object : RemappingSignatureAdapter(v, this) {
override fun visitTypeVariable(name: String) {
/*TODO try to erase absent type variable*/
val mapping = typeRemapper.mapTypeParameter(name) ?: return super.visitTypeVariable(name)
if (mapping.newName != null) {
if (mapping.isReified) {
result.reifiedTypeParametersUsages.addUsedReifiedParameter(mapping.newName)
}
return super.visitTypeVariable(mapping.newName)
}
// else TypeVariable is replaced by concrete type
SignatureReader(mapping.signature).accept(v)
}
override fun visitFormalTypeParameter(name: String) {
typeRemapper.registerTypeParameter(name)
super.visitFormalTypeParameter(name)
}
}
}
}

View File

@@ -25,26 +25,26 @@ import org.jetbrains.org.objectweb.asm.tree.*
import java.util.Comparator
import java.util.Collections
abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
public abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
val tryBlocksMetaInfo: IntervalMetaInfo<TryCatchBlockNodeInfo> = IntervalMetaInfo()
public val tryBlocksMetaInfo: IntervalMetaInfo<TryCatchBlockNodeInfo> = IntervalMetaInfo()
val localVarsMetaInfo: IntervalMetaInfo<LocalVarNodeWrapper> = IntervalMetaInfo()
public val localVarsMetaInfo: IntervalMetaInfo<LocalVarNodeWrapper> = IntervalMetaInfo()
var nextFreeLocalIndex: Int = parameterSize
public var nextFreeLocalIndex: Int = parameterSize
private set
fun getStartNodes(label: LabelNode): List<TryCatchBlockNodeInfo> {
public fun getStartNodes(label: LabelNode): List<TryCatchBlockNodeInfo> {
return tryBlocksMetaInfo.intervalStarts.get(label)
}
fun getEndNodes(label: LabelNode): List<TryCatchBlockNodeInfo> {
public fun getEndNodes(label: LabelNode): List<TryCatchBlockNodeInfo> {
return tryBlocksMetaInfo.intervalEnds.get(label)
}
open fun processInstruction(curInstr: AbstractInsnNode, directOrder: Boolean) {
public open fun processInstruction(curInstr: AbstractInsnNode, directOrder: Boolean) {
if (curInstr is VarInsnNode || curInstr is IincInsnNode) {
val argSize = InlineCodegenUtil.getLoadStoreArgSize(curInstr.opcode)
val argSize = InlineCodegenUtil.getLoadStoreArgSize(curInstr.getOpcode())
val varIndex = if (curInstr is VarInsnNode) curInstr.`var` else (curInstr as IincInsnNode).`var`
nextFreeLocalIndex = Math.max(nextFreeLocalIndex, varIndex + argSize)
}
@@ -55,9 +55,9 @@ abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
}
}
abstract fun instructionIndex(inst: AbstractInsnNode): Int
public abstract fun instructionIndex(inst: AbstractInsnNode): Int
fun sortTryCatchBlocks(intervals: List<TryCatchBlockNodeInfo>): List<TryCatchBlockNodeInfo> {
public fun sortTryCatchBlocks(intervals: List<TryCatchBlockNodeInfo>): List<TryCatchBlockNodeInfo> {
val comp = Comparator { t1: TryCatchBlockNodeInfo, t2: TryCatchBlockNodeInfo ->
var result = instructionIndex(t1.handler) - instructionIndex(t2.handler)
if (result == 0) {
@@ -83,7 +83,7 @@ abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
}
fun substituteLocalVarTable(node: MethodNode) {
public fun substituteLocalVarTable(node: MethodNode) {
node.localVariables.clear()
for (info in localVarsMetaInfo.getMeaningfulIntervals()) {
node.localVariables.add(info.node)
@@ -165,16 +165,16 @@ private fun Interval.isMeaningless(): Boolean {
val start = this.startLabel
var end: AbstractInsnNode = this.endLabel
while (end != start && !end.isMeaningful) {
end = end.previous
end = end.getPrevious()
}
return start == end
}
fun <T : SplittableInterval<T>> IntervalMetaInfo<T>.getMeaningfulIntervals(): List<T> {
public fun <T : SplittableInterval<T>> IntervalMetaInfo<T>.getMeaningfulIntervals(): List<T> {
return allIntervals.filterNot { it.isMeaningless() }
}
class DefaultProcessor(val node: MethodNode, parameterSize: Int) : CoveringTryCatchNodeProcessor(parameterSize) {
public class DefaultProcessor(val node: MethodNode, parameterSize: Int) : CoveringTryCatchNodeProcessor(parameterSize) {
init {
node.tryCatchBlocks.forEach { addTryNode(it) }
@@ -194,7 +194,7 @@ class DefaultProcessor(val node: MethodNode, parameterSize: Int) : CoveringTryCa
}
}
class LocalVarNodeWrapper(val node: LocalVariableNode) : Interval, SplittableInterval<LocalVarNodeWrapper> {
public class LocalVarNodeWrapper(val node: LocalVariableNode) : Interval, SplittableInterval<LocalVarNodeWrapper> {
override val startLabel: LabelNode
get() = node.start
override val endLabel: LabelNode

View File

@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.tree.MethodNode
class DeferredMethodVisitor(
public class DeferredMethodVisitor(
val intermediate: MethodNode,
val resultNode: () -> MethodVisitor
) : MethodVisitor(InlineCodegenUtil.API, intermediate) {

View File

@@ -1,38 +0,0 @@
/*
* Copyright 2010-2016 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 org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
internal class FictitiousArrayConstructor(arrayClass: ClassDescriptor) : SimpleFunctionDescriptorImpl(
arrayClass.containingDeclaration, null, Annotations.EMPTY, arrayClass.name, CallableMemberDescriptor.Kind.SYNTHESIZED,
SourceElement.NO_SOURCE
) {
companion object Factory {
@JvmStatic
fun create(arrayConstructor: ConstructorDescriptor): FictitiousArrayConstructor {
val arrayClass = arrayConstructor.containingDeclaration
return FictitiousArrayConstructor(arrayClass).apply {
this.initialize(null, null, arrayConstructor.typeParameters, arrayConstructor.valueParameters, arrayClass.defaultType,
Modality.FINAL, Visibilities.PUBLIC)
this.isInline = true
}
}
}
}

View File

@@ -23,15 +23,16 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.CodegenUtil;
import org.jetbrains.kotlin.codegen.*;
import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicArrayConstructorsKt;
import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
import org.jetbrains.kotlin.codegen.context.MethodContext;
import org.jetbrains.kotlin.codegen.context.PackageContext;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache;
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents;
import org.jetbrains.kotlin.modules.TargetId;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
@@ -70,7 +71,7 @@ public class InlineCodegen extends CallGenerator {
private final GenerationState state;
private final JetTypeMapper typeMapper;
private final FunctionDescriptor functionDescriptor;
private final SimpleFunctionDescriptor functionDescriptor;
private final JvmMethodSignature jvmSignature;
private final KtElement callElement;
private final MethodContext context;
@@ -84,8 +85,6 @@ public class InlineCodegen extends CallGenerator {
private final Map<Integer, LambdaInfo> expressionMap = new HashMap<Integer, LambdaInfo>();
private final ReifiedTypeInliner reifiedTypeInliner;
@Nullable private final TypeParameterMappings typeParameterMappings;
private final boolean isDefaultCompilation;
private LambdaInfo activeLambda;
@@ -94,23 +93,17 @@ public class InlineCodegen extends CallGenerator {
public InlineCodegen(
@NotNull ExpressionCodegen codegen,
@NotNull GenerationState state,
@NotNull FunctionDescriptor function,
@NotNull SimpleFunctionDescriptor functionDescriptor,
@NotNull KtElement callElement,
@Nullable TypeParameterMappings typeParameterMappings,
boolean isDefaultCompilation
@Nullable ReifiedTypeParameterMappings typeParameterMappings
) {
assert InlineUtil.isInline(function) || InlineUtil.isArrayConstructorWithLambda(function) :
"InlineCodegen can inline only inline functions and array constructors: " + function;
this.isDefaultCompilation = isDefaultCompilation;
assert InlineUtil.isInline(functionDescriptor) : "InlineCodegen could inline only inline function: " + functionDescriptor;
this.state = state;
this.typeMapper = state.getTypeMapper();
this.codegen = codegen;
this.callElement = callElement;
this.functionDescriptor =
InlineUtil.isArrayConstructorWithLambda(function)
? FictitiousArrayConstructor.create((ConstructorDescriptor) function)
: function.getOriginal();
this.typeParameterMappings = typeParameterMappings;
this.functionDescriptor = functionDescriptor.getOriginal();
reifiedTypeInliner = new ReifiedTypeInliner(typeParameterMappings);
@@ -126,14 +119,13 @@ public class InlineCodegen extends CallGenerator {
isSameModule = JvmCodegenUtil.isCallInsideSameModuleAsDeclared(functionDescriptor, codegen.getContext(), state.getOutDirectory());
sourceMapper = codegen.getParentCodegen().getOrCreateSourceMapper();
if (!(functionDescriptor instanceof FictitiousArrayConstructor)) {
reportIncrementalInfo(functionDescriptor, codegen.getContext().getFunctionDescriptor().getOriginal());
}
reportIncrementalInfo(functionDescriptor, codegen.getContext().getFunctionDescriptor().getOriginal());
}
@Override
public void genCallWithoutAssertions(@NotNull CallableMethod callableMethod, @NotNull ExpressionCodegen codegen) {
public void genCallWithoutAssertions(
@NotNull CallableMethod callableMethod, @NotNull ExpressionCodegen codegen
) {
genCall(callableMethod, null, false, codegen);
}
@@ -184,47 +176,37 @@ public class InlineCodegen extends CallGenerator {
}
@NotNull
private SMAPAndMethodNode createMethodNode(boolean callDefault) throws IOException {
Method asmMethod = callDefault
? typeMapper.mapDefaultMethod(functionDescriptor, context.getContextKind())
: jvmSignature.getAsmMethod();
private SMAPAndMethodNode createMethodNode(boolean callDefault) throws ClassNotFoundException, IOException {
JvmMethodSignature jvmSignature = typeMapper.mapSignature(functionDescriptor, context.getContextKind());
Method asmMethod;
if (callDefault) {
asmMethod = typeMapper.mapDefaultMethod(functionDescriptor, context.getContextKind());
}
else {
asmMethod = jvmSignature.getAsmMethod();
}
SMAPAndMethodNode nodeAndSMAP;
if (functionDescriptor instanceof FictitiousArrayConstructor) {
nodeAndSMAP = InlineCodegenUtil.getMethodNode(
IntrinsicArrayConstructorsKt.getBytecode(),
asmMethod.getName(),
asmMethod.getDescriptor(),
IntrinsicArrayConstructorsKt.getClassId()
);
if (nodeAndSMAP == null) {
throw new IllegalStateException("Couldn't obtain array constructor body for " + descriptorName(functionDescriptor));
}
}
else if (functionDescriptor instanceof DeserializedSimpleFunctionDescriptor) {
if (functionDescriptor instanceof DeserializedSimpleFunctionDescriptor) {
JetTypeMapper.ContainingClassesInfo containingClasses = typeMapper.getContainingClassesForDeserializedCallable(
(DeserializedSimpleFunctionDescriptor) functionDescriptor);
ClassId containerId = containingClasses.getImplClassId();
VirtualFile file = InlineCodegenUtil.findVirtualFile(state, containerId);
if (file == null) {
throw new IllegalStateException("Couldn't find declaration file for " + containerId);
}
nodeAndSMAP = InlineCodegenUtil.getMethodNode(
file.contentsToByteArray(), asmMethod.getName(), asmMethod.getDescriptor(), containerId
);
VirtualFile file = InlineCodegenUtil.getVirtualFileForCallable(containingClasses.getImplClassId(), state);
nodeAndSMAP = InlineCodegenUtil.getMethodNode(file.contentsToByteArray(),
asmMethod.getName(),
asmMethod.getDescriptor(),
containingClasses.getFacadeClassId());
if (nodeAndSMAP == null) {
throw new IllegalStateException("Couldn't obtain compiled function body for " + descriptorName(functionDescriptor));
throw new RuntimeException("Couldn't obtain compiled function body for " + descriptorName(functionDescriptor));
}
}
else {
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor);
if (!(element instanceof KtNamedFunction)) {
throw new IllegalStateException("Couldn't find declaration for function " + descriptorName(functionDescriptor));
if (element == null || !(element instanceof KtNamedFunction)) {
throw new RuntimeException("Couldn't find declaration for function " + descriptorName(functionDescriptor));
}
KtNamedFunction inliningFunction = (KtNamedFunction) element;
@@ -241,13 +223,13 @@ public class InlineCodegen extends CallGenerator {
SMAP smap;
if (callDefault) {
Type implementationOwner = typeMapper.mapImplementationOwner(functionDescriptor);
Type implementationOwner = typeMapper.mapOwner(functionDescriptor);
FakeMemberCodegen parentCodegen = new FakeMemberCodegen(codegen.getParentCodegen(), inliningFunction,
(FieldOwnerContext) methodContext.getParentContext(),
implementationOwner.getInternalName());
FunctionCodegen.generateDefaultImplBody(
methodContext, functionDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
inliningFunction, parentCodegen, asmMethod
inliningFunction, parentCodegen
);
smap = createSMAPWithDefaultMapping(inliningFunction, parentCodegen.getOrCreateSourceMapper().getResultMappings());
}
@@ -274,14 +256,17 @@ public class InlineCodegen extends CallGenerator {
Parameters parameters = invocationParamBuilder.buildParameters();
InliningContext info = new RootInliningContext(
expressionMap, state, codegen.getInlineNameGenerator().subGenerator(jvmSignature.getAsmMethod().getName()),
codegen.getContext(), callElement, getInlineCallSiteInfo(), reifiedTypeInliner, typeParameterMappings, isDefaultCompilation
);
InliningContext info = new RootInliningContext(expressionMap,
state,
codegen.getInlineNameGenerator()
.subGenerator(functionDescriptor.getName().asString()),
codegen.getContext(),
callElement,
codegen.getParentCodegen().getClassName(), reifiedTypeInliner);
MethodInliner inliner = new MethodInliner(node, parameters, info, new FieldRemapper(null, null, parameters), isSameModule,
"Method inlining " + callElement.getText(),
createNestedSourceMapper(nodeAndSmap), info.getCallSiteInfo()); //with captured
createNestedSourceMapper(nodeAndSmap)); //with captured
LocalVarRemapper remapper = new LocalVarRemapper(parameters, initialFrameSize);
@@ -313,22 +298,6 @@ public class InlineCodegen extends CallGenerator {
return result;
}
private InlineCallSiteInfo getInlineCallSiteInfo() {
MethodContext context = codegen.getContext();
MemberCodegen<?> parentCodegen = codegen.getParentCodegen();
while (context instanceof InlineLambdaContext) {
CodegenContext closureContext = context.getParentContext();
assert closureContext instanceof ClosureContext : "Parent context of inline lambda should be closure context";
assert closureContext.getParentContext() instanceof MethodContext : "Closure context should appear in method context";
context = (MethodContext) closureContext.getParentContext();
assert parentCodegen instanceof FakeMemberCodegen : "Parent codegen of inlined lambda should be FakeMemberCodegen";
parentCodegen = ((FakeMemberCodegen) parentCodegen).delegate;
}
JvmMethodSignature signature = typeMapper.mapSignature(context.getFunctionDescriptor(), context.getContextKind());
return new InlineCallSiteInfo(parentCodegen.getClassName(), signature.getAsmMethod().getName(), signature.getAsmMethod().getDescriptor());
}
private void generateClosuresBodies() {
for (LambdaInfo info : expressionMap.values()) {
info.setNode(generateLambdaBody(info));
@@ -366,7 +335,7 @@ public class InlineCodegen extends CallGenerator {
new FakeMemberCodegen(codegen.getParentCodegen(), expression,
(FieldOwnerContext) context.getParentContext(),
isLambda ? codegen.getParentCodegen().getClassName()
: typeMapper.mapImplementationOwner(descriptor).getInternalName());
: typeMapper.mapOwner(descriptor).getInternalName());
FunctionGenerationStrategy strategy =
expression instanceof KtCallableReferenceExpression ?
@@ -405,7 +374,7 @@ public class InlineCodegen extends CallGenerator {
private static class FakeMemberCodegen extends MemberCodegen {
@NotNull final MemberCodegen delegate;
private final MemberCodegen delegate;
@NotNull private final String className;
public FakeMemberCodegen(@NotNull MemberCodegen wrapped, @NotNull KtElement declaration, @NotNull FieldOwnerContext codegenContext, @NotNull String className) {
@@ -425,7 +394,7 @@ public class InlineCodegen extends CallGenerator {
}
@Override
protected void generateKotlinMetadataAnnotation() {
protected void generateKotlinAnnotation() {
throw new IllegalStateException();
}
@@ -447,6 +416,7 @@ public class InlineCodegen extends CallGenerator {
public void afterParameterPut(
@NotNull Type type,
@Nullable StackValue stackValue,
@Nullable ValueParameterDescriptor valueParameterDescriptor,
int parameterIndex
) {
putArgumentOrCapturedToLocalVal(type, stackValue, -1, parameterIndex);
@@ -539,11 +509,13 @@ public class InlineCodegen extends CallGenerator {
@Override
public void putHiddenParams() {
if ((getMethodAsmFlags(functionDescriptor, context.getContextKind()) & Opcodes.ACC_STATIC) == 0) {
List<JvmMethodParameterSignature> valueParameters = jvmSignature.getValueParameters();
if (!isStaticMethod(functionDescriptor, context)) {
invocationParamBuilder.addNextParameter(AsmTypes.OBJECT_TYPE, false, null);
}
for (JvmMethodParameterSignature param : jvmSignature.getValueParameters()) {
for (JvmMethodParameterSignature param : valueParameters) {
if (param.getKind() == JvmMethodParameterKind.VALUE) {
break;
}
@@ -651,6 +623,10 @@ public class InlineCodegen extends CallGenerator {
throw new IllegalStateException("Couldn't build context for " + descriptorName(descriptor));
}
private static boolean isStaticMethod(FunctionDescriptor functionDescriptor, MethodContext context) {
return (getMethodAsmFlags(functionDescriptor, context.getContextKind()) & Opcodes.ACC_STATIC) != 0;
}
private static String descriptorName(DeclarationDescriptor descriptor) {
return DescriptorRenderer.SHORT_NAMES_IN_TYPES.render(descriptor);
}
@@ -667,19 +643,21 @@ public class InlineCodegen extends CallGenerator {
}
else {
StackValue value = codegen.gen(argumentExpression);
putValueIfNeeded(parameterType, value, valueParameterDescriptor.getIndex());
putValueIfNeeded(valueParameterDescriptor, parameterType, value, valueParameterDescriptor.getIndex());
}
}
@Override
public void putValueIfNeeded(
@Nullable ValueParameterDescriptor valueParameterDescriptor,
@NotNull Type parameterType,
@NotNull StackValue value
) {
putValueIfNeeded(parameterType, value, -1);
putValueIfNeeded(valueParameterDescriptor, parameterType, value, -1);
}
private void putValueIfNeeded(
@Nullable ValueParameterDescriptor valueParameterDescriptor,
@NotNull Type parameterType,
@NotNull StackValue value,
int index
@@ -687,7 +665,7 @@ public class InlineCodegen extends CallGenerator {
if (shouldPutValue(parameterType, value)) {
value.put(parameterType, codegen.v);
}
afterParameterPut(parameterType, value, index);
afterParameterPut(parameterType, value, valueParameterDescriptor, index);
}
@Override

View File

@@ -16,10 +16,11 @@
package org.jetbrains.kotlin.codegen.inline;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import kotlin.text.StringsKt;
import kotlin.StringsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
@@ -30,7 +31,6 @@ import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.context.CodegenContextUtil;
import org.jetbrains.kotlin.codegen.context.InlineLambdaContext;
import org.jetbrains.kotlin.codegen.context.MethodContext;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicArrayConstructorsKt;
import org.jetbrains.kotlin.codegen.optimization.common.UtilKt;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
@@ -63,7 +63,6 @@ public class InlineCodegenUtil {
public static final int API = Opcodes.ASM5;
public static final String CAPTURED_FIELD_PREFIX = "$";
public static final String NON_CAPTURED_FIELD_PREFIX = "$$";
public static final String THIS$0 = "this$0";
public static final String THIS = "this";
public static final String RECEIVER$0 = "receiver$0";
@@ -85,7 +84,7 @@ public class InlineCodegenUtil {
final String methodName,
final String methodDescriptor,
ClassId classId
) throws IOException {
) throws ClassNotFoundException, IOException {
ClassReader cr = new ClassReader(classData);
final MethodNode[] node = new MethodNode[1];
final String[] debugInfo = new String[2];
@@ -93,10 +92,6 @@ public class InlineCodegenUtil {
lines[0] = Integer.MAX_VALUE;
lines[1] = Integer.MIN_VALUE;
cr.accept(new ClassVisitor(API) {
@Override
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
assertVersionNotGreaterThanJava6(version, name);
}
@Override
public void visitSource(String source, String debug) {
@@ -128,57 +123,44 @@ public class InlineCodegenUtil {
}
}, ClassReader.SKIP_FRAMES | (GENERATE_SMAP ? 0 : ClassReader.SKIP_DEBUG));
if (node[0] == null) {
return null;
}
if (classId.equals(IntrinsicArrayConstructorsKt.getClassId())) {
// Don't load source map for intrinsic array constructors
debugInfo[0] = null;
}
SMAP smap = SMAPParser.parseOrCreateDefault(debugInfo[1], debugInfo[0], classId.asString(), lines[0], lines[1]);
return new SMAPAndMethodNode(node[0], smap);
}
public static void assertVersionNotGreaterThanJava6(int version, String internalName) {
// TODO: report a proper diagnostic
if (version > Opcodes.V1_6 && !"true".equals(System.getProperty("kotlin.skip.bytecode.version.check"))) {
throw new UnsupportedOperationException(
"Cannot inline bytecode of class " + internalName + " which has version " + version + ". " +
"This compiler can only inline Java 1.6 bytecode (version " + Opcodes.V1_6 + ")"
);
}
}
public static void initDefaultSourceMappingIfNeeded(
@NotNull CodegenContext context, @NotNull MemberCodegen codegen, @NotNull GenerationState state
) {
if (!state.isInlineEnabled()) return;
CodegenContext<?> parentContext = context.getParentContext();
while (parentContext != null) {
if (parentContext.isInlineMethodContext()) {
//just init default one to one mapping
codegen.getOrCreateSourceMapper();
break;
public static void initDefaultSourceMappingIfNeeded(@NotNull CodegenContext context, @NotNull MemberCodegen codegen, @NotNull GenerationState state) {
if (state.isInlineEnabled()) {
CodegenContext<?> parentContext = context.getParentContext();
while (parentContext != null) {
if (parentContext instanceof MethodContext) {
if (((MethodContext) parentContext).isInlineMethodContext()) {
//just init default one to one mapping
codegen.getOrCreateSourceMapper();
break;
}
}
parentContext = parentContext.getParentContext();
}
parentContext = parentContext.getParentContext();
}
}
@Nullable
public static VirtualFile findVirtualFile(@NotNull GenerationState state, @NotNull ClassId classId) {
return JvmVirtualFileFinder.SERVICE.getInstance(state.getProject()).findVirtualFileWithHeader(classId);
@NotNull
public static VirtualFile getVirtualFileForCallable(@NotNull ClassId containerClassId, @NotNull GenerationState state) {
JvmVirtualFileFinder fileFinder = JvmVirtualFileFinder.SERVICE.getInstance(state.getProject());
VirtualFile file = fileFinder.findVirtualFileWithHeader(containerClassId);
if (file == null) {
throw new IllegalStateException("Couldn't find declaration file for " + containerClassId);
}
return file;
}
@Nullable
public static VirtualFile findVirtualFileImprecise(@NotNull GenerationState state, @NotNull String internalClassName) {
public static VirtualFile findVirtualFile(@NotNull Project project, @NotNull String internalClassName) {
FqName packageFqName = JvmClassName.byInternalName(internalClassName).getPackageFqName();
String classNameWithDollars = StringsKt.substringAfterLast(internalClassName, "/", internalClassName);
JvmVirtualFileFinder fileFinder = JvmVirtualFileFinder.SERVICE.getInstance(project);
//TODO: we cannot construct proper classId at this point, we need to read InnerClasses info from class file
// we construct valid.package.name/RelativeClassNameAsSingleName that should work in compiler, but fails for inner classes in IDE
return findVirtualFile(state, new ClassId(packageFqName, Name.identifier(classNameWithDollars)));
return fileFinder.findVirtualFileWithHeader(new ClassId(packageFqName, Name.identifier(classNameWithDollars)));
}
public static String getInlineName(
@@ -297,8 +279,7 @@ public class InlineCodegenUtil {
public static boolean isCapturedFieldName(@NotNull String fieldName) {
// TODO: improve this heuristic
return fieldName.startsWith(CAPTURED_FIELD_PREFIX) &&
!fieldName.startsWith(NON_CAPTURED_FIELD_PREFIX) ||
return fieldName.startsWith(CAPTURED_FIELD_PREFIX) ||
THIS$0.equals(fieldName) ||
RECEIVER$0.equals(fieldName);
}
@@ -381,9 +362,8 @@ public class InlineCodegenUtil {
OutputFile outputFile = state.getFactory().get(internalName + ".class");
if (outputFile != null) {
return new ClassReader(outputFile.asByteArray());
}
else {
VirtualFile file = findVirtualFileImprecise(state, internalName);
} else {
VirtualFile file = findVirtualFile(state.getProject(), internalName);
if (file == null) {
throw new RuntimeException("Couldn't find virtual file for " + internalName);
}

View File

@@ -73,18 +73,17 @@ public class InliningContext {
return subInline(nameGenerator.subGenerator("lambda"), map, true);
}
private InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings) {
public InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings) {
return subInline(generator, additionalTypeMappings, isInliningLambda);
}
public InliningContext subInlineWithClassRegeneration(@NotNull NameGenerator generator,
@NotNull Map<String, String> newTypeMappings,
@NotNull AnonymousObjectGeneration anonymousObjectGeneration,
@NotNull InlineCallSiteInfo callSiteInfo
@NotNull AnonymousObjectGeneration anonymousObjectGeneration
) {
return new RegeneratedClassContext(this, expressionMap, state, generator,
TypeRemapper.createFrom(typeRemapper, newTypeMappings),
reifedTypeInliner, isInliningLambda, anonymousObjectGeneration, callSiteInfo);
new TypeRemapper(typeRemapper, newTypeMappings),
reifedTypeInliner, isInliningLambda, anonymousObjectGeneration);
}
public InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings, boolean isInliningLambda) {
@@ -97,15 +96,8 @@ public class InliningContext {
boolean isInliningLambda,
boolean isRegeneration
) {
//isInliningLambda && !this.isInliningLambda for root inline lambda
return new InliningContext(this, expressionMap, state, generator,
TypeRemapper.createFrom(
typeRemapper,
additionalTypeMappings,
//root inline lambda
isInliningLambda && !this.isInliningLambda
),
reifedTypeInliner, isInliningLambda, isRegeneration);
new TypeRemapper(typeRemapper, additionalTypeMappings), reifedTypeInliner, isInliningLambda, isRegeneration);
}
public boolean isRoot() {
@@ -132,8 +124,8 @@ public class InliningContext {
return isInliningLambda && !getParent().isInliningLambda;
}
public InlineCallSiteInfo getCallSiteInfo() {
public String getClassNameToInline() {
assert parent != null : "At least root context should return proper value";
return parent.getCallSiteInfo();
return parent.getClassNameToInline();
}
}

View File

@@ -19,10 +19,12 @@ package org.jetbrains.kotlin.codegen.inline;
import org.jetbrains.annotations.Nullable;
class InvokeCall {
private final int index;
public final LambdaInfo lambdaInfo;
public final int finallyDepthShift;
InvokeCall(@Nullable LambdaInfo lambdaInfo, int finallyDepthShift) {
InvokeCall(int index, @Nullable LambdaInfo lambdaInfo, int finallyDepthShift) {
this.index = index;
this.lambdaInfo = lambdaInfo;
this.finallyDepthShift = finallyDepthShift;
}

View File

@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.codegen.StackValue;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
import org.jetbrains.kotlin.codegen.optimization.MandatoryMethodTransformer;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.utils.SmartSet;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Opcodes;
@@ -56,8 +55,6 @@ public class MethodInliner {
private final SourceMapper sourceMapper;
private final InlineCallSiteInfo inlineCallSiteInfo;
private final JetTypeMapper typeMapper;
private final List<InvokeCall> invokeCalls = new ArrayList<InvokeCall>();
@@ -85,8 +82,7 @@ public class MethodInliner {
@NotNull FieldRemapper nodeRemapper,
boolean isSameModule,
@NotNull String errorPrefix,
@NotNull SourceMapper sourceMapper,
@NotNull InlineCallSiteInfo inlineCallSiteInfo
@NotNull SourceMapper sourceMapper
) {
this.node = node;
this.parameters = parameters;
@@ -95,7 +91,6 @@ public class MethodInliner {
this.isSameModule = isSameModule;
this.errorPrefix = errorPrefix;
this.sourceMapper = sourceMapper;
this.inlineCallSiteInfo = inlineCallSiteInfo;
this.typeMapper = inliningContext.state.getTypeMapper();
this.result = InlineResult.create();
}
@@ -150,7 +145,7 @@ public class MethodInliner {
return result;
}
private MethodNode doInline(final MethodNode node) {
private MethodNode doInline(MethodNode node) {
final Deque<InvokeCall> currentInvokes = new LinkedList<InvokeCall>(invokeCalls);
@@ -159,12 +154,8 @@ public class MethodInliner {
final Iterator<AnonymousObjectGeneration> iterator = anonymousObjectGenerations.iterator();
final TypeRemapper remapper = TypeRemapper.createFrom(currentTypeMapping);
RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(
resultNode.access,
resultNode.desc,
resultNode,
new AsmTypeRemapper(remapper, inliningContext.getRoot().typeParameterMappings == null, result)
);
RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(resultNode.access, resultNode.desc, resultNode,
remapper);
final int markerShift = InlineCodegenUtil.calcMarkerShift(parameters, node);
InlineAdapter lambdaInliner = new InlineAdapter(remappingMethodAdapter, parameters.getArgsSizeOnStack(), sourceMapper) {
@@ -184,8 +175,7 @@ public class MethodInliner {
.subInlineWithClassRegeneration(
inliningContext.nameGenerator,
currentTypeMapping,
anonymousObjectGen,
inlineCallSiteInfo),
anonymousObjectGen),
isSameModule, Type.getObjectType(newClassName)
);
@@ -249,7 +239,7 @@ public class MethodInliner {
inliningContext.subInlineLambda(info),
newCapturedRemapper, true /*cause all calls in same module as lambda*/,
"Lambda inlining " + info.getLambdaClassType().getInternalName(),
mapper, inlineCallSiteInfo);
mapper);
LocalVarRemapper remapper = new LocalVarRemapper(lambdaParameters, valueParamShift);
InlineResult lambdaResult = inliner.doInline(this.mv, remapper, true, info, invokeCall.finallyDepthShift);//TODO add skipped this and receiver
@@ -371,10 +361,7 @@ public class MethodInliner {
@NotNull String name, @NotNull String desc, String signature, @NotNull Label start, @NotNull Label end, int index
) {
if (isInliningLambda || InlineCodegenUtil.GENERATE_SMAP) {
String varSuffix = inliningContext.isRoot() &&
!((RootInliningContext) inliningContext).isDefaultCompilation &&
!InlineCodegenUtil.isFakeLocalVariableForInline(name) ?
INLINE_FUN_VAR_SUFFIX : "";
String varSuffix = inliningContext.isRoot() && !InlineCodegenUtil.isFakeLocalVariableForInline(name) ? INLINE_FUN_VAR_SUFFIX : "";
String varName = !varSuffix.isEmpty() && name.equals("this") ? name + "_" : name;
super.visitLocalVariable(varName + varSuffix, desc, signature, start, end, getNewIndex(index));
}
@@ -428,15 +415,15 @@ public class MethodInliner {
catch (AnalyzerException e) {
throw wrapException(e, node, "couldn't inline method call");
}
Set<AbstractInsnNode> toDelete = SmartSet.create();
InsnList instructions = node.instructions;
AbstractInsnNode cur = instructions.getFirst();
AbstractInsnNode cur = node.instructions.getFirst();
int index = 0;
boolean awaitClassReification = false;
int currentFinallyDeep = 0;
while (cur != null) {
Frame<SourceValue> frame = sources[instructions.indexOf(cur)];
Frame<SourceValue> frame = sources[index];
if (frame != null) {
if (ReifiedTypeInliner.isNeedClassReificationMarker(cur)) {
@@ -459,11 +446,25 @@ public class MethodInliner {
if (isInvokeOnLambda(owner, name) /*&& methodInsnNode.owner.equals(INLINE_RUNTIME)*/) {
SourceValue sourceValue = frame.getStack(firstParameterIndex);
LambdaInfo lambdaInfo = MethodInlinerUtilKt.getLambdaIfExistsAndMarkInstructions(
this, MethodInlinerUtilKt.singleOrNullInsn(sourceValue), true, instructions, sources, toDelete
);
LambdaInfo lambdaInfo = null;
int varIndex = -1;
invokeCalls.add(new InvokeCall(lambdaInfo, currentFinallyDeep));
if (sourceValue.insns.size() == 1) {
AbstractInsnNode insnNode = sourceValue.insns.iterator().next();
AbstractInsnNode processingInstruction = insnNode;
if (insnNode.getOpcode() == Opcodes.SWAP) {
processingInstruction = InlineCodegenUtil.getPrevMeaningful(insnNode);
}
lambdaInfo = getLambdaIfExists(processingInstruction);
if (lambdaInfo != null) {
//remove inlinable access
assert processingInstruction != null;
InlineCodegenUtil.removeInterval(node, processingInstruction, insnNode);
}
}
invokeCalls.add(new InvokeCall(varIndex, lambdaInfo, currentFinallyDeep));
}
else if (isAnonymousConstructorCall(owner, name)) {
Map<Integer, LambdaInfo> lambdaMapping = new HashMap<Integer, LambdaInfo>();
@@ -471,13 +472,14 @@ public class MethodInliner {
int offset = 0;
for (int i = 0; i < paramCount; i++) {
SourceValue sourceValue = frame.getStack(firstParameterIndex + i);
LambdaInfo lambdaInfo = MethodInlinerUtilKt.getLambdaIfExistsAndMarkInstructions(
this, MethodInlinerUtilKt.singleOrNullInsn(sourceValue), false, instructions, sources, toDelete
);
if (lambdaInfo != null) {
lambdaMapping.put(offset, lambdaInfo);
if (sourceValue.insns.size() == 1) {
AbstractInsnNode insnNode = sourceValue.insns.iterator().next();
LambdaInfo lambdaInfo = getLambdaIfExists(insnNode);
if (lambdaInfo != null) {
lambdaMapping.put(offset, lambdaInfo);
node.instructions.remove(insnNode);
}
}
offset += i == 0 ? 1 : argTypes[i - 1].getSize();
}
@@ -504,6 +506,7 @@ public class MethodInliner {
}
AbstractInsnNode prevNode = cur;
cur = cur.getNext();
index++;
//given frame is <tt>null</tt> if and only if the corresponding instruction cannot be reached (dead code).
if (frame == null) {
@@ -513,15 +516,11 @@ public class MethodInliner {
//it may occurs that interval for default handler starts before catch start label, so this label seems as dead,
//but as result all this labels will be merged into one (see KT-5863)
} else {
toDelete.add(prevNode);
node.instructions.remove(prevNode);
}
}
}
for (AbstractInsnNode insnNode : toDelete) {
instructions.remove(insnNode);
}
//clean dead try/catch blocks
List<TryCatchBlockNode> blocks = node.tryCatchBlocks;
for (Iterator<TryCatchBlockNode> iterator = blocks.iterator(); iterator.hasNext(); ) {
@@ -564,7 +563,7 @@ public class MethodInliner {
}
@Nullable
LambdaInfo getLambdaIfExists(@Nullable AbstractInsnNode insnNode) {
public LambdaInfo getLambdaIfExists(@Nullable AbstractInsnNode insnNode) {
if (insnNode == null) {
return null;
}
@@ -636,7 +635,7 @@ public class MethodInliner {
}
}
private static void transformFinallyDeepIndex(@NotNull MethodNode node, int finallyDeepShift) {
private void transformFinallyDeepIndex(@NotNull MethodNode node, int finallyDeepShift) {
if (finallyDeepShift == 0) {
return;
}

View File

@@ -1,72 +0,0 @@
/*
* Copyright 2010-2016 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 org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.VarInsnNode
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue
fun MethodInliner.getLambdaIfExistsAndMarkInstructions(
insnNode: AbstractInsnNode?,
processSwap: Boolean,
insnList: InsnList,
frames: Array<Frame<SourceValue>?>,
toDelete: MutableSet<AbstractInsnNode>
): LambdaInfo? {
if (insnNode == null) return null
getLambdaIfExists(insnNode)?.let {
//delete lambda aload instruction
toDelete.add(insnNode)
return it
}
if (insnNode is VarInsnNode && insnNode.opcode == Opcodes.ALOAD) {
val varIndex = insnNode.`var`
val localFrame = frames[insnList.indexOf(insnNode)] ?: return null
val storeIns = localFrame.getLocal(varIndex).singleOrNullInsn()
if (storeIns is VarInsnNode && storeIns.getOpcode() == Opcodes.ASTORE) {
val frame = frames[insnList.indexOf(storeIns)] ?: return null
val topOfStack = frame.top()!!.singleOrNullInsn()
getLambdaIfExistsAndMarkInstructions(topOfStack, processSwap, insnList, frames, toDelete)?.let {
//remove intermediate lambda astore, aload instruction: see 'complexStack/simple.1.kt' test
toDelete.add(storeIns)
toDelete.add(insnNode)
return it
}
}
}
else if (processSwap && insnNode.opcode == Opcodes.SWAP) {
val swapFrame = frames[insnList.indexOf(insnNode)] ?: return null
val dispatchReceiver = swapFrame.top()!!.singleOrNullInsn()
getLambdaIfExistsAndMarkInstructions(dispatchReceiver, false, insnList, frames, toDelete).let {
//remove swap instruction (dispatch receiver would be deleted on recursion call): see 'complexStack/simpleExtension.1.kt' test
toDelete.add(insnNode)
return it
}
}
return null
}
fun SourceValue.singleOrNullInsn() = insns.singleOrNull()

View File

@@ -24,10 +24,10 @@ internal class Parameters(val real: List<ParameterInfo>, val captured: List<Capt
private val actualDeclShifts: Array<ParameterInfo?>
private val paramToDeclByteCodeIndex: HashMap<ParameterInfo, Int> = hashMapOf()
val realArgsSizeOnStack = real.sumBy { it.type.size }
val capturedArgsSizeOnStack = captured.sumBy { it.type.size }
public val realArgsSizeOnStack = real.sumBy { it.type.size }
public val capturedArgsSizeOnStack = captured.sumBy { it.type.size }
val argsSizeOnStack = realArgsSizeOnStack + capturedArgsSizeOnStack
public val argsSizeOnStack = realArgsSizeOnStack + capturedArgsSizeOnStack
init {
val declIndexesToActual = arrayOfNulls<Int>(argsSizeOnStack)
@@ -54,10 +54,10 @@ internal class Parameters(val real: List<ParameterInfo>, val captured: List<Capt
}
private fun get(index: Int): ParameterInfo {
if (index < real.size) {
if (index < real.size()) {
return real.get(index)
}
return captured.get(index - real.size)
return captured.get(index - real.size())
}
override fun iterator(): Iterator<ParameterInfo> {

View File

@@ -35,18 +35,18 @@ internal class ParametersBuilder private constructor(){
private var nextCaptured = 0
fun addThis(type: Type, skipped: Boolean): ParameterInfo {
val info = ParameterInfo(type, skipped, nextValueParameterIndex, -1, valueAndHiddenParams.size)
val info = ParameterInfo(type, skipped, nextValueParameterIndex, -1, valueAndHiddenParams.size())
addParameter(info)
return info
}
fun addNextParameter(type: Type, skipped: Boolean, remapValue: StackValue?): ParameterInfo {
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, remapValue, valueAndHiddenParams.size))
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, remapValue, valueAndHiddenParams.size()))
}
fun addNextValueParameter(type: Type, skipped: Boolean, remapValue: StackValue?, parameterIndex: Int): ParameterInfo {
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, remapValue,
if (parameterIndex == -1) valueAndHiddenParams.size else { parameterIndex + valueParamStart }))
if (parameterIndex == -1) valueAndHiddenParams.size() else { parameterIndex + valueParamStart }))
}
fun addCapturedParam(
@@ -102,7 +102,7 @@ internal class ParametersBuilder private constructor(){
}
fun markValueParametesStart(){
this.valueParamStart = valueAndHiddenParams.size
this.valueParamStart = valueAndHiddenParams.size()
}
fun listCaptured(): List<CapturedParamInfo> {

View File

@@ -24,7 +24,6 @@ import java.util.Map;
public class RegeneratedClassContext extends InliningContext {
private final AnonymousObjectGeneration anonymousObjectGeneration;
private InlineCallSiteInfo callSiteInfo;
public RegeneratedClassContext(
@Nullable InliningContext parent,
@@ -34,15 +33,14 @@ public class RegeneratedClassContext extends InliningContext {
@NotNull TypeRemapper typeRemapper,
@NotNull ReifiedTypeInliner reifiedTypeInliner,
boolean isInliningLambda,
@NotNull AnonymousObjectGeneration anonymousObjectGeneration,
@NotNull InlineCallSiteInfo callSiteInfo
@NotNull AnonymousObjectGeneration anonymousObjectGeneration
) {
super(parent, map, state, nameGenerator, typeRemapper, reifiedTypeInliner, isInliningLambda, true);
this.anonymousObjectGeneration = anonymousObjectGeneration;
this.callSiteInfo = callSiteInfo;
}
public InlineCallSiteInfo getCallSiteInfo() {
return callSiteInfo;
@Override
public String getClassNameToInline() {
return anonymousObjectGeneration.getOwnerInternalName();
}
}

View File

@@ -16,95 +16,80 @@
package org.jetbrains.kotlin.codegen.inline
import com.google.common.collect.ImmutableSet
import org.jetbrains.kotlin.codegen.context.MethodContext
import org.jetbrains.kotlin.codegen.generateAsCast
import org.jetbrains.kotlin.codegen.generateIsCheck
import org.jetbrains.kotlin.codegen.generateNullCheckForNonSafeAs
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.types.typeUtil.makeNullableIfNeeded
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.signature.SignatureReader
import org.jetbrains.org.objectweb.asm.signature.SignatureWriter
import org.jetbrains.org.objectweb.asm.tree.*
class ReificationArgument(
val parameterName: String, val nullable: Boolean, val arrayDepth: Int
) {
fun asString() = "[".repeat(arrayDepth) + parameterName + (if (nullable) "?" else "")
fun combine(replacement: ReificationArgument) =
ReificationArgument(
replacement.parameterName,
this.nullable || (replacement.nullable && this.arrayDepth == 0),
this.arrayDepth + replacement.arrayDepth)
private class ParameterNameAndNullability(val name: String, val nullable: Boolean)
fun reify(replacementAsmType: Type, kotlinType: KotlinType) =
Pair(Type.getType("[".repeat(arrayDepth) + replacementAsmType), kotlinType.arrayOf(arrayDepth).makeNullableIfNeeded(nullable))
private fun KotlinType.arrayOf(arrayDepth: Int): KotlinType {
val builtins = this.builtIns
var currentType = this
repeat(arrayDepth) {
currentType = builtins.getArrayType(Variance.INVARIANT, currentType)
}
return currentType
}
}
class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?) {
enum class OperationKind {
NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS;
val id: Int get() = ordinal
}
public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParameterMappings?) {
companion object {
@JvmField val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
@JvmField val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
public val NEW_ARRAY_MARKER_METHOD_NAME: String = "reifyNewArray"
public val CHECKCAST_MARKER_METHOD_NAME: String = "reifyCheckcast"
public val SAFE_CHECKCAST_MARKER_METHOD_NAME: String = "reifySafeCheckcast"
public val INSTANCEOF_MARKER_METHOD_NAME: String = "reifyInstanceof"
public val JAVA_CLASS_MARKER_METHOD_NAME: String = "reifyJavaClass"
public val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME: String = "needClassReification"
private fun isOperationReifiedMarker(insn: AbstractInsnNode) =
isReifiedMarker(insn) { it == REIFIED_OPERATION_MARKER_METHOD_NAME }
private val PARAMETRISED_MARKERS = ImmutableSet.of(
NEW_ARRAY_MARKER_METHOD_NAME,
CHECKCAST_MARKER_METHOD_NAME, SAFE_CHECKCAST_MARKER_METHOD_NAME,
INSTANCEOF_MARKER_METHOD_NAME, JAVA_CLASS_MARKER_METHOD_NAME
)
private fun isParametrisedReifiedMarker(insn: AbstractInsnNode) =
isReifiedMarker(insn) { PARAMETRISED_MARKERS.contains(it) }
private fun isReifiedMarker(insn: AbstractInsnNode, namePredicate: (String) -> Boolean): Boolean {
if (insn.opcode != Opcodes.INVOKESTATIC || insn !is MethodInsnNode) return false
if (insn.getOpcode() != Opcodes.INVOKESTATIC || insn !is MethodInsnNode) return false
return insn.owner == IntrinsicMethods.INTRINSICS_CLASS_NAME && namePredicate(insn.name)
}
@JvmStatic fun isNeedClassReificationMarker(insn: AbstractInsnNode): Boolean =
@JvmStatic
public fun isNeedClassReificationMarker(insn: AbstractInsnNode): Boolean =
isReifiedMarker(insn) { s -> s == NEED_CLASS_REIFICATION_MARKER_METHOD_NAME }
@JvmStatic fun putNeedClassReificationMarker(v: MethodVisitor) {
@JvmStatic
public fun putNeedClassReificationMarker(v: MethodVisitor) {
v.visitMethodInsn(
Opcodes.INVOKESTATIC,
IntrinsicMethods.INTRINSICS_CLASS_NAME, NEED_CLASS_REIFICATION_MARKER_METHOD_NAME,
Type.getMethodDescriptor(Type.VOID_TYPE), false
);
}
@JvmStatic
public fun isNullableMarkerInstruction(marker: String) = INSTANCEOF_MARKER_METHOD_NAME == marker ||
CHECKCAST_MARKER_METHOD_NAME == marker
}
private var maxStackSize = 0
private val hasReifiedParameters = parametersMapping?.hasReifiedParameters() ?: false
/**
* @return set of type parameters' identifiers contained in markers that should be reified further
* e.g. when we're generating inline function containing reified T
* and another function containing reifiable parts is inlined into that function
*/
fun reifyInstructions(node: MethodNode): ReifiedTypeParametersUsages {
if (!hasReifiedParameters) return ReifiedTypeParametersUsages()
public fun reifyInstructions(node: MethodNode): ReifiedTypeParametersUsages {
if (parametersMapping == null) return ReifiedTypeParametersUsages()
val instructions = node.instructions
maxStackSize = 0
var result = ReifiedTypeParametersUsages()
for (insn in instructions.toArray()) {
if (isOperationReifiedMarker(insn)) {
if (isParametrisedReifiedMarker(insn)) {
val newName: String? = processReifyMarker(insn as MethodInsnNode, instructions)
if (newName != null) {
result.addUsedReifiedParameter(newName)
@@ -116,82 +101,144 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
return result
}
public fun reifySignature(oldSignature: String): SignatureReificationResult {
if (parametersMapping == null) return SignatureReificationResult(oldSignature, ReifiedTypeParametersUsages())
val signatureRemapper = object : SignatureWriter() {
var typeParamsToReify = ReifiedTypeParametersUsages()
override fun visitTypeVariable(name: String?) {
val mapping = getMappingByName(name) ?:
return super.visitTypeVariable(name)
if (mapping.newName != null) {
typeParamsToReify.addUsedReifiedParameter(mapping.newName)
return super.visitTypeVariable(mapping.newName)
}
// else TypeVariable is replaced by concrete type
SignatureReader(mapping.signature).accept(this)
}
override fun visitFormalTypeParameter(name: String?) {
val mapping = getMappingByName(name) ?:
return super.visitFormalTypeParameter(name)
if (mapping.newName != null) {
typeParamsToReify.addUsedReifiedParameter(mapping.newName)
super.visitFormalTypeParameter(mapping.newName)
}
}
private fun getMappingByName(name: String?) = parametersMapping[name!!]
}
SignatureReader(oldSignature).accept(signatureRemapper)
return SignatureReificationResult(signatureRemapper.toString(), signatureRemapper.typeParamsToReify)
}
data class SignatureReificationResult(val newSignature: String, val typeParametersUsages: ReifiedTypeParametersUsages)
/**
* @return new type parameter identifier if this marker should be reified further
* or null if it shouldn't
*/
private fun processReifyMarker(insn: MethodInsnNode, instructions: InsnList): String? {
val operationKind = insn.operationKind ?: return null
val reificationArgument = insn.reificationArgument ?: return null
val mapping = parametersMapping?.get(reificationArgument.parameterName) ?: return null
val parameter = getParameter(insn) ?: return null
val mapping = parametersMapping?.get(parameter.name) ?: return null
val kotlinType =
if (isNullableMarkerInstruction(insn.name) && parameter.nullable)
TypeUtils.makeNullable(mapping.type)
else
mapping.type
if (mapping.asmType != null) {
val asmType = mapping.asmType
if (asmType != null) {
// process* methods return false if marker should be reified further
// or it's invalid (may be emitted explicitly in code)
// they return true if instruction is reified and marker can be deleted
val (asmType, kotlinType) = reificationArgument.reify(mapping.asmType, mapping.type)
if (when (operationKind) {
OperationKind.NEW_ARRAY -> processNewArray(insn, asmType)
OperationKind.AS -> processAs(insn, instructions, kotlinType, asmType, safe = false)
OperationKind.SAFE_AS -> processAs(insn, instructions, kotlinType, asmType, safe = true)
OperationKind.IS -> processIs(insn, instructions, kotlinType, asmType)
OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType)
if (when (insn.name) {
NEW_ARRAY_MARKER_METHOD_NAME -> processNewArray(insn, asmType)
CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, kotlinType, asmType, safe = false)
SAFE_CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, kotlinType, asmType, safe = true)
INSTANCEOF_MARKER_METHOD_NAME -> processInstanceof(insn, instructions, kotlinType, asmType)
JAVA_CLASS_MARKER_METHOD_NAME -> processJavaClass(insn, asmType)
else -> false
}) {
instructions.remove(insn.previous.previous!!) // PUSH operation ID
instructions.remove(insn.previous!!) // PUSH type parameter
instructions.remove(insn) // INVOKESTATIC marker method
instructions.remove(insn.getPrevious()!!)
instructions.remove(insn)
}
return null
} else {
val newReificationArgument = reificationArgument.combine(mapping.reificationArgument!!)
instructions.set(insn.previous!!, LdcInsnNode(newReificationArgument.asString()))
return mapping.reificationArgument.parameterName
val nullableSuffix = if (isNullableMarkerInstruction(insn.name) && kotlinType.isMarkedNullable) "?" else ""
instructions.set(insn.previous!!, LdcInsnNode(mapping.newName + nullableSuffix))
return mapping.newName
}
}
private fun processNewArray(insn: MethodInsnNode, parameter: Type) =
processNextTypeInsn(insn, parameter, Opcodes.ANEWARRAY)
private fun processAs(insn: MethodInsnNode,
instructions: InsnList,
kotlinType: KotlinType,
asmType: Type,
safe: Boolean) =
rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { stubCheckcast: AbstractInsnNode ->
if (stubCheckcast !is TypeInsnNode) return false
val newMethodNode = MethodNode(InlineCodegenUtil.API)
generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe)
instructions.insert(insn, newMethodNode.instructions)
instructions.remove(stubCheckcast)
// TODO: refine max stack calculation (it's not always as big as +4)
maxStackSize = Math.max(maxStackSize, 4)
private fun processCheckcast(insn: MethodInsnNode,
instructions: InsnList,
jetType: KotlinType,
asmType: Type,
safe: Boolean) =
rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { instanceofInsn: AbstractInsnNode ->
if (instanceofInsn !is TypeInsnNode) return false
addNullCheckForAsIfNeeded(insn.previous!!, instructions, jetType, safe)
TypeIntrinsics.checkcast(instanceofInsn, instructions, jetType, asmType, safe)
return true
}
private fun processIs(insn: MethodInsnNode,
instructions: InsnList,
kotlinType: KotlinType,
asmType: Type) =
rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { stubInstanceOf: AbstractInsnNode ->
if (stubInstanceOf !is TypeInsnNode) return false
private fun addNullCheckForAsIfNeeded(insn: AbstractInsnNode, instructions: InsnList, jetType: KotlinType, safe: Boolean) {
if (!safe && !TypeUtils.isNullableType(jetType)) {
val methodNode = MethodNode(InlineCodegenUtil.API)
generateNullCheckForNonSafeAs(InstructionAdapter(methodNode), jetType)
val newMethodNode = MethodNode(InlineCodegenUtil.API)
generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType)
InlineCodegenUtil.insertNodeBefore(methodNode, instructions, insn)
maxStackSize = Math.max(maxStackSize, 4)
}
}
instructions.insert(insn, newMethodNode.instructions)
instructions.remove(stubInstanceOf)
private fun processInstanceof(insn: MethodInsnNode, instructions: InsnList, jetType: KotlinType, asmType: Type) =
rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { instanceofInsn: AbstractInsnNode ->
if (instanceofInsn !is TypeInsnNode) return false
// TODO: refine max stack calculation (it's not always as big as +2)
maxStackSize = Math.max(maxStackSize, 2)
addNullCheckForIsIfNeeded(insn, instructions, jetType)
TypeIntrinsics.instanceOf(instanceofInsn, instructions, jetType, asmType)
return true
}
private fun addNullCheckForIsIfNeeded(insn: AbstractInsnNode, instructions: InsnList, type: KotlinType) {
if (TypeUtils.isNullableType(type)) {
val instanceOf = insn.next
insertNullCheckAround(instructions, insn.previous!!, instanceOf)
maxStackSize = Math.max(maxStackSize, 2)
}
}
private fun insertNullCheckAround(instructions: InsnList, start: AbstractInsnNode, end: AbstractInsnNode) {
val methodNode = MethodNode(InlineCodegenUtil.API)
var splitIndex: Int = -1
generateIsCheck(InstructionAdapter(methodNode), true) {
splitIndex = methodNode.instructions.size()
}
assert(splitIndex >= 0) {
"Split index should be non-negative, but $splitIndex"
}
val nullCheckInsns = methodNode.instructions.toArray()
nullCheckInsns.take(splitIndex).forEach {
instructions.insertBefore(start, it)
}
nullCheckInsns.drop(splitIndex).reversed().forEach {
instructions.insert(end, it)
}
}
inline private fun rewriteNextTypeInsn(
marker: MethodInsnNode,
expectedNextOpcode: Int,
@@ -203,81 +250,61 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
}
private fun processNextTypeInsn(insn: MethodInsnNode, parameter: Type, expectedNextOpcode: Int): Boolean {
if (insn.next?.opcode != expectedNextOpcode) return false
(insn.next as TypeInsnNode).desc = parameter.internalName
if (insn.getNext()?.getOpcode() != expectedNextOpcode) return false
(insn.getNext() as TypeInsnNode).desc = parameter.getInternalName()
return true
}
private fun processJavaClass(insn: MethodInsnNode, parameter: Type): Boolean {
val next = insn.next
val next = insn.getNext()
if (next !is LdcInsnNode) return false
next.cst = parameter
return true
}
}
private fun getParameter(insn: MethodInsnNode): ParameterNameAndNullability? {
val prev = insn.getPrevious()!!
private val MethodInsnNode.reificationArgument: ReificationArgument?
get() {
val prev = previous!!
val reificationArgumentRaw = when (prev.opcode) {
val parameterNameWithFlag = when (prev.getOpcode()) {
Opcodes.LDC -> (prev as LdcInsnNode).cst as String
else -> return null
}
val arrayDepth = reificationArgumentRaw.indexOfFirst { it != '[' }
val parameterName = reificationArgumentRaw.substring(arrayDepth).removeSuffix("?")
val nullable = reificationArgumentRaw.endsWith('?')
return ReificationArgument(parameterName, nullable, arrayDepth)
}
private val MethodInsnNode.operationKind: ReifiedTypeInliner.OperationKind? get() =
previous?.previous?.intConstant?.let {
ReifiedTypeInliner.OperationKind.values().getOrNull(it)
}
class TypeParameterMappings() {
private val mappingsByName = hashMapOf<String, TypeParameterMapping>()
fun addParameterMappingToType(name: String, type: KotlinType, asmType: Type, signature: String, isReified: Boolean) {
mappingsByName[name] = TypeParameterMapping(name, type, asmType, reificationArgument = null, signature = signature, isReified = isReified)
}
fun addParameterMappingForFurtherReification(name: String, type: KotlinType, reificationArgument: ReificationArgument, isReified: Boolean) {
mappingsByName[name] = TypeParameterMapping(name, type, asmType = null, reificationArgument = reificationArgument, signature = null, isReified = isReified)
}
operator fun get(name: String): TypeParameterMapping? {
return mappingsByName[name]
}
fun hasReifiedParameters() = mappingsByName.values.any { it.isReified }
internal inline fun forEach(l: (TypeParameterMapping) -> Unit) {
mappingsByName.values.forEach(l)
val parameterName = if (parameterNameWithFlag.endsWith("?")) parameterNameWithFlag.dropLast(1) else parameterNameWithFlag
return ParameterNameAndNullability(parameterName, parameterName !== parameterNameWithFlag)
}
}
class TypeParameterMapping(
val name: String, val type: KotlinType,
val asmType: Type?,
val reificationArgument: ReificationArgument?,
val signature: String?,
val isReified: Boolean
public class ReifiedTypeParameterMappings() {
private val mappingsByName = hashMapOf<String, ReifiedTypeParameterMapping>()
public fun addParameterMappingToType(name: String, type: KotlinType, asmType: Type, signature: String) {
mappingsByName[name] = ReifiedTypeParameterMapping(name, type, asmType, newName = null, signature = signature)
}
public fun addParameterMappingToNewParameter(name: String, type: KotlinType, newName: String) {
mappingsByName[name] = ReifiedTypeParameterMapping(name, type = type, asmType = null, newName = newName, signature = null)
}
operator fun get(name: String): ReifiedTypeParameterMapping? {
return mappingsByName[name]
}
}
public class ReifiedTypeParameterMapping(
val name: String, val type: KotlinType, val asmType: Type?, val newName: String?, val signature: String?
)
class ReifiedTypeParametersUsages {
public class ReifiedTypeParametersUsages {
val usedTypeParameters: MutableSet<String> = hashSetOf()
fun wereUsedReifiedParameters(): Boolean = usedTypeParameters.isNotEmpty()
public fun wereUsedReifiedParameters(): Boolean = usedTypeParameters.isNotEmpty()
fun addUsedReifiedParameter(name: String) {
public fun addUsedReifiedParameter(name: String) {
usedTypeParameters.add(name)
}
fun propagateChildUsagesWithinContext(child: ReifiedTypeParametersUsages, context: MethodContext) {
public fun propagateChildUsagesWithinContext(child: ReifiedTypeParametersUsages, context: MethodContext) {
if (!child.wereUsedReifiedParameters()) return
// used for propagating reified TP usages from children member codegen to parent's
// mark enclosing object-literal/lambda as needed reification iff
@@ -291,7 +318,7 @@ class ReifiedTypeParametersUsages {
}.forEach { usedTypeParameters.add(it) }
}
fun mergeAll(other: ReifiedTypeParametersUsages) {
public fun mergeAll(other: ReifiedTypeParametersUsages) {
if (!other.wereUsedReifiedParameters()) return
usedTypeParameters.addAll(other.usedTypeParameters)
}

View File

@@ -52,10 +52,7 @@ public class RemappingClassBuilder extends DelegatingClassBuilder {
@Nullable String signature,
@Nullable Object value
) {
return new RemappingFieldAdapter(
builder.newField(origin, access, name, remapper.mapDesc(desc), remapper.mapSignature(signature, true), value),
remapper
);
return new RemappingFieldAdapter(builder.newField(origin, access, name, remapper.mapDesc(desc), signature, value), remapper);
}
@Override
@@ -68,11 +65,9 @@ public class RemappingClassBuilder extends DelegatingClassBuilder {
@Nullable String signature,
@Nullable String[] exceptions
) {
return new RemappingMethodAdapter(
access, desc,
builder.newMethod(origin, access, name, remapper.mapMethodDesc(desc), remapper.mapSignature(signature, false), exceptions),
remapper
);
return new RemappingMethodAdapter(access, desc,
builder.newMethod(origin, access, name, remapper.mapMethodDesc(desc), signature, exceptions),
remapper);
}
@Override
@@ -86,4 +81,5 @@ public class RemappingClassBuilder extends DelegatingClassBuilder {
public ClassVisitor getVisitor() {
return new RemappingClassAdapter(builder.getVisitor(), remapper);
}
}

View File

@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.codegen.inline;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.psi.KtElement;
@@ -26,9 +25,7 @@ import java.util.Map;
public class RootInliningContext extends InliningContext {
public final CodegenContext startContext;
private final InlineCallSiteInfo inlineCallSiteInfo;
public final TypeParameterMappings typeParameterMappings;
public final boolean isDefaultCompilation;
private final String classNameToInline;
public final KtElement callElement;
public RootInliningContext(
@@ -37,21 +34,18 @@ public class RootInliningContext extends InliningContext {
@NotNull NameGenerator nameGenerator,
@NotNull CodegenContext startContext,
@NotNull KtElement callElement,
@NotNull InlineCallSiteInfo classNameToInline,
@NotNull ReifiedTypeInliner inliner,
@Nullable TypeParameterMappings typeParameterMappings,
boolean isDefaultCompilation
@NotNull String classNameToInline,
@NotNull ReifiedTypeInliner inliner
) {
super(null, map, state, nameGenerator, TypeRemapper.createRoot(typeParameterMappings), inliner, false, false);
super(null, map, state, nameGenerator, TypeRemapper.createEmpty(), inliner, false, false);
this.callElement = callElement;
this.startContext = startContext;
this.inlineCallSiteInfo = classNameToInline;
this.typeParameterMappings = typeParameterMappings;
this.isDefaultCompilation = isDefaultCompilation;
this.classNameToInline = classNameToInline;
}
@Override
public InlineCallSiteInfo getCallSiteInfo() {
return inlineCallSiteInfo;
@NotNull
public String getClassNameToInline() {
return classNameToInline;
}
}

View File

@@ -24,12 +24,11 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor
import java.util.*
//TODO join parameter
class SMAPBuilder(
val source: String,
val path: String,
val fileMappings: List<FileMapping>
) {
private val header = "SMAP\n$source\nKotlin\n*S Kotlin"
public class SMAPBuilder(val source: String,
val path: String,
val fileMappings: List<FileMapping>) {
val header = "SMAP\n$source\nKotlin\n*S Kotlin"
fun build(): String? {
var realMappings = fileMappings.filter {
@@ -38,7 +37,7 @@ class SMAPBuilder(
}
if (realMappings.isEmpty()) {
return null
return null;
}
val fileIds = "*F" + realMappings.mapIndexed { id, file -> "\n${file.toSMAPFile(id + 1)}" }.joinToString("")
@@ -47,29 +46,29 @@ class SMAPBuilder(
return "$header\n$fileIds\n$lineMappings\n*E\n"
}
private fun RangeMapping.toSMAP(fileId: Int): String {
fun RangeMapping.toSMAP(fileId: Int): String {
return if (range == 1) "$source#$fileId:$dest" else "$source#$fileId,$range:$dest"
}
private fun FileMapping.toSMAPFile(id: Int): String {
this.id = id
fun FileMapping.toSMAPFile(id: Int): String {
this.id = id;
return "+ $id $name\n$path"
}
//TODO inline
private fun FileMapping.toSMAPMapping(): String {
fun FileMapping.toSMAPMapping(): String {
return lineMappings.joinToString("") { "\n${it.toSMAP(id)}" }
}
}
open class NestedSourceMapper(
parent: SourceMapper, val ranges: List<RangeMapping>, sourceInfo: SourceInfo
) : DefaultSourceMapper(sourceInfo, parent) {
public open class NestedSourceMapper(parent: SourceMapper, val ranges: List<RangeMapping>, sourceInfo: SourceInfo) : DefaultSourceMapper(sourceInfo, parent) {
override fun visitLineNumber(iv: MethodVisitor, lineNumber: Int, start: Label) {
val index = ranges.binarySearch(RangeMapping(lineNumber, lineNumber, 1), Comparator {
val index = Collections.binarySearch(ranges, RangeMapping(lineNumber, lineNumber, 1)) {
value, key ->
if (key.dest in value) 0 else RangeMapping.Comparator.compare(value, key)
})
if (value.contains(key.dest)) 0 else RangeMapping.Comparator.compare(value, key)
}
if (index < 0) {
parent!!.visitSource(sourceInfo.source, sourceInfo.pathOrCleanFQN)
parent!!.visitLineNumber(iv, lineNumber, start)
@@ -82,9 +81,8 @@ open class NestedSourceMapper(
}
}
open class InlineLambdaSourceMapper(
parent: SourceMapper, smap: SMAPAndMethodNode
) : NestedSourceMapper(parent, smap.ranges, smap.classSMAP.sourceInfo) {
public open class InlineLambdaSourceMapper(parent: SourceMapper, smap: SMAPAndMethodNode) : NestedSourceMapper(parent, smap.ranges, smap.classSMAP.sourceInfo) {
override fun visitSource(name: String, path: String) {
super.visitSource(name, path)
if (isOriginalVisited()) {
@@ -102,13 +100,13 @@ open class InlineLambdaSourceMapper(
}
override fun visitLineNumber(iv: MethodVisitor, lineNumber: Int, start: Label) {
val index = ranges.binarySearch(RangeMapping(lineNumber, lineNumber, 1), Comparator {
val index = Collections.binarySearch(ranges, RangeMapping(lineNumber, lineNumber, 1)) {
value, key ->
if (key.dest in value) 0 else RangeMapping.Comparator.compare(value, key)
})
if (value.contains(key.dest)) 0 else RangeMapping.Comparator.compare(value, key)
}
if (index >= 0) {
val mapping = ranges[index].parent!!
if (mapping.path == origin.path && mapping.name == origin.name) {
val fmapping = ranges[index].parent!!
if (fmapping.path == origin.path && fmapping.name == origin.name) {
parent!!.visitOrigin()
parent!!.visitLineNumber(iv, lineNumber, start)
return
@@ -119,6 +117,7 @@ open class InlineLambdaSourceMapper(
}
interface SourceMapper {
val resultMappings: List<FileMapping>
val parent: SourceMapper?
@@ -139,6 +138,7 @@ interface SourceMapper {
}
companion object {
fun flushToClassBuilder(mapper: SourceMapper, v: ClassBuilder) {
for (fileMapping in mapper.resultMappings) {
v.addSMAP(fileMapping)
@@ -162,7 +162,7 @@ interface SourceMapper {
}
}
object IdenticalSourceMapper : SourceMapper {
public object IdenticalSourceMapper : SourceMapper {
override val resultMappings: List<FileMapping>
get() = emptyList()
@@ -178,11 +178,16 @@ object IdenticalSourceMapper : SourceMapper {
}
}
open class DefaultSourceMapper(val sourceInfo: SourceInfo, override val parent: SourceMapper?): SourceMapper {
public open class DefaultSourceMapper(val sourceInfo: SourceInfo, override val parent: SourceMapper?): SourceMapper {
protected var maxUsedValue: Int = sourceInfo.linesInFile
var lastVisited: RawFileMapping? = null
private var lastMappedWithChanges: RawFileMapping? = null
private var fileMappings: LinkedHashMap<String, RawFileMapping> = linkedMapOf()
var fileMappings: LinkedHashMap<String, RawFileMapping> = linkedMapOf()
protected val origin: RawFileMapping
init {
@@ -197,10 +202,10 @@ open class DefaultSourceMapper(val sourceInfo: SourceInfo, override val parent:
private fun createKey(name: String, path: String) = "$name#$path"
override val resultMappings: List<FileMapping>
get() = fileMappings.values.map { it.toFileMapping() }
get() = fileMappings.values().map { it.toFileMapping() }
override fun visitSource(name: String, path: String) {
lastVisited = fileMappings.getOrPut(createKey(name, path)) { RawFileMapping(name, path) }
lastVisited = fileMappings.getOrPut(createKey(name, path), { RawFileMapping(name, path) })
}
override fun visitOrigin() {
@@ -227,6 +232,7 @@ open class DefaultSourceMapper(val sourceInfo: SourceInfo, override val parent:
}
}
/*Source Mapping*/
class SMAP(val fileMappings: List<FileMapping>) {
init {
assert(fileMappings.isNotEmpty()) { "File Mappings shouldn't be empty" }
@@ -245,7 +251,9 @@ class SMAP(val fileMappings: List<FileMapping>) {
companion object {
val FILE_SECTION = "*F"
val LINE_SECTION = "*L"
val END = "*E"
}
}
@@ -254,17 +262,18 @@ class RawFileMapping(val name: String, val path: String) {
private val lineMappings = TIntIntHashMap()
private val rangeMappings = arrayListOf<RangeMapping>()
private var lastMappedWithNewIndex = -1000
private var lastMappedWithNewIndex = -1000;
fun toFileMapping() =
FileMapping(name, path).apply {
for (range in rangeMappings) {
addRangeMapping(range)
}
}
fun toFileMapping(): FileMapping {
val fileMapping = FileMapping(name, path)
for (range in rangeMappings) {
fileMapping.addRangeMapping(range)
}
return fileMapping
}
fun initRange(start: Int, end: Int) {
assert(lineMappings.isEmpty) { "initRange should only be called for empty mapping" }
assert(lineMappings.isEmpty()) { "initRange should only be called for empty mapping" }
for (index in start..end) {
lineMappings.put(index, index)
}
@@ -306,20 +315,21 @@ class RawFileMapping(val name: String, val path: String) {
private fun couldFoldInRange(first: Int, second: Int): Boolean {
//TODO
val delta = second - first
return delta > 0 && delta <= 10
return delta > 0 && delta <= 10;
}
}
open class FileMapping(val name: String, val path: String) {
open public class FileMapping(val name: String, val path: String) {
val lineMappings = arrayListOf<RangeMapping>()
var id = -1
var id = -1;
fun addRangeMapping(lineMapping: RangeMapping) {
lineMappings.add(lineMapping)
lineMapping.parent = this
}
object SKIP : FileMapping("no-source-info", "no-source-info") {
public object SKIP : FileMapping("no-source-info", "no-source-info") {
init {
addRangeMapping(RangeMapping.SKIP)
}
@@ -327,11 +337,13 @@ open class FileMapping(val name: String, val path: String) {
}
//TODO comparable
data class RangeMapping(val source: Int, val dest: Int, var range: Int = 1) {
var parent: FileMapping? = null
data public class RangeMapping(val source: Int, val dest: Int, var range: Int = 1) {
var parent: FileMapping? = null;
private val skip = source == -1 && dest == -1
operator fun contains(destLine: Int): Boolean {
fun contains(destLine: Int): Boolean {
return if (skip) true else dest <= destLine && destLine < dest + range
}
@@ -354,6 +366,6 @@ data class RangeMapping(val source: Int, val dest: Int, var range: Int = 1) {
}
companion object {
val SKIP = RangeMapping(-1, -1, 1)
public val SKIP = RangeMapping(-1, -1, 1)
}
}
}

Some files were not shown because too many files have changed in this diff Show More