Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
硅谷海盗
kotlin
提交
20520e99
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,发现更多精彩内容 >>
提交
20520e99
编写于
4月 14, 2011
作者:
D
Dmitry Jemerov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
generate calls to functions in a Jet namespace
上级
91b613e8
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
89 addition
and
38 deletion
+89
-38
idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
+41
-20
idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java
idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java
+4
-18
idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java
idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java
+25
-0
idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java
idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java
+3
-0
idea/testData/codegen/functionCall.jet
idea/testData/codegen/functionCall.jet
+9
-0
idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java
idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java
+7
-0
未找到文件。
idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
浏览文件 @
20520e99
...
...
@@ -7,11 +7,13 @@ import org.jetbrains.jet.lang.psi.*;
import
org.jetbrains.jet.lang.resolve.BindingContext
;
import
org.jetbrains.jet.lang.types.*
;
import
org.jetbrains.jet.lexer.JetTokens
;
import
org.jetbrains.jet.resolve.DescriptorUtil
;
import
org.objectweb.asm.Label
;
import
org.objectweb.asm.MethodVisitor
;
import
org.objectweb.asm.Opcodes
;
import
org.objectweb.asm.Type
;
import
org.objectweb.asm.commons.InstructionAdapter
;
import
org.objectweb.asm.commons.Method
;
import
java.util.List
;
import
java.util.Stack
;
...
...
@@ -324,7 +326,8 @@ public class ExpressionCodegen extends JetVisitor {
if
(
callee
instanceof
JetSimpleNameExpression
)
{
DeclarationDescriptor
funDescriptor
=
bindingContext
.
resolveReferenceExpression
((
JetSimpleNameExpression
)
callee
);
if
(
funDescriptor
instanceof
FunctionDescriptor
)
{
if
(
isNumberPrimitive
(
funDescriptor
.
getContainingDeclaration
()))
{
final
DeclarationDescriptor
functionParent
=
funDescriptor
.
getContainingDeclaration
();
if
(
isNumberPrimitive
(
functionParent
))
{
if
(
funDescriptor
.
getName
().
equals
(
"inv"
))
{
final
StackValue
value
=
myStack
.
pop
();
// HACK we rely on the dot reference handler to put it on the stack
final
Type
asmType
=
expressionType
(
expression
);
...
...
@@ -333,23 +336,41 @@ public class ExpressionCodegen extends JetVisitor {
return
;
}
}
if
(
expression
.
getParent
()
instanceof
JetDotQualifiedExpression
)
{
final
JetDotQualifiedExpression
parent
=
(
JetDotQualifiedExpression
)
expression
.
getParent
();
if
(!
resolvesToClassOrPackage
(
parent
.
getReceiverExpression
()))
{
// we have a receiver on stack
myStack
.
pop
().
put
(
Type
.
getObjectType
(
"java/lang/Object"
),
v
);
}
}
PsiElement
declarationPsiElement
=
bindingContext
.
getDeclarationPsiElement
(
funDescriptor
);
Method
methodDescriptor
;
if
(
declarationPsiElement
instanceof
PsiMethod
)
{
PsiMethod
method
=
(
PsiMethod
)
declarationPsiElement
;
pushMethodArguments
(
expression
,
method
);
PsiMethod
psiMethod
=
(
PsiMethod
)
declarationPsiElement
;
methodDescriptor
=
getMethodDescriptor
(
psiMethod
);
pushMethodArguments
(
expression
,
methodDescriptor
);
final
boolean
isStatic
=
m
ethod
.
hasModifierProperty
(
PsiModifier
.
STATIC
);
final
boolean
isStatic
=
psiM
ethod
.
hasModifierProperty
(
PsiModifier
.
STATIC
);
v
.
visitMethodInsn
(
isStatic
?
Opcodes
.
INVOKESTATIC
:
Opcodes
.
INVOKEVIRTUAL
,
JetTypeMapper
.
jvmName
(
method
.
getContainingClass
()),
method
.
getName
(),
getMethodDescriptor
(
method
));
final
Type
type
=
psiTypeToAsm
(
method
.
getReturnType
());
if
(
type
!=
Type
.
VOID_TYPE
)
{
myStack
.
push
(
StackValue
.
onStack
(
type
));
}
JetTypeMapper
.
jvmName
(
psiMethod
.
getContainingClass
()),
methodDescriptor
.
getName
(),
methodDescriptor
.
getDescriptor
());
}
else
{
throw
new
UnsupportedOperationException
(
"don't know how to generate call to "
+
declarationPsiElement
);
if
(
functionParent
instanceof
NamespaceDescriptor
&&
declarationPsiElement
instanceof
JetFunction
)
{
methodDescriptor
=
typeMapper
.
mapSignature
((
JetFunction
)
declarationPsiElement
);
pushMethodArguments
(
expression
,
methodDescriptor
);
final
String
owner
=
NamespaceCodegen
.
getJVMClassName
(
DescriptorUtil
.
getFQName
(
functionParent
));
v
.
invokestatic
(
owner
,
methodDescriptor
.
getName
(),
methodDescriptor
.
getDescriptor
());
}
else
{
throw
new
UnsupportedOperationException
(
"don't know how to generate call to "
+
declarationPsiElement
);
}
}
if
(
methodDescriptor
.
getReturnType
()
!=
Type
.
VOID_TYPE
)
{
myStack
.
push
(
StackValue
.
onStack
(
methodDescriptor
.
getReturnType
()));
}
}
else
{
...
...
@@ -361,24 +382,23 @@ public class ExpressionCodegen extends JetVisitor {
}
}
private
void
pushMethodArguments
(
JetCall
expression
,
PsiMethod
method
)
{
PsiParameter
[]
parameters
=
method
.
getParameterList
().
getParameters
();
private
void
pushMethodArguments
(
JetCall
expression
,
Method
method
)
{
final
Type
[]
argTypes
=
method
.
getArgumentTypes
();
List
<
JetArgument
>
args
=
expression
.
getValueArguments
();
for
(
int
i
=
0
,
argsSize
=
args
.
size
();
i
<
argsSize
;
i
++)
{
JetArgument
arg
=
args
.
get
(
i
);
gen
(
arg
.
getArgumentExpression
(),
psiTypeToAsm
(
parameters
[
i
].
getType
())
);
gen
(
arg
.
getArgumentExpression
(),
argTypes
[
i
]
);
}
}
private
static
String
getMethodDescriptor
(
PsiMethod
method
)
{
private
static
Method
getMethodDescriptor
(
PsiMethod
method
)
{
Type
returnType
=
method
.
isConstructor
()
?
Type
.
VOID_TYPE
:
psiTypeToAsm
(
method
.
getReturnType
());
PsiParameter
[]
parameters
=
method
.
getParameterList
().
getParameters
();
Type
[]
parameterTypes
=
new
Type
[
parameters
.
length
];
for
(
int
i
=
0
;
i
<
parameters
.
length
;
i
++)
{
parameterTypes
[
i
]
=
psiTypeToAsm
(
parameters
[
i
].
getType
());
}
return
Type
.
getMethodDescriptor
(
returnType
,
parameterTypes
);
return
new
Method
(
method
.
getName
(),
Type
.
getMethodDescriptor
(
returnType
,
parameterTypes
)
);
}
private
Type
expressionType
(
JetExpression
expr
)
{
...
...
@@ -798,8 +818,9 @@ public class ExpressionCodegen extends JetVisitor {
Type
type
=
JetTypeMapper
.
psiClassType
(
javaClass
);
v
.
anew
(
type
);
v
.
dup
();
pushMethodArguments
(
expression
,
constructor
);
v
.
invokespecial
(
JetTypeMapper
.
jvmName
(
javaClass
),
"<init>"
,
getMethodDescriptor
(
constructor
));
final
Method
constructorDescriptor
=
getMethodDescriptor
(
constructor
);
pushMethodArguments
(
expression
,
constructorDescriptor
);
v
.
invokespecial
(
JetTypeMapper
.
jvmName
(
javaClass
),
"<init>"
,
constructorDescriptor
.
getDescriptor
());
myStack
.
push
(
StackValue
.
onStack
(
type
));
return
;
}
...
...
idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java
浏览文件 @
20520e99
...
...
@@ -36,22 +36,7 @@ public class FunctionCodegen {
}
private
void
gen
(
JetFunction
f
)
{
final
List
<
JetParameter
>
parameters
=
f
.
getValueParameters
();
Type
[]
parameterTypes
=
new
Type
[
parameters
.
size
()];
for
(
int
i
=
0
;
i
<
parameters
.
size
();
i
++)
{
parameterTypes
[
i
]
=
typeMapper
.
mapType
(
bindingContext
.
resolveTypeReference
(
parameters
.
get
(
i
).
getTypeReference
()));
}
final
JetTypeReference
returnTypeRef
=
f
.
getReturnTypeRef
();
Type
returnType
;
if
(
returnTypeRef
==
null
)
{
final
FunctionDescriptor
functionDescriptor
=
bindingContext
.
getFunctionDescriptor
(
f
);
final
JetType
type
=
functionDescriptor
.
getUnsubstitutedReturnType
();
returnType
=
typeMapper
.
mapType
(
type
);
}
else
{
returnType
=
typeMapper
.
mapType
(
bindingContext
.
resolveTypeReference
(
returnTypeRef
));
}
Method
method
=
new
Method
(
f
.
getName
(),
returnType
,
parameterTypes
);
Method
method
=
typeMapper
.
mapSignature
(
f
);
final
MethodVisitor
mv
=
v
.
visitMethod
(
Opcodes
.
ACC_PUBLIC
|
Opcodes
.
ACC_STATIC
,
method
.
getName
(),
method
.
getDescriptor
(),
null
,
null
);
mv
.
visitCode
();
...
...
@@ -60,12 +45,13 @@ public class FunctionCodegen {
List
<
ValueParameterDescriptor
>
parameDescrs
=
bindingContext
.
getFunctionDescriptor
(
f
).
getUnsubstitutedValueParameters
();
Type
[]
argTypes
=
method
.
getArgumentTypes
();
for
(
int
i
=
0
;
i
<
parameDescrs
.
size
();
i
++)
{
ValueParameterDescriptor
parameter
=
parameDescrs
.
get
(
i
);
frameMap
.
enter
(
parameter
,
parameter
Types
[
i
].
getSize
());
frameMap
.
enter
(
parameter
,
arg
Types
[
i
].
getSize
());
}
ExpressionCodegen
codegen
=
new
ExpressionCodegen
(
mv
,
bindingContext
,
frameMap
,
typeMapper
,
returnType
);
ExpressionCodegen
codegen
=
new
ExpressionCodegen
(
mv
,
bindingContext
,
frameMap
,
typeMapper
,
method
.
getReturnType
()
);
bodyExpression
.
accept
(
codegen
);
generateReturn
(
mv
,
bodyExpression
,
codegen
);
mv
.
visitMaxs
(
0
,
0
);
...
...
idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java
浏览文件 @
20520e99
...
...
@@ -2,9 +2,15 @@ package org.jetbrains.jet.codegen;
import
com.intellij.psi.PsiClass
;
import
com.intellij.psi.PsiElement
;
import
org.jetbrains.jet.lang.psi.JetFunction
;
import
org.jetbrains.jet.lang.psi.JetParameter
;
import
org.jetbrains.jet.lang.psi.JetTypeReference
;
import
org.jetbrains.jet.lang.resolve.BindingContext
;
import
org.jetbrains.jet.lang.types.*
;
import
org.objectweb.asm.Type
;
import
org.objectweb.asm.commons.Method
;
import
java.util.List
;
/**
* @author yole
...
...
@@ -105,4 +111,23 @@ public class JetTypeMapper {
throw
new
UnsupportedOperationException
(
"Unknown type "
+
jetType
);
}
public
Method
mapSignature
(
JetFunction
f
)
{
final
List
<
JetParameter
>
parameters
=
f
.
getValueParameters
();
Type
[]
parameterTypes
=
new
Type
[
parameters
.
size
()];
for
(
int
i
=
0
;
i
<
parameters
.
size
();
i
++)
{
parameterTypes
[
i
]
=
mapType
(
bindingContext
.
resolveTypeReference
(
parameters
.
get
(
i
).
getTypeReference
()));
}
final
JetTypeReference
returnTypeRef
=
f
.
getReturnTypeRef
();
Type
returnType
;
if
(
returnTypeRef
==
null
)
{
final
FunctionDescriptor
functionDescriptor
=
bindingContext
.
getFunctionDescriptor
(
f
);
final
JetType
type
=
functionDescriptor
.
getUnsubstitutedReturnType
();
returnType
=
mapType
(
type
);
}
else
{
returnType
=
mapType
(
bindingContext
.
resolveTypeReference
(
returnTypeRef
));
}
return
new
Method
(
f
.
getName
(),
returnType
,
parameterTypes
);
}
}
idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java
浏览文件 @
20520e99
...
...
@@ -54,6 +54,9 @@ public class NamespaceCodegen {
}
public
static
String
getJVMClassName
(
String
fqName
)
{
if
(
fqName
.
length
()
==
0
)
{
return
"namespace"
;
}
return
fqName
.
replace
(
'.'
,
'/'
)
+
"/namespace"
;
}
...
...
idea/testData/codegen/functionCall.jet
0 → 100644
浏览文件 @
20520e99
fun f() {
val x = new StringBuilder();
g(x);
return x.toString();
}
fun g(sb: StringBuilder): Unit {
sb.append("foo");
}
idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java
浏览文件 @
20520e99
...
...
@@ -530,6 +530,13 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
assertEquals
(
Boolean
.
FALSE
,
main
.
invoke
(
null
,
null
,
"jet"
));
}
public
void
testFunctionCall
()
throws
Exception
{
loadFile
(
"functionCall.jet"
);
System
.
out
.
println
(
generateToText
());
final
Method
main
=
generateFunction
();
assertEquals
(
"foo"
,
main
.
invoke
(
null
));
}
private
void
binOpTest
(
final
String
text
,
final
Object
arg1
,
final
Object
arg2
,
final
Object
expected
)
throws
Exception
{
loadText
(
text
);
System
.
out
.
println
(
generateToText
());
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录