Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
硅谷海盗
kotlin
提交
400e939c
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,发现更多精彩内容 >>
提交
400e939c
编写于
6月 14, 2011
作者:
A
Andrey Breslav
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Bindings are propagated over control flow, only directly, otherwise it is confusing
上级
79d3f318
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
65 addition
and
94 deletion
+65
-94
idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java
idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java
+48
-81
idea/testData/checker/infos/Autocasts.jet
idea/testData/checker/infos/Autocasts.jet
+17
-13
未找到文件。
idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java
浏览文件 @
400e939c
...
...
@@ -373,12 +373,12 @@ public class JetTypeInferrer {
if
(
newDataFlowInfo
==
null
)
{
newDataFlowInfo
=
dataFlowInfo
;
}
WritableScope
newScope
=
blockLevelVisitor
.
getResultScope
();
if
(
newScope
==
null
)
{
newScope
=
scope
;
}
if
(
newDataFlowInfo
!=
dataFlowInfo
||
newScope
!=
scope
)
{
blockLevelVisitor
=
new
TypeInferrerVisitorWithWritableScope
(
newS
cope
,
true
,
newDataFlowInfo
);
//
WritableScope newScope = blockLevelVisitor.getResultScope();
//
if (newScope == null) {
//
newScope = scope;
//
}
if
(
newDataFlowInfo
!=
dataFlowInfo
)
{
//
|| newScope != scope) {
blockLevelVisitor
=
new
TypeInferrerVisitorWithWritableScope
(
s
cope
,
true
,
newDataFlowInfo
);
}
else
{
blockLevelVisitor
.
resetResult
();
// TODO : maybe it's better to recreate the visitors with the same scope?
...
...
@@ -591,7 +591,7 @@ public class JetTypeInferrer {
protected
JetType
result
;
protected
DataFlowInfo
resultDataFlowInfo
;
protected
WritableScope
resultScope
;
//
protected WritableScope resultScope;
private
TypeInferrerVisitor
(
@NotNull
JetScope
scope
,
boolean
preferBlock
,
@NotNull
DataFlowInfo
dataFlowInfo
)
{
this
.
scope
=
scope
;
...
...
@@ -604,16 +604,16 @@ public class JetTypeInferrer {
return
resultDataFlowInfo
;
}
public
WritableScope
getResultScope
()
{
if
(
resultScope
instanceof
WritableScopeImpl
)
{
WritableScopeImpl
writableScope
=
(
WritableScopeImpl
)
resultScope
;
if
(!
writableScope
.
hasDeclaredItems
())
{
return
null
;
}
}
return
resultScope
;
}
//
public WritableScope getResultScope() {
//
if (resultScope instanceof WritableScopeImpl) {
//
WritableScopeImpl writableScope = (WritableScopeImpl) resultScope;
//
if (!writableScope.hasDeclaredItems()) {
//
return null;
//
}
//
}
//
return resultScope;
//
}
//
@Nullable
public
JetType
getType
(
@NotNull
JetScope
scope
,
@NotNull
JetExpression
expression
,
boolean
preferBlock
)
{
return
getType
(
scope
,
expression
,
preferBlock
,
dataFlowInfo
);
...
...
@@ -673,7 +673,7 @@ public class JetTypeInferrer {
public
void
resetResult
()
{
result
=
null
;
resultDataFlowInfo
=
null
;
resultScope
=
null
;
//
resultScope = null;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
...
...
@@ -1350,7 +1350,7 @@ public class JetTypeInferrer {
JetType
type
=
getType
(
thenScope
,
thenBranch
,
true
,
thenInfo
);
if
(
type
!=
null
&&
JetStandardClasses
.
isNothing
(
type
))
{
resultDataFlowInfo
=
elseInfo
;
resultScope
=
elseScope
;
//
resultScope = elseScope;
}
result
=
JetStandardClasses
.
getUnitType
();
}
...
...
@@ -1359,7 +1359,7 @@ public class JetTypeInferrer {
JetType
type
=
getType
(
elseScope
,
elseBranch
,
true
,
elseInfo
);
if
(
type
!=
null
&&
JetStandardClasses
.
isNothing
(
type
))
{
resultDataFlowInfo
=
thenInfo
;
resultScope
=
thenScope
;
//
resultScope = thenScope;
}
result
=
JetStandardClasses
.
getUnitType
();
}
...
...
@@ -1382,16 +1382,16 @@ public class JetTypeInferrer {
if
(
jumpInThen
&&
!
jumpInElse
)
{
resultDataFlowInfo
=
elseInfo
;
resultScope
=
elseScope
;
//
resultScope = elseScope;
}
else
if
(
jumpInElse
&&
!
jumpInThen
)
{
resultDataFlowInfo
=
thenInfo
;
resultScope
=
thenScope
;
//
resultScope = thenScope;
}
}
}
private
DataFlowInfo
extractDataFlowInfoFromCondition
(
@Nullable
JetExpression
condition
,
final
boolean
conditionValue
,
@N
otNull
final
WritableScope
scopeToExtend
)
{
private
DataFlowInfo
extractDataFlowInfoFromCondition
(
@Nullable
JetExpression
condition
,
final
boolean
conditionValue
,
@N
ullable
final
WritableScope
scopeToExtend
)
{
if
(
condition
==
null
)
return
dataFlowInfo
;
final
DataFlowInfo
[]
result
=
new
DataFlowInfo
[]
{
dataFlowInfo
};
condition
.
accept
(
new
JetVisitor
()
{
...
...
@@ -1399,72 +1399,39 @@ public class JetTypeInferrer {
public
void
visitIsExpression
(
JetIsExpression
expression
)
{
if
(
conditionValue
)
{
JetPattern
pattern
=
expression
.
getPattern
();
for
(
VariableDescriptor
variableDescriptor
:
patternsToBoundVariableLists
.
get
(
pattern
))
{
scopeToExtend
.
addVariableDescriptor
(
variableDescriptor
);
}
result
[
0
]
=
patternsToDataFlowInfo
.
get
(
pattern
);
if
(
scopeToExtend
!=
null
)
{
for
(
VariableDescriptor
variableDescriptor
:
patternsToBoundVariableLists
.
get
(
pattern
))
{
scopeToExtend
.
addVariableDescriptor
(
variableDescriptor
);
}
}
}
}
@Override
public
void
visitBinaryExpression
(
JetBinaryExpression
expression
)
{
IElementType
operationToken
=
expression
.
getOperationToken
();
if
(
operationToken
==
JetTokens
.
ANDAND
)
{
DataFlowInfo
dataFlowInfo
=
extractDataFlowInfoFromCondition
(
expression
.
getLeft
(),
conditionValue
,
scopeToExtend
);
JetExpression
expressionRight
=
expression
.
getRight
();
if
(
expressionRight
!=
null
)
{
DataFlowInfo
rightInfo
=
extractDataFlowInfoFromCondition
(
expressionRight
,
conditionValue
,
scopeToExtend
);
DataFlowInfo
.
CompositionOperator
operator
=
conditionValue
?
DataFlowInfo
.
AND
:
DataFlowInfo
.
OR
;
dataFlowInfo
=
operator
.
compose
(
dataFlowInfo
,
rightInfo
);
if
(
operationToken
==
JetTokens
.
ANDAND
||
operationToken
==
JetTokens
.
OROR
)
{
WritableScope
actualScopeToExtend
;
if
(
operationToken
==
JetTokens
.
ANDAND
)
{
actualScopeToExtend
=
conditionValue
?
scopeToExtend
:
null
;
}
// TODO : intersect scopes when condition is false
result
[
0
]
=
dataFlowInfo
;
}
else
if
(
operationToken
==
JetTokens
.
OROR
)
{
WritableScopeImpl
leftScope
=
newWritableScopeImpl
(
scopeToExtend
);
DataFlowInfo
dataFlowInfo
=
extractDataFlowInfoFromCondition
(
expression
.
getLeft
(),
conditionValue
,
leftScope
);
else
{
actualScopeToExtend
=
conditionValue
?
null
:
scopeToExtend
;
}
DataFlowInfo
dataFlowInfo
=
extractDataFlowInfoFromCondition
(
expression
.
getLeft
(),
conditionValue
,
actualScopeToExtend
);
JetExpression
expressionRight
=
expression
.
getRight
();
WritableScopeImpl
rightScope
=
newWritableScopeImpl
(
scopeToExtend
);
if
(
expressionRight
!=
null
)
{
DataFlowInfo
rightInfo
=
extractDataFlowInfoFromCondition
(
expressionRight
,
conditionValue
,
rightScope
);
DataFlowInfo
.
CompositionOperator
operator
=
conditionValue
?
DataFlowInfo
.
OR
:
DataFlowInfo
.
AND
;
dataFlowInfo
=
operator
.
compose
(
dataFlowInfo
,
rightInfo
);
}
// TODO : this is incorrect, we need to intersect only when condition is true (and on && and condition being false), and intersect together with dataFlowInfo
if
(
leftScope
.
hasDeclaredItems
()
&&
rightScope
.
hasDeclaredItems
())
{
Map
<
String
,
VariableDescriptor
>
leftVariableMap
=
Maps
.
newHashMap
();
for
(
VariableDescriptor
leftVariable
:
leftScope
.
getDeclaredVariables
())
{
leftVariableMap
.
put
(
leftVariable
.
getName
(),
leftVariable
);
DataFlowInfo
rightInfo
=
extractDataFlowInfoFromCondition
(
expressionRight
,
conditionValue
,
actualScopeToExtend
);
DataFlowInfo
.
CompositionOperator
operator
;
if
(
operationToken
==
JetTokens
.
ANDAND
)
{
operator
=
conditionValue
?
DataFlowInfo
.
AND
:
DataFlowInfo
.
OR
;
}
for
(
VariableDescriptor
rightVariable
:
rightScope
.
getDeclaredVariables
())
{
VariableDescriptor
leftVariable
=
leftVariableMap
.
get
(
rightVariable
.
getName
());
if
(
leftVariable
!=
null
)
{
// TODO : allow only vals
JetType
leftType
=
leftVariable
.
getOutType
();
if
(
leftType
==
null
)
{
continue
;
}
JetType
rightType
=
rightVariable
.
getOutType
();
if
(
rightType
==
null
)
{
continue
;
}
List
<
JetType
>
leftPossibleTypes
=
dataFlowInfo
.
getPossibleTypes
(
leftVariable
);
List
<
JetType
>
rightPossibleTypes
=
dataFlowInfo
.
getPossibleTypes
(
rightVariable
);
VariableDescriptor
variable
;
if
(
semanticServices
.
getTypeChecker
().
isSubtypeOf
(
rightType
,
leftType
))
{
variable
=
leftVariable
;
}
else
if
(
semanticServices
.
getTypeChecker
().
isSubtypeOf
(
leftType
,
rightType
))
{
variable
=
rightVariable
;
}
else
{
continue
;
}
scopeToExtend
.
addVariableDescriptor
(
variable
);
}
else
{
operator
=
conditionValue
?
DataFlowInfo
.
OR
:
DataFlowInfo
.
AND
;
}
dataFlowInfo
=
operator
.
compose
(
dataFlowInfo
,
rightInfo
);
}
result
[
0
]
=
dataFlowInfo
;
}
...
...
@@ -1571,8 +1538,8 @@ public class JetTypeInferrer {
getType
(
scopeToExtend
,
body
,
true
,
conditionInfo
);
}
if
(!
flowInformationProvider
.
isBreakable
(
expression
))
{
resultScope
=
newWritableScopeImpl
();
resultDataFlowInfo
=
extractDataFlowInfoFromCondition
(
condition
,
false
,
resultScope
);
//
resultScope = newWritableScopeImpl();
resultDataFlowInfo
=
extractDataFlowInfoFromCondition
(
condition
,
false
,
null
);
}
result
=
JetStandardClasses
.
getUnitType
();
}
...
...
@@ -1600,8 +1567,8 @@ public class JetTypeInferrer {
JetExpression
condition
=
expression
.
getCondition
();
checkCondition
(
conditionScope
,
condition
);
if
(!
flowInformationProvider
.
isBreakable
(
expression
))
{
resultScope
=
newWritableScopeImpl
();
resultDataFlowInfo
=
extractDataFlowInfoFromCondition
(
condition
,
false
,
resultScope
);
//
resultScope = newWritableScopeImpl();
resultDataFlowInfo
=
extractDataFlowInfoFromCondition
(
condition
,
false
,
null
);
}
result
=
JetStandardClasses
.
getUnitType
();
}
...
...
idea/testData/checker/infos/Autocasts.jet
浏览文件 @
400e939c
...
...
@@ -117,29 +117,33 @@ fun f13(a : A?) {
<error>c</error>.bar()
}
// a?.foo()
// if ((a is val c is B) || (a is val c is A)) {
// c.foo()
// c.bar()
// }
// else {
// a?.foo()
// c.bar()
// }
if (!(a is val c is B) || !(a is val x is C)) {
<error>x</error>
<error>c</error>
}
else {
<info descr="Automatically cast to C">x</info>.bar()
<info descr="Automatically cast to B">c</info>.bar()
}
if (!(a is val <error>c</error> is B) || !(a is val <error>c</error> is C)) {
}
if (!(a is val c is B)) return
<info descr="Automatically cast to B">a</info>.bar()
c
.foo()
<
info descr="Automatically cast to B">c</info
>.bar()
<error>c</error>
.foo()
<
error>c</error
>.bar()
}
fun f14(a : A?) {
while (!(a is val c is B)) {
}
<info descr="Automatically cast to B">c</info>.bar()
<info descr="Automatically cast to B">a</info>.bar()
<error>c</error>.bar()
}
fun f15(a : A?) {
do {
} while (!(a is val c is B))
<info descr="Automatically cast to B">c</info>.bar()
<info descr="Automatically cast to B">a</info>.bar()
<error>c</error>.bar()
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录