Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
硅谷海盗
kotlin
提交
aaed9b03
K
kotlin
项目概览
硅谷海盗
/
kotlin
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kotlin
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
aaed9b03
编写于
11月 15, 2011
作者:
A
Alex Tkachman
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
KT-504 array like expressions with type parameters
上级
74654c46
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
196 addition
and
60 deletion
+196
-60
compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java
...backend/src/org/jetbrains/jet/codegen/CallableMethod.java
+0
-8
compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
...kend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
+18
-8
compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java
...ler/backend/src/org/jetbrains/jet/codegen/StackValue.java
+156
-44
compiler/testData/codegen/regressions/kt504.jet
compiler/testData/codegen/regressions/kt504.jet
+16
-0
compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java
compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java
+6
-0
未找到文件。
compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java
浏览文件 @
aaed9b03
...
...
@@ -84,12 +84,4 @@ public class CallableMethod implements Callable {
public
boolean
isNeedsReceiver
()
{
return
receiverFunction
!=
null
;
}
public
ClassDescriptor
getThisClass
()
{
return
thisClass
;
}
public
CallableDescriptor
getReceiverFunction
()
{
return
receiverFunction
;
}
}
compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
浏览文件 @
aaed9b03
...
...
@@ -53,8 +53,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
private
int
myLastLineNumber
=
-
1
;
final
InstructionAdapter
v
;
private
final
FrameMap
myFrameMap
;
private
final
JetTypeMapper
typeMapper
;
final
FrameMap
myFrameMap
;
final
JetTypeMapper
typeMapper
;
private
final
GenerationState
state
;
private
final
Type
returnType
;
...
...
@@ -1200,7 +1200,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
callableMethod
.
invokeWithDefault
(
v
,
mask
);
}
pr
ivate
void
generateFromResolvedCall
(
ReceiverDescriptor
descriptor
)
{
pr
otected
void
generateFromResolvedCall
(
ReceiverDescriptor
descriptor
)
{
if
(
descriptor
instanceof
ClassReceiver
)
{
ClassReceiver
classReceiver
=
(
ClassReceiver
)
descriptor
;
generateThisOrOuter
((
ClassDescriptor
)
classReceiver
.
getDeclarationDescriptor
()).
put
(
typeMapper
.
mapType
(
descriptor
.
getType
()),
v
);
...
...
@@ -2111,12 +2111,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
boolean
isGetter
=
accessor
.
getSignature
().
getName
().
equals
(
"get"
);
ResolvedCall
<
FunctionDescriptor
>
resolvedSetCall
=
bindingContext
.
get
(
BindingContext
.
INDEXED_LVALUE_SET
,
expression
);
FunctionDescriptor
setterDescriptor
=
resolvedSetCall
==
null
?
null
:
resolvedSetCall
.
getResultingDescriptor
();
CallableMethod
setter
=
resolvedSetCall
==
null
?
null
:
typeMapper
.
mapToCallableMethod
(
setterDescriptor
,
false
,
OwnerKind
.
IMPLEMENTATION
);
ResolvedCall
<
FunctionDescriptor
>
resolvedGetCall
=
bindingContext
.
get
(
BindingContext
.
INDEXED_LVALUE_GET
,
expression
);
FunctionDescriptor
setterDescriptor
=
resolvedSetCall
==
null
?
null
:
resolvedSetCall
.
getResultingDescriptor
();
FunctionDescriptor
getterDescriptor
=
resolvedGetCall
==
null
?
null
:
resolvedGetCall
.
getResultingDescriptor
();
CallableMethod
getter
=
resolvedGetCall
==
null
?
null
:
typeMapper
.
mapToCallableMethod
(
getterDescriptor
,
false
,
OwnerKind
.
IMPLEMENTATION
);
Type
asmType
;
Type
[]
argumentTypes
=
accessor
.
getSignature
().
getArgumentTypes
();
...
...
@@ -2126,6 +2124,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
if
(
getterDescriptor
.
getReceiverParameter
().
exists
())
{
index
++;
}
for
(
TypeParameterDescriptor
typeParameterDescriptor
:
getterDescriptor
.
getTypeParameters
())
{
if
(
typeParameterDescriptor
.
isReified
())
{
generateTypeInfo
(
resolvedGetCall
.
getTypeArguments
().
get
(
typeParameterDescriptor
));
index
++;
}
}
asmType
=
accessor
.
getSignature
().
getReturnType
();
}
else
{
...
...
@@ -2133,6 +2137,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
if
(
setterDescriptor
.
getReceiverParameter
().
exists
())
{
index
++;
}
for
(
TypeParameterDescriptor
typeParameterDescriptor
:
setterDescriptor
.
getOriginal
().
getTypeParameters
())
{
if
(
typeParameterDescriptor
.
isReified
())
{
generateTypeInfo
(
resolvedSetCall
.
getTypeArguments
().
get
(
typeParameterDescriptor
));
index
++;
}
}
asmType
=
argumentTypes
[
argumentTypes
.
length
-
1
];
}
...
...
@@ -2140,7 +2150,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
gen
(
jetExpression
,
argumentTypes
[
index
]);
index
++;
}
return
StackValue
.
collectionElement
(
asmType
,
getter
,
setter
,
myFrameMap
);
return
StackValue
.
collectionElement
(
asmType
,
resolvedGetCall
,
resolvedSetCall
,
this
);
}
}
...
...
compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java
浏览文件 @
aaed9b03
...
...
@@ -2,7 +2,12 @@ package org.jetbrains.jet.codegen;
import
com.intellij.psi.tree.IElementType
;
import
org.jetbrains.jet.lang.descriptors.ClassDescriptor
;
import
org.jetbrains.jet.lang.descriptors.FunctionDescriptor
;
import
org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
;
import
org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor
;
import
org.jetbrains.jet.lang.psi.JetExpression
;
import
org.jetbrains.jet.lang.resolve.calls.ResolvedCall
;
import
org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
;
import
org.jetbrains.jet.lexer.JetTokens
;
import
org.objectweb.asm.Label
;
import
org.objectweb.asm.Opcodes
;
...
...
@@ -10,6 +15,8 @@ import org.objectweb.asm.Type;
import
org.objectweb.asm.commons.InstructionAdapter
;
import
org.objectweb.asm.commons.Method
;
import
java.util.List
;
/**
* @author yole
* @author alex.tkachman
...
...
@@ -85,8 +92,8 @@ public abstract class StackValue {
return
new
ArrayElement
(
type
,
unbox
);
}
public
static
StackValue
collectionElement
(
Type
type
,
CallableMethod
getter
,
CallableMethod
setter
,
FrameMap
frame
)
{
return
new
CollectionElement
(
type
,
getter
,
setter
,
frame
);
public
static
StackValue
collectionElement
(
Type
type
,
ResolvedCall
<
FunctionDescriptor
>
getter
,
ResolvedCall
<
FunctionDescriptor
>
setter
,
ExpressionCodegen
codegen
)
{
return
new
CollectionElement
(
type
,
getter
,
setter
,
codegen
);
}
public
static
StackValue
field
(
Type
type
,
String
owner
,
String
name
,
boolean
isStatic
)
{
...
...
@@ -477,13 +484,23 @@ public abstract class StackValue {
private
static
class
CollectionElement
extends
StackValue
{
private
final
CallableMethod
getter
;
private
final
CallableMethod
setter
;
private
final
ExpressionCodegen
codegen
;
private
final
FrameMap
frame
;
private
final
ResolvedCall
<
FunctionDescriptor
>
resolvedGetCall
;
private
final
ResolvedCall
<
FunctionDescriptor
>
resolvedSetCall
;
private
final
FunctionDescriptor
setterDescriptor
;
private
final
FunctionDescriptor
getterDescriptor
;
public
CollectionElement
(
Type
type
,
CallableMethod
getter
,
CallableMethod
setter
,
FrameMap
frame
)
{
public
CollectionElement
(
Type
type
,
ResolvedCall
<
FunctionDescriptor
>
resolvedGetCall
,
ResolvedCall
<
FunctionDescriptor
>
resolvedSetCall
,
ExpressionCodegen
codegen
)
{
super
(
type
);
this
.
getter
=
getter
;
this
.
setter
=
setter
;
this
.
frame
=
frame
;
this
.
resolvedGetCall
=
resolvedGetCall
;
this
.
resolvedSetCall
=
resolvedSetCall
;
this
.
setterDescriptor
=
resolvedSetCall
==
null
?
null
:
resolvedSetCall
.
getResultingDescriptor
();
this
.
getterDescriptor
=
resolvedGetCall
==
null
?
null
:
resolvedGetCall
.
getResultingDescriptor
();
this
.
setter
=
resolvedSetCall
==
null
?
null
:
codegen
.
typeMapper
.
mapToCallableMethod
(
setterDescriptor
,
false
,
OwnerKind
.
IMPLEMENTATION
);
this
.
getter
=
resolvedGetCall
==
null
?
null
:
codegen
.
typeMapper
.
mapToCallableMethod
(
getterDescriptor
,
false
,
OwnerKind
.
IMPLEMENTATION
);
this
.
codegen
=
codegen
;
this
.
frame
=
codegen
.
myFrameMap
;
}
@Override
...
...
@@ -505,69 +522,164 @@ public abstract class StackValue {
@Override
public
void
dupReceiver
(
InstructionAdapter
v
)
{
int
size
=
calcSize
();
if
(
size
==
2
)
{
if
(
isStandardStack
(
resolvedGetCall
)
&&
isStandardStack
(
resolvedSetCall
))
{
v
.
dup2
();
// collection and index
}
else
{
Method
signature
=
getter
.
getSignature
();
Type
[]
argumentTypes
=
signature
.
getArgumentTypes
();
int
firstIndex
=
frame
.
enterTemp
();
int
lastIndex
=
firstIndex
;
int
size
=
0
;
int
lastIndex
=
frame
.
enterTemp
();
frame
.
leaveTemp
();
for
(
int
i
=
argumentTypes
.
length
-
1
;
i
>=
0
;
i
--)
{
int
sz
=
argumentTypes
[
i
].
getSize
();
// indexes
List
<
ValueParameterDescriptor
>
valueParameters
=
resolvedGetCall
.
getResultingDescriptor
().
getValueParameters
();
int
firstParamIndex
=
-
1
;
for
(
int
i
=
valueParameters
.
size
()-
1
;
i
>=
0
;
--
i
)
{
Type
type
=
codegen
.
typeMapper
.
mapType
(
valueParameters
.
get
(
i
).
getOutType
());
int
sz
=
type
.
getSize
();
frame
.
enterTemp
(
sz
);
lastIndex
+=
sz
;
size
+=
sz
;
v
.
store
((
firstParamIndex
=
lastIndex
)-
sz
,
type
);
}
List
<
TypeParameterDescriptor
>
typeParameters
=
resolvedGetCall
.
getResultingDescriptor
().
getTypeParameters
();
int
firstTypeParamIndex
=
-
1
;
for
(
int
i
=
typeParameters
.
size
()-
1
;
i
>=
0
;
--
i
)
{
if
(
typeParameters
.
get
(
i
).
isReified
())
{
frame
.
enterTemp
();
lastIndex
++;
size
++;
v
.
store
(
firstTypeParamIndex
=
lastIndex
-
1
,
JetTypeMapper
.
TYPE_OBJECT
);
}
}
ReceiverDescriptor
receiverParameter
=
resolvedGetCall
.
getReceiverArgument
();
int
receiverIndex
=
-
1
;
if
(
receiverParameter
.
exists
())
{
Type
type
=
codegen
.
typeMapper
.
mapType
(
receiverParameter
.
getType
());
int
sz
=
type
.
getSize
();
frame
.
enterTemp
(
sz
);
lastIndex
+=
sz
;
v
.
store
(
lastIndex
-
sz
,
argumentTypes
[
i
]);
size
+=
sz
;
v
.
store
((
receiverIndex
=
lastIndex
)-
sz
,
type
);
}
if
(
getter
.
getInvokeOpcode
()
!=
Opcodes
.
INVOKESTATIC
)
{
ReceiverDescriptor
thisObject
=
resolvedGetCall
.
getThisObject
();
int
thisIndex
=
-
1
;
if
(
thisObject
.
exists
())
{
frame
.
enterTemp
();
lastIndex
++;
v
.
store
(
lastIndex
-
1
,
JetTypeMapper
.
TYPE_OBJECT
);
size
++;
v
.
store
((
thisIndex
=
lastIndex
)-
1
,
JetTypeMapper
.
TYPE_OBJECT
);
}
// for setter
int
realReceiverIndex
;
Type
realReceiverType
;
if
(
thisIndex
!=
-
1
)
{
if
(
receiverIndex
!=
-
1
)
{
realReceiverIndex
=
receiverIndex
;
realReceiverType
=
codegen
.
typeMapper
.
mapType
(
receiverParameter
.
getType
());
}
else
{
realReceiverIndex
=
thisIndex
;
realReceiverType
=
JetTypeMapper
.
TYPE_OBJECT
;
}
}
else
{
if
(
receiverIndex
!=
-
1
)
{
realReceiverType
=
codegen
.
typeMapper
.
mapType
(
receiverParameter
.
getType
());
realReceiverIndex
=
receiverIndex
;
}
else
{
throw
new
UnsupportedOperationException
();
}
}
firstIndex
=
lastIndex
;
int
curIndex
=
lastIndex
;
if
(
getter
.
getInvokeOpcode
()
!=
Opcodes
.
INVOKESTATIC
)
{
v
.
load
(
curIndex
-
1
,
JetTypeMapper
.
TYPE_OBJECT
);
curIndex
--;
if
(
resolvedSetCall
.
getThisObject
().
exists
())
{
if
(
resolvedSetCall
.
getReceiverArgument
().
exists
())
{
codegen
.
generateFromResolvedCall
(
resolvedSetCall
.
getThisObject
());
}
v
.
load
(
realReceiverIndex
-
realReceiverType
.
getSize
(),
realReceiverType
);
}
else
{
if
(
resolvedSetCall
.
getReceiverArgument
().
exists
())
{
v
.
load
(
realReceiverIndex
-
realReceiverType
.
getSize
(),
realReceiverType
);
}
else
{
throw
new
UnsupportedOperationException
();
}
}
for
(
TypeParameterDescriptor
typeParameterDescriptor
:
setterDescriptor
.
getOriginal
().
getTypeParameters
())
{
if
(
typeParameterDescriptor
.
isReified
())
{
codegen
.
generateTypeInfo
(
resolvedSetCall
.
getTypeArguments
().
get
(
typeParameterDescriptor
));
}
}
for
(
int
i
=
0
;
i
!=
argumentTypes
.
length
;
i
++)
{
int
sz
=
argumentTypes
[
i
].
getSize
();
v
.
load
(
curIndex
-
sz
,
argumentTypes
[
i
]);
curIndex
-=
sz
;
int
index
=
firstParamIndex
;
for
(
int
i
=
0
;
i
!=
valueParameters
.
size
();
++
i
)
{
Type
type
=
codegen
.
typeMapper
.
mapType
(
valueParameters
.
get
(
i
).
getOutType
());
int
sz
=
type
.
getSize
();
v
.
load
(
index
-
sz
,
type
);
index
-=
sz
;
}
curIndex
=
firstIndex
;
if
(
getter
.
getInvokeOpcode
()
!=
Opcodes
.
INVOKESTATIC
)
{
v
.
load
(
curIndex
-
1
,
JetTypeMapper
.
TYPE_OBJECT
);
curIndex
--;
// restoring original
if
(
thisIndex
!=
-
1
)
{
v
.
load
(
thisIndex
-
1
,
JetTypeMapper
.
TYPE_OBJECT
);
}
if
(
receiverIndex
!=
-
1
)
{
Type
type
=
codegen
.
typeMapper
.
mapType
(
receiverParameter
.
getType
());
v
.
load
(
receiverIndex
-
type
.
getSize
(),
type
);
}
for
(
int
i
=
0
;
i
!=
argumentTypes
.
length
;
i
++)
{
int
sz
=
argumentTypes
[
i
].
getSize
();
v
.
load
(
curIndex
-
sz
,
argumentTypes
[
i
]);
curIndex
-=
sz
;
if
(
firstTypeParamIndex
!=
-
1
)
{
index
=
firstTypeParamIndex
;
for
(
int
i
=
0
;
i
!=
typeParameters
.
size
();
++
i
)
{
if
(
typeParameters
.
get
(
i
).
isReified
())
{
v
.
load
(
index
-
1
,
JetTypeMapper
.
TYPE_OBJECT
);
index
--;
}
}
}
index
=
firstParamIndex
;
for
(
int
i
=
0
;
i
!=
valueParameters
.
size
();
++
i
)
{
Type
type
=
codegen
.
typeMapper
.
mapType
(
valueParameters
.
get
(
i
).
getOutType
());
int
sz
=
type
.
getSize
();
v
.
load
(
index
-
sz
,
type
);
index
-=
sz
;
}
frame
.
leaveTemp
(
size
);
}
}
private
int
calcSize
()
{
assert
getter
!=
null
;
int
size
=
getter
.
getInvokeOpcode
()
==
Opcodes
.
INVOKESTATIC
?
0
:
1
;
Method
signature
=
getter
.
getSignature
();
Type
[]
argumentTypes
=
signature
.
getArgumentTypes
();
for
(
int
i
=
0
;
i
!=
argumentTypes
.
length
;
++
i
)
size
+=
argumentTypes
[
i
].
getSize
();
return
size
;
private
boolean
isStandardStack
(
ResolvedCall
call
)
{
for
(
TypeParameterDescriptor
typeParameterDescriptor
:
call
.
getResultingDescriptor
().
getTypeParameters
())
{
if
(
typeParameterDescriptor
.
isReified
())
return
false
;
}
if
(
call
.
getResultingDescriptor
().
getValueParameters
().
size
()
!=
1
)
return
false
;
if
(
codegen
.
typeMapper
.
mapType
(
call
.
getResultingDescriptor
().
getValueParameters
().
get
(
0
).
getOutType
()).
getSize
()
!=
1
)
return
false
;
if
(
call
.
getThisObject
().
exists
())
{
if
(
call
.
getReceiverArgument
().
exists
())
return
false
;
}
else
{
if
(
codegen
.
typeMapper
.
mapType
(
call
.
getResultingDescriptor
().
getReceiverParameter
().
getType
()).
getSize
()
!=
1
)
return
false
;
}
return
true
;
}
}
...
...
compiler/testData/codegen/regressions/kt504.jet
0 → 100644
浏览文件 @
aaed9b03
import java.util.HashMap
import java.util.Map
import java.io.*
fun <K, V> Map<K, V>.set(key : K, value : V) = put(key, value)
fun box() : String {
val commands : Map<String, String> = HashMap()
commands["c1"] = "239"
if(commands["c1"] != "239") return "fail"
commands["c1"] += "932"
return if(commands["c1"] == "239932") "OK" else "fail"
}
compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java
浏览文件 @
aaed9b03
...
...
@@ -202,4 +202,10 @@ public class ClassGenTest extends CodegenTestCase {
System
.
out
.
println
(
generateToText
());
blackBox
();
}
public
void
testKt504
()
throws
Exception
{
loadFile
(
"regressions/kt504.jet"
);
System
.
out
.
println
(
generateToText
());
blackBox
();
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录