Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
硅谷海盗
kotlin
提交
812d2a18
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,发现更多精彩内容 >>
提交
812d2a18
编写于
4月 07, 2011
作者:
D
Dmitry Jemerov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
casts for constants
上级
365c9af5
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
140 addition
and
89 deletion
+140
-89
idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
+75
-26
idea/src/org/jetbrains/jet/codegen/StackValue.java
idea/src/org/jetbrains/jet/codegen/StackValue.java
+52
-63
idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java
idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java
+13
-0
未找到文件。
idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
浏览文件 @
812d2a18
...
...
@@ -2,6 +2,7 @@ package org.jetbrains.jet.codegen;
import
com.intellij.psi.*
;
import
com.intellij.psi.tree.IElementType
;
import
org.jetbrains.annotations.Nullable
;
import
org.jetbrains.jet.lang.psi.*
;
import
org.jetbrains.jet.lang.resolve.BindingContext
;
import
org.jetbrains.jet.lang.types.*
;
...
...
@@ -186,7 +187,7 @@ public class ExpressionCodegen extends JetVisitor {
@Override
public
void
visitConstantExpression
(
JetConstantExpression
expression
)
{
myStack
.
push
(
StackValue
.
constant
(
expression
.
getValue
()));
myStack
.
push
(
StackValue
.
constant
(
expression
.
getValue
()
,
expressionType
(
expression
)
));
}
@Override
...
...
@@ -259,6 +260,18 @@ public class ExpressionCodegen extends JetVisitor {
@Override
public
void
visitSimpleNameExpression
(
JetSimpleNameExpression
expression
)
{
final
DeclarationDescriptor
descriptor
=
bindingContext
.
resolveReferenceExpression
(
expression
);
if
(
descriptor
instanceof
PropertyDescriptor
)
{
final
DeclarationDescriptor
container
=
descriptor
.
getContainingDeclaration
();
if
(
isClass
(
container
,
"Number"
))
{
Type
castType
=
getCastType
(
expression
.
getReferencedName
());
if
(
castType
!=
null
)
{
final
StackValue
value
=
myStack
.
pop
();
value
.
put
(
castType
,
v
);
myStack
.
push
(
StackValue
.
onStack
(
castType
));
return
;
}
}
}
PsiElement
declaration
=
bindingContext
.
getDeclarationPsiElement
(
descriptor
);
if
(
declaration
instanceof
PsiField
)
{
PsiField
psiField
=
(
PsiField
)
declaration
;
...
...
@@ -284,6 +297,32 @@ public class ExpressionCodegen extends JetVisitor {
}
}
@Nullable
private
static
Type
getCastType
(
String
castMethodName
)
{
if
(
"dbl"
.
equals
(
castMethodName
))
{
return
Type
.
DOUBLE_TYPE
;
}
if
(
"flt"
.
equals
(
castMethodName
))
{
return
Type
.
FLOAT_TYPE
;
}
if
(
"lng"
.
equals
(
castMethodName
))
{
return
Type
.
LONG_TYPE
;
}
if
(
"int"
.
equals
(
castMethodName
))
{
return
Type
.
INT_TYPE
;
}
if
(
"chr"
.
equals
(
castMethodName
))
{
return
Type
.
CHAR_TYPE
;
}
if
(
"sht"
.
equals
(
castMethodName
))
{
return
Type
.
SHORT_TYPE
;
}
if
(
"byt"
.
equals
(
castMethodName
))
{
return
Type
.
BYTE_TYPE
;
}
return
null
;
}
@Override
public
void
visitCallExpression
(
JetCallExpression
expression
)
{
JetExpression
callee
=
expression
.
getCalleeExpression
();
...
...
@@ -354,6 +393,10 @@ public class ExpressionCodegen extends JetVisitor {
return
Type
.
getMethodDescriptor
(
returnType
,
parameterTypes
);
}
private
Type
expressionType
(
JetExpression
expr
)
{
return
typeMapper
.
mapType
(
bindingContext
.
getExpressionType
(
expr
));
}
private
static
Type
psiTypeToAsm
(
PsiType
type
)
{
if
(
type
instanceof
PsiPrimitiveType
)
{
if
(
type
==
PsiType
.
VOID
)
{
...
...
@@ -444,45 +487,51 @@ public class ExpressionCodegen extends JetVisitor {
JetType
returnType
=
bindingContext
.
getExpressionType
(
expression
);
final
Type
asmType
=
typeMapper
.
mapType
(
returnType
);
DeclarationDescriptor
cls
=
op
.
getContainingDeclaration
();
if
(
cls
instanceof
ClassDescriptor
)
{
final
String
className
=
cls
.
getName
();
if
(
isNumberPrimitive
(
className
))
{
if
(
op
.
getName
().
equals
(
"compareTo"
))
{
generateCompareOp
(
expression
,
opToken
,
asmType
);
if
(
isNumberPrimitive
(
cls
))
{
if
(
op
.
getName
().
equals
(
"compareTo"
))
{
generateCompareOp
(
expression
,
opToken
,
asmType
);
}
else
{
int
opcode
=
opcodeForMethod
(
op
.
getName
());
generateBinaryOp
(
expression
,
(
FunctionDescriptor
)
op
,
opcode
);
}
return
;
}
else
if
(
isClass
(
cls
,
"Hashable"
))
{
if
(
op
.
getName
().
equals
(
"equals"
))
{
final
Type
leftType
=
typeMapper
.
mapType
(
bindingContext
.
getExpressionType
(
expression
.
getLeft
()));
final
Type
rightType
=
typeMapper
.
mapType
(
bindingContext
.
getExpressionType
(
expression
.
getRight
()));
if
(
isNumberPrimitive
(
leftType
)
&&
leftType
==
rightType
)
{
generateCompareOp
(
expression
,
opToken
,
leftType
);
return
;
}
else
{
int
opcode
=
opcodeForMethod
(
op
.
getName
());
generateBinaryOp
(
expression
,
(
FunctionDescriptor
)
op
,
opcode
);
}
return
;
}
else
if
(
className
.
equals
(
"Hashable"
))
{
if
(
op
.
getName
().
equals
(
"equals"
))
{
final
Type
leftType
=
typeMapper
.
mapType
(
bindingContext
.
getExpressionType
(
expression
.
getLeft
()));
final
Type
rightType
=
typeMapper
.
mapType
(
bindingContext
.
getExpressionType
(
expression
.
getRight
()));
if
(
isNumberPrimitive
(
leftType
)
&&
leftType
==
rightType
)
{
generateCompareOp
(
expression
,
opToken
,
leftType
);
return
;
}
else
{
throw
new
UnsupportedOperationException
(
"Don't know how to generate equality for these types"
);
}
throw
new
UnsupportedOperationException
(
"Don't know how to generate equality for these types"
);
}
}
else
{
throw
new
UnsupportedOperationException
(
"Don't know how to generate binary op for class "
+
className
);
}
}
}
throw
new
UnsupportedOperationException
(
"Don't know how to generate binary op "
+
expression
);
}
private
static
boolean
isNumberPrimitive
(
String
className
)
{
private
static
boolean
isNumberPrimitive
(
DeclarationDescriptor
descriptor
)
{
if
(!(
descriptor
instanceof
ClassDescriptor
))
{
return
false
;
}
String
className
=
descriptor
.
getName
();
return
className
.
equals
(
"Int"
)
||
className
.
equals
(
"Long"
)
||
className
.
equals
(
"Short"
)
||
className
.
equals
(
"Byte"
)
||
className
.
equals
(
"Char"
)
||
className
.
equals
(
"Float"
)
||
className
.
equals
(
"Double"
);
}
private
static
boolean
isClass
(
DeclarationDescriptor
descriptor
,
String
name
)
{
if
(!(
descriptor
instanceof
ClassDescriptor
))
{
return
false
;
}
String
className
=
descriptor
.
getName
();
return
className
.
equals
(
name
);
}
private
static
boolean
isNumberPrimitive
(
Type
type
)
{
return
type
==
Type
.
INT_TYPE
||
type
==
Type
.
SHORT_TYPE
||
type
==
Type
.
BYTE_TYPE
||
type
==
Type
.
CHAR_TYPE
||
type
==
Type
.
FLOAT_TYPE
||
type
==
Type
.
DOUBLE_TYPE
||
type
==
Type
.
LONG_TYPE
;
...
...
idea/src/org/jetbrains/jet/codegen/StackValue.java
浏览文件 @
812d2a18
...
...
@@ -11,6 +11,12 @@ import org.objectweb.asm.commons.InstructionAdapter;
* @author yole
*/
public
abstract
class
StackValue
{
protected
final
Type
type
;
public
StackValue
(
Type
type
)
{
this
.
type
=
type
;
}
public
abstract
void
put
(
Type
type
,
InstructionAdapter
v
);
public
static
StackValue
local
(
int
index
,
Type
type
)
{
...
...
@@ -22,8 +28,8 @@ public abstract class StackValue {
return
new
OnStack
(
type
);
}
public
static
StackValue
constant
(
Object
value
)
{
return
new
Constant
(
value
);
public
static
StackValue
constant
(
Object
value
,
Type
type
)
{
return
new
Constant
(
value
,
type
);
}
public
static
StackValue
cmp
(
IElementType
opToken
,
Type
type
)
{
...
...
@@ -32,44 +38,54 @@ public abstract class StackValue {
public
abstract
void
condJump
(
Label
label
,
boolean
jumpIfFalse
,
InstructionAdapter
v
);
private
static
void
box
(
final
Type
type
,
InstructionAdapter
v
)
{
if
(
type
==
Type
.
INT_TYPE
)
{
v
.
invokestatic
(
"java/lang/Integer"
,
"valueOf"
,
"(I)Ljava/lang/Integer;"
);
}
else
if
(
type
==
Type
.
BOOLEAN_TYPE
)
{
v
.
invokestatic
(
"java/lang/Boolean"
,
"valueOf"
,
"(Z)Ljava/lang/Boolean;"
);
}
else
if
(
type
==
Type
.
CHAR_TYPE
)
{
v
.
invokestatic
(
"java/lang/Character"
,
"valueOf"
,
"(C)Ljava/lang/Character;"
);
}
else
if
(
type
==
Type
.
SHORT_TYPE
)
{
v
.
invokestatic
(
"java/lang/Short"
,
"valueOf"
,
"(S)Ljava/lang/Short;"
);
}
else
if
(
type
==
Type
.
LONG_TYPE
)
{
v
.
invokestatic
(
"java/lang/Long"
,
"valueOf"
,
"(J)Ljava/lang/Long;"
);
}
else
if
(
type
==
Type
.
BYTE_TYPE
)
{
v
.
invokestatic
(
"java/lang/Byte"
,
"valueOf"
,
"(B)Ljava/lang/Byte;"
);
}
else
if
(
type
==
Type
.
FLOAT_TYPE
)
{
v
.
invokestatic
(
"java/lang/Float"
,
"valueOf"
,
"(F)Ljava/lang/Float;"
);
}
else
if
(
type
==
Type
.
DOUBLE_TYPE
)
{
v
.
invokestatic
(
"java/lang/Double"
,
"valueOf"
,
"(D)Ljava/lang/Double;"
);
}
}
protected
void
coerce
(
Type
type
,
InstructionAdapter
v
)
{
if
(
type
.
getSort
()
==
Type
.
OBJECT
)
{
box
(
this
.
type
,
v
);
}
else
if
(
type
!=
this
.
type
)
{
v
.
cast
(
this
.
type
,
type
);
}
}
public
static
class
Local
extends
StackValue
{
private
final
int
index
;
private
final
Type
type
;
public
Local
(
int
index
,
Type
type
)
{
super
(
type
);
this
.
index
=
index
;
this
.
type
=
type
;
}
@Override
public
void
put
(
Type
type
,
InstructionAdapter
v
)
{
v
.
load
(
index
,
this
.
type
);
if
(
type
.
getSort
()
==
Type
.
OBJECT
)
{
if
(
this
.
type
==
Type
.
INT_TYPE
)
{
v
.
invokestatic
(
"java/lang/Integer"
,
"valueOf"
,
"(I)Ljava/lang/Integer;"
);
}
else
if
(
this
.
type
==
Type
.
BOOLEAN_TYPE
)
{
v
.
invokestatic
(
"java/lang/Boolean"
,
"valueOf"
,
"(Z)Ljava/lang/Boolean;"
);
}
else
if
(
this
.
type
==
Type
.
CHAR_TYPE
)
{
v
.
invokestatic
(
"java/lang/Character"
,
"valueOf"
,
"(C)Ljava/lang/Character;"
);
}
else
if
(
this
.
type
==
Type
.
SHORT_TYPE
)
{
v
.
invokestatic
(
"java/lang/Short"
,
"valueOf"
,
"(S)Ljava/lang/Short;"
);
}
else
if
(
this
.
type
==
Type
.
LONG_TYPE
)
{
v
.
invokestatic
(
"java/lang/Long"
,
"valueOf"
,
"(J)Ljava/lang/Long;"
);
}
else
if
(
this
.
type
==
Type
.
BYTE_TYPE
)
{
v
.
invokestatic
(
"java/lang/Byte"
,
"valueOf"
,
"(B)Ljava/lang/Byte;"
);
}
else
if
(
this
.
type
==
Type
.
FLOAT_TYPE
)
{
v
.
invokestatic
(
"java/lang/Float"
,
"valueOf"
,
"(F)Ljava/lang/Float;"
);
}
else
if
(
this
.
type
==
Type
.
DOUBLE_TYPE
)
{
v
.
invokestatic
(
"java/lang/Double"
,
"valueOf"
,
"(D)Ljava/lang/Double;"
);
}
}
coerce
(
type
,
v
);
// TODO unbox
}
...
...
@@ -86,10 +102,8 @@ public abstract class StackValue {
}
public
static
class
OnStack
extends
StackValue
{
private
final
Type
type
;
public
OnStack
(
Type
type
)
{
this
.
type
=
type
;
super
(
type
)
;
}
@Override
...
...
@@ -98,7 +112,7 @@ public abstract class StackValue {
@Override
public
void
condJump
(
Label
label
,
boolean
jumpIfFalse
,
InstructionAdapter
v
)
{
if
(
type
==
Type
.
BOOLEAN_TYPE
)
{
if
(
t
his
.
t
ype
==
Type
.
BOOLEAN_TYPE
)
{
if
(
jumpIfFalse
)
{
v
.
ifeq
(
label
);
}
...
...
@@ -115,39 +129,15 @@ public abstract class StackValue {
public
static
class
Constant
extends
StackValue
{
private
final
Object
value
;
public
Constant
(
Object
value
)
{
public
Constant
(
Object
value
,
Type
type
)
{
super
(
type
);
this
.
value
=
value
;
}
@Override
public
void
put
(
Type
type
,
InstructionAdapter
v
)
{
v
.
aconst
(
value
);
if
(
type
.
getSort
()
==
Type
.
OBJECT
)
{
if
(
value
instanceof
Integer
)
{
v
.
invokestatic
(
"java/lang/Integer"
,
"valueOf"
,
"(I)Ljava/lang/Integer;"
);
}
else
if
(
value
instanceof
Boolean
)
{
v
.
invokestatic
(
"java/lang/Boolean"
,
"valueOf"
,
"(Z)Ljava/lang/Boolean;"
);
}
else
if
(
value
instanceof
Character
)
{
v
.
invokestatic
(
"java/lang/Character"
,
"valueOf"
,
"(C)Ljava/lang/Character;"
);
}
else
if
(
value
instanceof
Short
)
{
v
.
invokestatic
(
"java/lang/Short"
,
"valueOf"
,
"(S)Ljava/lang/Short;"
);
}
else
if
(
value
instanceof
Long
)
{
v
.
invokestatic
(
"java/lang/Long"
,
"valueOf"
,
"(J)Ljava/lang/Long;"
);
}
else
if
(
value
instanceof
Byte
)
{
v
.
invokestatic
(
"java/lang/Byte"
,
"valueOf"
,
"(B)Ljava/lang/Byte;"
);
}
else
if
(
value
instanceof
Float
)
{
v
.
invokestatic
(
"java/lang/Float"
,
"valueOf"
,
"(F)Ljava/lang/Float;"
);
}
else
if
(
value
instanceof
Double
)
{
v
.
invokestatic
(
"java/lang/Double"
,
"valueOf"
,
"(D)Ljava/lang/Double;"
);
}
}
coerce
(
type
,
v
);
}
@Override
...
...
@@ -166,11 +156,10 @@ public abstract class StackValue {
private
static
class
NumberCompare
extends
StackValue
{
private
final
IElementType
opToken
;
private
final
Type
type
;
public
NumberCompare
(
IElementType
opToken
,
Type
type
)
{
super
(
type
);
this
.
opToken
=
opToken
;
this
.
type
=
type
;
}
@Override
...
...
idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java
浏览文件 @
812d2a18
...
...
@@ -314,6 +314,19 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
assertEquals
(
"1.0"
,
main
.
invoke
(
null
,
1.0
));
}
public
void
testDoubleToInt
()
throws
Exception
{
loadText
(
"fun foo(a: Double): Int = a.int"
);
System
.
out
.
println
(
generateToText
());
final
Method
main
=
generateFunction
();
assertEquals
(
1
,
main
.
invoke
(
null
,
1.0
));
}
public
void
testCastConstant
()
throws
Exception
{
loadText
(
"fun foo(): Double = 1.dbl"
);
final
Method
main
=
generateFunction
();
assertEquals
(
1.0
,
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录