Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
硅谷海盗
kotlin
提交
cfc41361
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,发现更多精彩内容 >>
提交
cfc41361
编写于
11月 08, 2011
作者:
A
Alex Tkachman
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
expressions as functions
上级
30e44b16
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
268 addition
and
140 deletion
+268
-140
compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java
...backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java
+34
-18
compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java
...backend/src/org/jetbrains/jet/codegen/CodegenContext.java
+27
-28
compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java
...er/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java
+22
-4
compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
...kend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
+71
-22
compiler/backend/src/org/jetbrains/jet/codegen/GeneratedAnonymousClassDescriptor.java
...brains/jet/codegen/GeneratedAnonymousClassDescriptor.java
+8
-1
compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java
...ackend/src/org/jetbrains/jet/codegen/GenerationState.java
+1
-1
compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java
...src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java
+36
-12
compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java
...ler/backend/src/org/jetbrains/jet/codegen/StackValue.java
+9
-3
compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java
...rc/org/jetbrains/jet/lang/resolve/calls/CallResolver.java
+1
-1
compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ExpressionAsFunctionDescriptor.java
...et/lang/resolve/calls/ExpressionAsFunctionDescriptor.java
+21
-0
compiler/testData/codegen/functions/functionExpression.jet
compiler/testData/codegen/functions/functionExpression.jet
+25
-0
compiler/testData/codegen/functions/withtypeparams.jet
compiler/testData/codegen/functions/withtypeparams.jet
+10
-0
compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java
...iler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java
+2
-49
stdlib/src/jet/DefaultJetObject.java
stdlib/src/jet/DefaultJetObject.java
+1
-1
未找到文件。
compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java
浏览文件 @
cfc41361
...
...
@@ -85,7 +85,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
final
Type
enclosingType
=
thisDescriptor
==
null
?
null
:
Type
.
getObjectType
(
thisDescriptor
.
getName
());
if
(
enclosingType
==
null
)
captureThis
=
false
;
final
Method
constructor
=
generateConstructor
(
funClass
,
captureThis
,
fun
,
funDescriptor
.
getReturnType
()
);
final
Method
constructor
=
generateConstructor
(
funClass
,
fun
);
if
(
captureThis
)
{
cv
.
newField
(
fun
,
0
,
"this$0"
,
enclosingType
.
getDescriptor
(),
null
,
null
);
...
...
@@ -97,10 +97,12 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
cv
.
done
();
final
GeneratedAnonymousClassDescriptor
answer
=
new
GeneratedAnonymousClassDescriptor
(
name
,
constructor
,
captureThis
);
final
GeneratedAnonymousClassDescriptor
answer
=
new
GeneratedAnonymousClassDescriptor
(
name
,
constructor
,
captureThis
,
captureReceiver
);
for
(
DeclarationDescriptor
descriptor
:
closure
.
keySet
())
{
final
EnclosedValueDescriptor
valueDescriptor
=
closure
.
get
(
descriptor
);
answer
.
addArg
(
valueDescriptor
.
getOuterValue
());
if
(
descriptor
instanceof
VariableDescriptor
)
{
final
EnclosedValueDescriptor
valueDescriptor
=
closure
.
get
(
descriptor
);
answer
.
addArg
(
valueDescriptor
.
getOuterValue
());
}
}
return
answer
;
}
...
...
@@ -144,7 +146,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
final
CodegenContext
.
ClosureContext
closureContext
=
context
.
intoClosure
(
funDescriptor
,
function
,
name
,
this
);
FunctionCodegen
fc
=
new
FunctionCodegen
(
closureContext
,
cv
,
state
);
fc
.
generateMethod
(
body
,
invokeSignature
(
funDescriptor
),
funDescriptor
);
return
closureContext
.
isOuterWasUsed
()
;
return
closureContext
.
outerWasUsed
;
}
private
void
generateBridge
(
String
className
,
FunctionDescriptor
funDescriptor
,
JetFunctionLiteralExpression
fun
,
ClassBuilder
cv
)
{
...
...
@@ -185,26 +187,36 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
mv
.
visitEnd
();
}
private
Method
generateConstructor
(
String
funClass
,
boolean
captureThis
,
JetFunctionLiteralExpression
fun
,
JetType
returnType
)
{
int
argCount
=
c
losure
.
size
()
;
private
Method
generateConstructor
(
String
funClass
,
JetFunctionLiteralExpression
fun
)
{
int
argCount
=
c
aptureThis
?
1
:
0
;
if
(
captureThis
)
{
argCount
++;
for
(
DeclarationDescriptor
descriptor
:
closure
.
keySet
())
{
if
(
descriptor
instanceof
VariableDescriptor
)
{
argCount
++;
}
else
if
(
descriptor
instanceof
FunctionDescriptor
)
{
captureReceiver
=
state
.
getTypeMapper
().
mapType
(((
FunctionDescriptor
)
descriptor
).
getReceiverParameter
().
getType
());
argCount
++;
}
}
Type
[]
argTypes
=
new
Type
[
argCount
];
int
i
=
0
;
if
(
captureThis
)
{
i
=
1
;
argTypes
[
0
]
=
Type
.
getObjectType
(
context
.
getThisDescriptor
().
getName
());
argTypes
[
i
++]
=
Type
.
getObjectType
(
context
.
getThisDescriptor
().
getName
());
}
if
(
captureReceiver
!=
null
)
{
argTypes
[
i
++]
=
captureReceiver
;
}
for
(
DeclarationDescriptor
descriptor
:
closure
.
keySet
())
{
final
Type
sharedVarType
=
exprContext
.
getSharedVarType
(
descriptor
);
final
Type
type
=
sharedVarType
!=
null
?
sharedVarType
:
state
.
getTypeMapper
().
mapType
(((
VariableDescriptor
)
descriptor
).
getOutType
());
argTypes
[
i
++]
=
type
;
if
(
descriptor
instanceof
VariableDescriptor
)
{
final
Type
sharedVarType
=
exprContext
.
getSharedVarType
(
descriptor
);
final
Type
type
=
sharedVarType
!=
null
?
sharedVarType
:
state
.
getTypeMapper
().
mapType
(((
VariableDescriptor
)
descriptor
).
getOutType
());
argTypes
[
i
++]
=
type
;
}
}
final
Method
constructor
=
new
Method
(
"<init>"
,
Type
.
VOID_TYPE
,
argTypes
);
...
...
@@ -225,11 +237,15 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
final
String
fieldName
;
if
(
captureThis
&&
i
==
1
)
{
fieldName
=
"this$0"
;
captureThis
=
false
;
}
else
{
fieldName
=
"$"
+
(
i
);
i
++;
if
(
captureReceiver
!=
null
&&
(
captureThis
&&
i
==
2
||
!
captureThis
&&
i
==
1
))
{
fieldName
=
"receiver$0"
;
}
else
{
fieldName
=
"$"
+
(
i
);
i
++;
}
}
StackValue
.
field
(
type
,
name
,
fieldName
,
false
).
store
(
iv
);
...
...
compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java
浏览文件 @
cfc41361
...
...
@@ -36,14 +36,9 @@ public abstract class CodegenContext {
HashMap
<
JetType
,
Integer
>
typeInfoConstants
;
HashMap
<
DeclarationDescriptor
,
DeclarationDescriptor
>
accessors
;
protected
DeclarationDescriptor
outerDescriptor
;
protected
DeclarationDescriptor
outerReceiverDescriptor
;
protected
StackValue
outerExpression
;
protected
StackValue
outerReceiverExpression
;
protected
boolean
outerWasUsed
=
false
;
protected
boolean
outerWasUsed
;
public
CodegenContext
(
DeclarationDescriptor
contextType
,
OwnerKind
contextKind
,
@Nullable
CodegenContext
parentContext
,
@Nullable
ObjectOrClosureCodegen
closureCodegen
)
{
this
.
contextType
=
contextType
;
...
...
@@ -54,7 +49,7 @@ public abstract class CodegenContext {
protected
abstract
ClassDescriptor
getThisDescriptor
();
protected
Declara
tionDescriptor
getReceiverDescriptor
()
{
protected
Func
tionDescriptor
getReceiverDescriptor
()
{
return
null
;
}
...
...
@@ -139,16 +134,18 @@ public abstract class CodegenContext {
}
}
public
StackValue
lookupInContext
(
DeclarationDescriptor
d
,
InstructionAdapter
v
)
{
public
StackValue
lookupInContext
(
DeclarationDescriptor
d
,
InstructionAdapter
v
,
StackValue
result
)
{
final
ObjectOrClosureCodegen
top
=
closure
;
if
(
top
!=
null
)
{
final
StackValue
answer
=
top
.
lookupInContext
(
d
);
if
(
answer
!=
null
)
return
answer
;
final
StackValue
answer
=
top
.
lookupInContext
(
d
,
result
);
if
(
answer
!=
null
)
return
result
==
null
?
answer
:
StackValue
.
composed
(
result
,
answer
);
getOuterExpression
(
null
).
put
(
JetTypeMapper
.
TYPE_OBJECT
,
v
);
StackValue
outer
=
getOuterExpression
(
null
);
result
=
result
==
null
?
outer
:
StackValue
.
composed
(
result
,
outer
);
}
return
parentContext
!=
null
?
parentContext
.
lookupInContext
(
d
,
v
)
:
null
;
return
parentContext
!=
null
?
parentContext
.
lookupInContext
(
d
,
v
,
result
)
:
null
;
}
public
Type
enclosingClassType
()
{
...
...
@@ -229,32 +226,34 @@ public abstract class CodegenContext {
return
accessor
;
}
public
boolean
isOuterWasUsed
()
{
return
outerWasUsed
;
}
public
StackValue
getReceiverExpression
()
{
public
StackValue
getReceiverExpression
(
JetTypeMapper
typeMapper
)
{
assert
getReceiverDescriptor
()
!=
null
;
return
getThisDescriptor
()
!=
null
?
local1
:
local0
;
}
public
StackValue
getThisExpression
()
{
assert
getThisDescriptor
()
!=
null
;
return
local0
;
Type
asmType
=
typeMapper
.
mapType
(
getReceiverDescriptor
().
getReceiverParameter
().
getType
());
return
getThisDescriptor
()
!=
null
?
StackValue
.
local
(
1
,
asmType
)
:
StackValue
.
local
(
0
,
asmType
);
}
public
abstract
static
class
FunctionContext
extends
CodegenContext
{
final
Declara
tionDescriptor
receiverDescriptor
;
final
Func
tionDescriptor
receiverDescriptor
;
public
FunctionContext
(
FunctionDescriptor
contextType
,
OwnerKind
contextKind
,
CodegenContext
parentContext
,
@Nullable
ObjectOrClosureCodegen
closureCodegen
)
{
super
(
contextType
,
contextKind
,
parentContext
,
closureCodegen
);
receiverDescriptor
=
contextType
.
getReceiverParameter
().
exists
()
?
contextType
.
getReceiverParameter
().
getType
().
getConstructor
().
getDeclarationDescriptor
()
:
null
;
receiverDescriptor
=
contextType
.
getReceiverParameter
().
exists
()
?
contextType
:
null
;
}
@Override
protected
Declara
tionDescriptor
getReceiverDescriptor
()
{
protected
Func
tionDescriptor
getReceiverDescriptor
()
{
return
receiverDescriptor
;
}
public
FunctionContext
getOuterFunction
()
{
CodegenContext
c
=
getParentContext
();
while
(
c
!=
null
)
{
if
(
c
instanceof
FunctionContext
)
return
(
FunctionContext
)
c
;
c
=
c
.
getParentContext
();
}
return
null
;
}
}
public
static
class
MethodContext
extends
FunctionContext
{
...
...
@@ -267,8 +266,8 @@ public abstract class CodegenContext {
return
getParentContext
().
getThisDescriptor
();
}
public
StackValue
lookupInContext
(
DeclarationDescriptor
d
,
InstructionAdapter
v
)
{
return
getParentContext
().
lookupInContext
(
d
,
v
);
public
StackValue
lookupInContext
(
DeclarationDescriptor
d
,
InstructionAdapter
v
,
StackValue
result
)
{
return
getParentContext
().
lookupInContext
(
d
,
v
,
result
);
}
public
Type
enclosingClassType
()
{
...
...
compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java
浏览文件 @
cfc41361
package
org.jetbrains.jet.codegen
;
import
com.intellij.psi.util.PsiTreeUtil
;
import
org.jetbrains.jet.lang.descriptors.ClassDescriptor
;
import
org.jetbrains.jet.lang.descriptors.ClassKind
;
import
org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
;
import
org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
;
import
org.jetbrains.jet.lang.descriptors.*
;
import
org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
;
import
org.jetbrains.jet.lang.psi.JetClass
;
import
org.jetbrains.jet.lang.psi.JetNamedDeclaration
;
import
org.jetbrains.jet.lang.psi.JetNamespace
;
import
org.jetbrains.jet.lang.resolve.calls.ExpressionAsFunctionDescriptor
;
import
org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
;
import
org.jetbrains.jet.lang.types.JetStandardClasses
;
import
org.jetbrains.jet.lang.types.JetType
;
import
java.util.Collections
;
import
java.util.List
;
/**
...
...
@@ -124,4 +126,20 @@ public class CodegenUtil {
}
return
jetClass
.
getName
();
}
public
static
FunctionDescriptor
createInvoke
(
ExpressionAsFunctionDescriptor
fd
)
{
int
arity
=
fd
.
getValueParameters
().
size
();
FunctionDescriptorImpl
invokeDescriptor
=
new
FunctionDescriptorImpl
(
fd
.
getExpectedThisObject
().
exists
()
?
JetStandardClasses
.
getReceiverFunction
(
arity
)
:
JetStandardClasses
.
getFunction
(
arity
),
Collections
.<
AnnotationDescriptor
>
emptyList
(),
"invoke"
);
invokeDescriptor
.
initialize
(
fd
.
getReceiverParameter
().
exists
()
?
fd
.
getReceiverParameter
().
getType
()
:
null
,
fd
.
getExpectedThisObject
(),
Collections
.<
TypeParameterDescriptor
>
emptyList
(),
fd
.
getValueParameters
(),
fd
.
getReturnType
(),
Modality
.
FINAL
,
Visibility
.
PUBLIC
);
return
invokeDescriptor
;
}
}
compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
浏览文件 @
cfc41361
...
...
@@ -15,6 +15,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import
org.jetbrains.jet.lang.resolve.calls.*
;
import
org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant
;
import
org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor
;
import
org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver
;
import
org.jetbrains.jet.lang.types.*
;
import
org.jetbrains.jet.lexer.JetTokens
;
import
org.objectweb.asm.Label
;
...
...
@@ -584,6 +585,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
v
.
load
(
0
,
JetTypeMapper
.
TYPE_OBJECT
);
}
if
(
closure
.
isCaptureReceiver
()
!=
null
)
{
v
.
load
(
context
.
getContextDescriptor
().
getContainingDeclaration
()
instanceof
NamespaceDescriptor
?
0
:
1
,
closure
.
isCaptureReceiver
());
}
for
(
int
i
=
0
;
i
<
closure
.
getArgs
().
size
();
i
++)
{
StackValue
arg
=
closure
.
getArgs
().
get
(
i
);
arg
.
put
(
cons
.
getArgumentTypes
()[
i
],
v
);
...
...
@@ -738,7 +743,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override
public
StackValue
visitSimpleNameExpression
(
JetSimpleNameExpression
expression
,
StackValue
receiver
)
{
DeclarationDescriptor
descriptor
=
bindingContext
.
get
(
BindingContext
.
REFERENCE_TARGET
,
expression
);
ResolvedCall
<?
extends
CallableDescriptor
>
resolvedCall
=
bindingContext
.
get
(
BindingContext
.
RESOLVED_CALL
,
expression
);
DeclarationDescriptor
descriptor
;
if
(
resolvedCall
==
null
)
{
descriptor
=
bindingContext
.
get
(
BindingContext
.
REFERENCE_TARGET
,
expression
);
}
else
descriptor
=
resolvedCall
.
getResultingDescriptor
();
if
(
descriptor
instanceof
NamespaceDescriptor
)
return
StackValue
.
none
();
// No code to generate
if
(
descriptor
instanceof
VariableAsFunctionDescriptor
)
{
...
...
@@ -813,7 +826,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final
StackValue
iValue
=
intermediateValueForProperty
(
propertyDescriptor
,
directToField
,
isSuper
?
(
JetSuperExpression
)
r
:
null
);
if
(!
isStatic
)
{
if
(
receiver
==
StackValue
.
none
())
{
receiver
=
generateThisOrOuter
((
ClassDescriptor
)
propertyDescriptor
.
getContainingDeclaration
());
if
(
resolvedCall
==
null
)
receiver
=
generateThisOrOuter
((
ClassDescriptor
)
propertyDescriptor
.
getContainingDeclaration
());
else
{
if
(
resolvedCall
.
getThisObject
()
instanceof
ExtensionReceiver
)
receiver
=
generateReceiver
((
FunctionDescriptor
)
((
ExtensionReceiver
)
resolvedCall
.
getThisObject
()).
getDeclarationDescriptor
());
else
receiver
=
generateThisOrOuter
((
ClassDescriptor
)
propertyDescriptor
.
getContainingDeclaration
());
}
}
JetType
receiverType
=
bindingContext
.
get
(
BindingContext
.
EXPRESSION_TYPE
,
r
);
receiver
.
put
(
receiverType
!=
null
&&
!
isSuper
?
typeMapper
.
mapType
(
receiverType
)
:
JetTypeMapper
.
TYPE_OBJECT
,
v
);
...
...
@@ -856,13 +876,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
else
{
// receiver
StackValue
.
local
(
0
,
JetTypeMapper
.
TYPE_OBJECT
).
put
(
JetTypeMapper
.
TYPE_OBJECT
,
v
);
final
StackValue
value
=
context
.
lookupInContext
(
descriptor
,
v
);
StackValue
value
=
context
.
lookupInContext
(
descriptor
,
v
,
StackValue
.
local
(
0
,
JetTypeMapper
.
TYPE_OBJECT
));
if
(
value
==
null
)
{
throw
new
UnsupportedOperationException
(
"don't know how to generate reference "
+
descriptor
);
}
if
(
value
instanceof
StackValue
.
Composed
)
{
StackValue
.
Composed
composed
=
(
StackValue
.
Composed
)
value
;
composed
.
prefix
.
put
(
JetTypeMapper
.
TYPE_OBJECT
,
v
);
value
=
composed
.
suffix
;
}
if
(
value
instanceof
StackValue
.
FieldForSharedVar
)
{
StackValue
.
FieldForSharedVar
fieldForSharedVar
=
(
StackValue
.
FieldForSharedVar
)
value
;
Type
sharedType
=
StackValue
.
sharedTypeForType
(
value
.
type
);
...
...
@@ -911,7 +934,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
public
StackValue
intermediateValueForProperty
(
PropertyDescriptor
propertyDescriptor
,
final
boolean
forceField
,
@Nullable
JetSuperExpression
superExpression
)
{
boolean
isSuper
=
superExpression
!=
null
;
DeclarationDescriptor
containingDeclaration
=
propertyDescriptor
.
getContainingDeclaration
().
getOriginal
();
DeclarationDescriptor
containingDeclaration
=
propertyDescriptor
.
getContainingDeclaration
();
assert
containingDeclaration
!=
null
;
containingDeclaration
=
containingDeclaration
.
getOriginal
();
boolean
isStatic
=
containingDeclaration
instanceof
NamespaceDescriptorImpl
;
propertyDescriptor
=
propertyDescriptor
.
getOriginal
();
boolean
isInsideClass
=
((
containingDeclaration
==
context
.
getThisDescriptor
())
||
...
...
@@ -932,7 +958,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
if
(
isSuper
)
{
PsiElement
enclosingElement
=
bindingContext
.
get
(
BindingContext
.
LABEL_TARGET
,
superExpression
.
getTargetLabel
());
ClassDescriptor
enclosed
=
(
ClassDescriptor
)
bindingContext
.
get
(
BindingContext
.
DECLARATION_TO_DESCRIPTOR
,
enclosingElement
);
if
(!
CodegenUtil
.
isInterface
(
propertyDescriptor
.
getContainingDeclaration
()
))
{
if
(!
CodegenUtil
.
isInterface
(
containingDeclaration
))
{
if
(
enclosed
!=
null
&&
enclosed
!=
context
.
getThisDescriptor
())
{
CodegenContext
c
=
context
;
while
(
c
.
getContextDescriptor
()
!=
enclosed
)
{
...
...
@@ -1055,6 +1081,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
assert
!
superCall
;
callableMethod
=
asCallableMethod
((
FunctionDescriptor
)
fd
);
}
else
if
(
fd
instanceof
ExpressionAsFunctionDescriptor
)
{
FunctionDescriptor
invoke
=
CodegenUtil
.
createInvoke
((
ExpressionAsFunctionDescriptor
)
fd
);
callableMethod
=
asCallableMethod
(
invoke
);
}
else
if
(
fd
instanceof
FunctionDescriptor
)
{
callableMethod
=
typeMapper
.
mapToCallableMethod
((
FunctionDescriptor
)
fd
,
superCall
,
OwnerKind
.
IMPLEMENTATION
);
}
...
...
@@ -1066,14 +1096,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
private
DeclarationDescriptor
resolveCalleeDescriptor
(
JetCallExpression
call
)
{
JetExpression
callee
=
call
.
getCalleeExpression
();
if
(!(
callee
instanceof
JetReferenceExpression
))
{
throw
new
UnsupportedOperationException
(
"Don't know how to generate a call to "
+
callee
);
}
DeclarationDescriptor
funDescriptor
=
bindingContext
.
get
(
BindingContext
.
REFERENCE_TARGET
,
(
JetReferenceExpression
)
callee
);
if
(
funDescriptor
==
null
)
{
ResolvedCall
<?
extends
CallableDescriptor
>
resolvedCall
=
bindingContext
.
get
(
BindingContext
.
RESOLVED_CALL
,
callee
);
if
(
resolvedCall
==
null
)
{
assert
callee
!=
null
;
throw
new
CompilationException
(
"Cannot resolve: "
+
callee
.
getText
());
}
return
funDescriptor
;
return
resolvedCall
.
getResultingDescriptor
();
}
public
void
invokeMethodWithArguments
(
CallableMethod
callableMethod
,
JetCallElement
expression
,
StackValue
receiver
)
{
...
...
@@ -1102,7 +1131,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
v
.
load
(
0
,
JetTypeMapper
.
TYPE_OBJECT
);
}
else
receiver
.
put
(
JetTypeMapper
.
TYPE_OBJECT
,
v
);
receiver
.
put
(
callableMethod
.
getSignature
().
getArgumentTypes
()[
0
]
,
v
);
}
}
...
...
@@ -1147,11 +1176,33 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
}
private
StackValue
generateReceiver
(
FunctionDescriptor
descriptor
)
{
assert
context
instanceof
CodegenContext
.
FunctionContext
;
CodegenContext
.
FunctionContext
cur
=
(
CodegenContext
.
FunctionContext
)
context
;
if
(
cur
.
getReceiverDescriptor
()
==
descriptor
)
{
return
cur
.
getReceiverExpression
(
typeMapper
);
}
return
context
.
lookupInContext
(
descriptor
,
v
,
StackValue
.
local
(
0
,
JetTypeMapper
.
TYPE_OBJECT
));
// assert context instanceof CodegenContext.FunctionContext;
// CodegenContext.FunctionContext cur = (CodegenContext.FunctionContext) context;
//
// StackValue result = StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
// while (cur != null) {
//
// if (cur.getReceiverDescriptor() == descriptor) {
// return cur.getReceiverExpression(typeMapper);
// }
//
// result = cur.getOuterExpression(result);
// cur = cur.getOuterFunction();
// }
//
// throw new UnsupportedOperationException("Don't know how to generate receiver for " + descriptor);
}
public
StackValue
generateThisOrOuter
(
ClassDescriptor
calleeContainingClass
)
{
CodegenContext
cur
=
context
;
if
(
cur
.
getReceiverDescriptor
()
==
calleeContainingClass
)
{
return
cur
.
getReceiverExpression
();
}
StackValue
result
=
StackValue
.
local
(
0
,
JetTypeMapper
.
TYPE_OBJECT
);
while
(
cur
!=
null
)
{
...
...
@@ -2071,9 +2122,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
else
{
if
(
descriptor
instanceof
FunctionDescriptor
)
{
FunctionDescriptor
functionDescriptor
=
(
FunctionDescriptor
)
descriptor
;
Type
type
=
typeMapper
.
mapType
(
functionDescriptor
.
getReceiverParameter
().
getType
());
return
StackValue
.
local
(
descriptor
.
getContainingDeclaration
()
instanceof
NamespaceDescriptor
?
0
:
1
,
type
);
return
generateReceiver
((
FunctionDescriptor
)
descriptor
);
}
throw
new
UnsupportedOperationException
();
}
...
...
@@ -2362,8 +2411,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return
;
}
DeclarationDescriptor
containingDeclaration
=
typeParameterDescriptor
.
getContainingDeclaration
();
if
(
context
.
getThisDescriptor
()
instanceof
ClassDescriptor
)
{
ClassDescriptor
descriptor
=
(
ClassDescriptor
)
context
.
getThisDescriptor
();
if
(
context
.
getThisDescriptor
()
!=
null
)
{
ClassDescriptor
descriptor
=
context
.
getThisDescriptor
();
assert
containingDeclaration
!=
null
;
JetType
defaultType
=
((
ClassDescriptor
)
containingDeclaration
).
getDefaultType
();
Type
ownerType
=
typeMapper
.
mapType
(
defaultType
);
...
...
compiler/backend/src/org/jetbrains/jet/codegen/GeneratedAnonymousClassDescriptor.java
浏览文件 @
cfc41361
...
...
@@ -3,6 +3,7 @@
*/
package
org.jetbrains.jet.codegen
;
import
org.objectweb.asm.Type
;
import
org.objectweb.asm.commons.Method
;
import
java.util.ArrayList
;
...
...
@@ -12,12 +13,14 @@ public class GeneratedAnonymousClassDescriptor {
private
final
String
classname
;
private
Method
constructor
;
private
final
boolean
captureThis
;
private
final
Type
captureReceiver
;
private
List
<
StackValue
>
args
=
new
ArrayList
<
StackValue
>();
public
GeneratedAnonymousClassDescriptor
(
String
classname
,
Method
constructor
,
boolean
captureThis
)
{
public
GeneratedAnonymousClassDescriptor
(
String
classname
,
Method
constructor
,
boolean
captureThis
,
Type
captureReceiver
)
{
this
.
classname
=
classname
;
this
.
constructor
=
constructor
;
this
.
captureThis
=
captureThis
;
this
.
captureReceiver
=
captureReceiver
;
}
public
String
getClassname
()
{
...
...
@@ -39,4 +42,8 @@ public class GeneratedAnonymousClassDescriptor {
public
boolean
isCaptureThis
()
{
return
captureThis
;
}
public
Type
isCaptureReceiver
()
{
return
captureReceiver
;
}
}
compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java
浏览文件 @
cfc41361
...
...
@@ -126,7 +126,7 @@ public class GenerationState {
ConstructorDescriptor
constructorDescriptor
=
closure
.
state
.
getBindingContext
().
get
(
BindingContext
.
CONSTRUCTOR
,
objectDeclaration
);
CallableMethod
callableMethod
=
closure
.
state
.
getTypeMapper
().
mapToCallableMethod
(
constructorDescriptor
,
OwnerKind
.
IMPLEMENTATION
);
return
new
GeneratedAnonymousClassDescriptor
(
nameAndVisitor
.
first
,
callableMethod
.
getSignature
(),
false
);
return
new
GeneratedAnonymousClassDescriptor
(
nameAndVisitor
.
first
,
callableMethod
.
getSignature
(),
objectContext
.
outerWasUsed
,
null
);
}
public
static
void
prepareAnonymousClasses
(
JetElement
aClass
,
final
JetTypeMapper
typeMapper
)
{
...
...
compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java
浏览文件 @
cfc41361
package
org.jetbrains.jet.codegen
;
import
org.jetbrains.jet.lang.descriptors.ClassDescriptorImpl
;
import
org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
;
import
org.jetbrains.jet.lang.descriptors.VariableDescriptor
;
import
org.jetbrains.jet.lang.descriptors.*
;
import
org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
;
import
org.objectweb.asm.Opcodes
;
import
org.objectweb.asm.Type
;
...
...
@@ -16,6 +14,7 @@ import java.util.Map;
*/
public
class
ObjectOrClosureCodegen
{
protected
boolean
captureThis
;
protected
Type
captureReceiver
;
public
final
GenerationState
state
;
protected
final
ExpressionCodegen
exprContext
;
...
...
@@ -30,13 +29,16 @@ public class ObjectOrClosureCodegen {
this
.
state
=
state
;
}
public
StackValue
lookupInContext
(
DeclarationDescriptor
d
)
{
public
StackValue
lookupInContext
(
DeclarationDescriptor
d
,
StackValue
result
)
{
EnclosedValueDescriptor
answer
=
closure
.
get
(
d
);
if
(
answer
!=
null
)
{
StackValue
innerValue
=
answer
.
getInnerValue
();
return
result
!=
null
?
innerValue
:
StackValue
.
composed
(
result
,
innerValue
);
}
if
(
d
instanceof
VariableDescriptor
)
{
VariableDescriptor
vd
=
(
VariableDescriptor
)
d
;
EnclosedValueDescriptor
answer
=
closure
.
get
(
vd
);
if
(
answer
!=
null
)
return
answer
.
getInnerValue
();
final
int
idx
=
exprContext
.
lookupLocal
(
vd
);
if
(
idx
<
0
)
return
null
;
...
...
@@ -56,14 +58,36 @@ public class ObjectOrClosureCodegen {
return
innerValue
;
}
return
null
;
}
if
(
d
instanceof
FunctionDescriptor
)
{
// we are looking for receiver
FunctionDescriptor
fd
=
(
FunctionDescriptor
)
d
;
// we generate method
assert
context
instanceof
CodegenContext
.
FunctionContext
;
CodegenContext
.
FunctionContext
fcontext
=
(
CodegenContext
.
FunctionContext
)
context
;
if
(
fcontext
.
getReceiverDescriptor
()
!=
fd
)
return
null
;
Type
type
=
state
.
getTypeMapper
().
mapType
(
fcontext
.
getReceiverDescriptor
().
getReceiverParameter
().
getType
());
boolean
isStatic
=
fcontext
.
getContextDescriptor
().
getContainingDeclaration
()
instanceof
NamespaceDescriptor
;
StackValue
outerValue
=
StackValue
.
local
(
isStatic
?
0
:
1
,
type
);
final
String
fieldName
=
"receiver$0"
;
StackValue
innerValue
=
StackValue
.
field
(
type
,
name
,
fieldName
,
false
);
public
boolean
isCaptureThis
()
{
return
captureThis
;
cv
.
newField
(
null
,
Opcodes
.
ACC_PUBLIC
,
fieldName
,
type
.
getDescriptor
(),
null
,
null
);
answer
=
new
EnclosedValueDescriptor
(
d
,
innerValue
,
outerValue
);
closure
.
put
(
d
,
answer
);
return
innerValue
;
}
return
null
;
}
public
boolean
isConst
()
{
return
!
captureThis
&&
closure
.
isEmpty
();
return
!
captureThis
&&
c
aptureReceiver
!=
null
&&
c
losure
.
isEmpty
();
}
}
compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java
浏览文件 @
cfc41361
...
...
@@ -795,9 +795,9 @@ public abstract class StackValue {
}
}
p
rivate
static
class
Composed
extends
StackValue
{
p
rivate
StackValue
prefix
;
p
rivate
StackValue
suffix
;
p
ublic
static
class
Composed
extends
StackValue
{
p
ublic
final
StackValue
prefix
;
p
ublic
final
StackValue
suffix
;
public
Composed
(
StackValue
prefix
,
StackValue
suffix
)
{
super
(
suffix
.
type
);
...
...
@@ -810,5 +810,11 @@ public abstract class StackValue {
prefix
.
put
(
prefix
.
type
,
v
);
suffix
.
put
(
type
,
v
);
}
@Override
public
void
store
(
InstructionAdapter
v
)
{
prefix
.
put
(
JetTypeMapper
.
TYPE_OBJECT
,
v
);
suffix
.
store
(
v
);
}
}
}
compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java
浏览文件 @
cfc41361
...
...
@@ -187,7 +187,7 @@ public class CallResolver {
return
null
;
}
FunctionDescriptorImpl
functionDescriptor
=
new
FunctionDescriptorImpl
(
scope
.
getContainingDeclaration
(),
Collections
.<
AnnotationDescriptor
>
emptyList
(),
"[for expression "
+
calleeExpression
.
getText
()
+
"]"
);
FunctionDescriptorImpl
functionDescriptor
=
new
ExpressionAsFunctionDescriptor
(
scope
.
getContainingDeclaration
(),
"[for expression "
+
calleeExpression
.
getText
()
+
"]"
);
FunctionDescriptorUtil
.
initializeFromFunctionType
(
functionDescriptor
,
calleeType
);
ResolvedCallImpl
<
FunctionDescriptor
>
resolvedCall
=
ResolvedCallImpl
.<
FunctionDescriptor
>
create
(
functionDescriptor
);
resolvedCall
.
setReceiverArgument
(
call
.
getExplicitReceiver
());
...
...
compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ExpressionAsFunctionDescriptor.java
0 → 100644
浏览文件 @
cfc41361
package
org.jetbrains.jet.lang.resolve.calls
;
import
org.jetbrains.annotations.NotNull
;
import
org.jetbrains.annotations.Nullable
;
import
org.jetbrains.jet.lang.descriptors.*
;
import
org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
;
import
org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
;
import
org.jetbrains.jet.lang.types.JetStandardClasses
;
import
org.jetbrains.jet.lang.types.JetType
;
import
java.util.Collections
;
import
java.util.List
;
/**
* @author alex.tkachman
*/
public
class
ExpressionAsFunctionDescriptor
extends
FunctionDescriptorImpl
{
public
ExpressionAsFunctionDescriptor
(
DeclarationDescriptor
containingDeclaration
,
String
name
)
{
super
(
containingDeclaration
,
Collections
.<
AnnotationDescriptor
>
emptyList
(),
name
);
}
}
compiler/testData/codegen/functions/functionExpression.jet
0 → 100644
浏览文件 @
cfc41361
fun Any.foo1() : fun(): String {
return { "239" + this }
}
fun Int.foo2() : fun(i : Int) : Int {
return { x => x + this }
}
fun fooT1<T>(t : T) = { t.toString() }
fun fooT2<T>(t: T) = { (x:T) => t.toString() + x.toString() }
fun box() : String {
if( (10.foo1())() != "23910") return "foo1 fail"
if( (10.foo2())(1) != 11 ) return "foo2 fail"
if(1.{Int.() => this + 1}() != 2) return "test 3 failed";
if( {1}() != 1) return "test 4 failed";
if( {(x : Int) => x}(1) != 1) return "test 5 failed";
if( 1.{Int.(x : Int) => x + this}(1) != 2) return "test 6 failed";
if( 1.({Int.() => this})() != 1) return "test 7 failed";
if( (fooT1<String>("mama"))() != "mama") return "test 8 failed";
if( (fooT2<String>("mama"))("papa") != "mamapapa") return "test 9 failed";
return "OK"
}
compiler/testData/codegen/functions/withtypeparams.jet
0 → 100644
浏览文件 @
cfc41361
class X<T> () {
fun getTypeChecker() = { (a : Any) => a is T }
}
fun box() : String {
val c = X<String>().getTypeChecker()
if(c(10)) return "fail"
if(!c("lala")) return "fail"
return "OK"
}
compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java
浏览文件 @
cfc41361
...
...
@@ -80,55 +80,8 @@ public class FunctionGenTest extends CodegenTestCase {
public
void
testKt395
()
{
blackBoxFile
(
"regressions/kt395.jet"
);
}
/*
public
void
testFunction
()
throws
InvocationTargetException
,
IllegalAccessException
{
loadText("fun Any.foo() : fun(): String {\n" +
" return { \"239\" + this }\n" +
"}\n" +
"fun box() : String {\n" +
" return if((10.foo())() == \"23910\") \"OK\" else \"fail\"" +
"}" +
"");
System.out.println(generateToText());
Method foo = generateFunction();
assertTrue((Boolean) foo.invoke(null, "lala"));
assertFalse((Boolean) foo.invoke(null, "mama"));
blackBoxFile
(
"functions/functionExpression.jet"
);
}
fun Any.foo() : fun() : Unit {
return {}
}
fun Any.foo1() : fun(i : Int) : Unit {
return {}
}
fun foo2() : fun(i : fun()) : Unit {
return {}
}
fun fooT1<T>(t : T) : fun() : T {
return {t}
}
fun fooT2<T>() : fun(t : T) : T {
return {it}
}
fun main(args : Array<String>) {
args.foo()()
args.foo1()(1)
foo2()({})
(foo2()){}
val a = fooT1(1)()
a : Int
val b = fooT2<Int>()(1)
b : Int
fooT2()(1) // : Any?
}
*/
}
stdlib/src/jet/DefaultJetObject.java
浏览文件 @
cfc41361
...
...
@@ -13,7 +13,7 @@ public class DefaultJetObject implements JetObject {
}
@Override
public
TypeInfo
<?>
getTypeInfo
()
{
public
final
TypeInfo
<?>
getTypeInfo
()
{
return
typeInfo
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录