Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
硅谷海盗
kotlin
提交
d4b1658b
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,发现更多精彩内容 >>
提交
d4b1658b
编写于
6月 12, 2011
作者:
A
Andrey Breslav
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Autocasts & binding patterns in 'when'-expressions
上级
75365016
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
335 addition
and
223 deletion
+335
-223
idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java
...c/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java
+10
-0
idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java
.../org/jetbrains/jet/lang/parsing/JetExpressionParsing.java
+24
-9
idea/src/org/jetbrains/jet/lang/psi/JetBindingPattern.java
idea/src/org/jetbrains/jet/lang/psi/JetBindingPattern.java
+13
-4
idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java
idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java
+4
-0
idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java
...g/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java
+6
-1
idea/src/org/jetbrains/jet/lang/types/ErrorUtils.java
idea/src/org/jetbrains/jet/lang/types/ErrorUtils.java
+1
-1
idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java
idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java
+1
-1
idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java
idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java
+111
-86
idea/testData/checker/infos/Autocasts.jet
idea/testData/checker/infos/Autocasts.jet
+22
-0
idea/testData/psi/AttributesOnPatterns.txt
idea/testData/psi/AttributesOnPatterns.txt
+16
-13
idea/testData/psi/When.txt
idea/testData/psi/When.txt
+127
-108
未找到文件。
idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java
浏览文件 @
d4b1658b
...
...
@@ -641,6 +641,8 @@ public class JetControlFlowProcessor {
JetWhenCondition
condition
=
whenEntry
.
getCondition
();
if
(
condition
!=
null
)
{
condition
.
accept
(
new
JetVisitor
()
{
private
final
JetVisitor
conditionVisitor
=
this
;
@Override
public
void
visitWhenConditionWithExpression
(
JetWhenConditionWithExpression
condition
)
{
value
(
condition
.
getExpression
(),
false
,
inCondition
);
// TODO : inCondition?
...
...
@@ -689,6 +691,14 @@ public class JetControlFlowProcessor {
pattern
.
getArgumentList
().
accept
(
this
);
}
@Override
public
void
visitBindingPattern
(
JetBindingPattern
pattern
)
{
JetWhenCondition
condition
=
pattern
.
getCondition
();
if
(
condition
!=
null
)
{
condition
.
accept
(
conditionVisitor
);
}
}
@Override
public
void
visitJetElement
(
JetElement
element
)
{
throw
new
UnsupportedOperationException
(
"[JetControlFlowProcessor] "
+
element
.
toString
());
...
...
idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java
浏览文件 @
d4b1658b
...
...
@@ -886,22 +886,37 @@ public class JetExpressionParsing extends AbstractJetParsing {
private
void
parseBindingPattern
()
{
assert
_at
(
VAL_KEYWORD
);
PsiBuilder
.
Marker
declaration
=
mark
();
advance
();
// VAL_KEYWORD
expect
(
IDENTIFIER
,
"Expecting an identifier"
);
if
(
at
(
IS_KEYWORD
)
||
at
(
NOT_IS
))
{
advance
();
// IS_KEYWORD or NOT_IS
parsePattern
();
}
else
if
(
at
(
IN_KEYWORD
)
||
at
(
NOT_IN
))
{
advance
();
// IN_KEYWORD ot NOT_IN
parseExpression
();
}
else
if
(
at
(
COLON
))
{
if
(
at
(
COLON
))
{
advance
();
// EQ
myJetParsing
.
parseTypeRef
();
declaration
.
done
(
PROPERTY
);
}
else
{
declaration
.
done
(
PROPERTY
);
PsiBuilder
.
Marker
subCondition
=
mark
();
if
(
at
(
IS_KEYWORD
)
||
at
(
NOT_IS
))
{
advance
();
// IS_KEYWORD or NOT_IS
parsePattern
();
subCondition
.
done
(
WHEN_CONDITION_IS_PATTERN
);
}
else
if
(
at
(
IN_KEYWORD
)
||
at
(
NOT_IN
))
{
PsiBuilder
.
Marker
mark
=
mark
();
advance
();
// IN_KEYWORD ot NOT_IN
mark
.
done
(
OPERATION_REFERENCE
);
parseExpression
();
subCondition
.
done
(
WHEN_CONDITION_IN_RANGE
);
}
else
{
subCondition
.
drop
();
}
}
}
...
...
idea/src/org/jetbrains/jet/lang/psi/JetBindingPattern.java
浏览文件 @
d4b1658b
...
...
@@ -2,7 +2,8 @@ package org.jetbrains.jet.lang.psi;
import
com.intellij.lang.ASTNode
;
import
org.jetbrains.annotations.NotNull
;
import
org.jetbrains.jet.lexer.JetTokens
;
import
org.jetbrains.annotations.Nullable
;
import
org.jetbrains.jet.JetNodeTypes
;
/**
* @author abreslav
...
...
@@ -12,10 +13,18 @@ public class JetBindingPattern extends JetPattern {
super
(
node
);
}
public
boolean
isVar
()
{
return
findChildByType
(
JetTokens
.
VAR_KEYWORD
)
!=
null
;
@NotNull
public
JetProperty
getVariableDeclaration
()
{
return
(
JetProperty
)
findChildByType
(
JetNodeTypes
.
PROPERTY
);
}
@Nullable
public
JetWhenCondition
getCondition
()
{
return
findChildByClass
(
JetWhenCondition
.
class
);
}
@Override
public
void
accept
(
@NotNull
JetVisitor
visitor
)
{
visitor
.
visitBindingPattern
(
this
);
}
}
idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java
浏览文件 @
d4b1658b
...
...
@@ -397,4 +397,8 @@ public class JetVisitor extends PsiElementVisitor {
public
void
visitObjectDeclaration
(
JetObjectDeclaration
declaration
)
{
visitNamedDeclaration
(
declaration
);
}
public
void
visitBindingPattern
(
JetBindingPattern
pattern
)
{
visitPattern
(
pattern
);
}
}
idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java
浏览文件 @
d4b1658b
...
...
@@ -413,9 +413,14 @@ public class ClassDescriptorResolver {
}
@NotNull
public
VariableDescriptor
resolveLocalVariableDescriptor
(
DeclarationDescriptor
containingDeclaration
,
Writable
Scope
scope
,
JetProperty
property
)
{
public
VariableDescriptor
resolveLocalVariableDescriptor
(
DeclarationDescriptor
containingDeclaration
,
Jet
Scope
scope
,
JetProperty
property
)
{
JetType
type
=
getVariableType
(
scope
,
property
,
false
);
// For a local variable the type must not be deferred
return
resolveLocalVariableDescriptorWithType
(
containingDeclaration
,
property
,
type
);
}
@NotNull
public
VariableDescriptor
resolveLocalVariableDescriptorWithType
(
DeclarationDescriptor
containingDeclaration
,
JetProperty
property
,
JetType
type
)
{
VariableDescriptorImpl
variableDescriptor
=
new
LocalVariableDescriptor
(
containingDeclaration
,
AnnotationResolver
.
INSTANCE
.
resolveAnnotations
(
property
.
getModifierList
()),
...
...
idea/src/org/jetbrains/jet/lang/types/ErrorUtils.java
浏览文件 @
d4b1658b
...
...
@@ -160,7 +160,7 @@ public class ErrorUtils {
}
private
static
JetType
createErrorType
(
String
debugMessage
,
JetScope
memberScope
)
{
return
new
ErrorTypeImpl
(
new
TypeConstructorImpl
(
ERROR_CLASS
,
Collections
.<
Annotation
>
emptyList
(),
false
,
"[ERROR : "
+
debugMessage
+
"]"
,
Collections
.<
TypeParameterDescriptor
>
emptyList
(),
Collections
.
<
JetType
>
emptyList
(
)),
memberScope
);
return
new
ErrorTypeImpl
(
new
TypeConstructorImpl
(
ERROR_CLASS
,
Collections
.<
Annotation
>
emptyList
(),
false
,
"[ERROR : "
+
debugMessage
+
"]"
,
Collections
.<
TypeParameterDescriptor
>
emptyList
(),
Collections
.
singleton
(
JetStandardClasses
.
getAnyType
()
)),
memberScope
);
}
public
static
JetType
createWrongVarianceErrorType
(
TypeProjection
value
)
{
...
...
idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java
浏览文件 @
d4b1658b
...
...
@@ -104,7 +104,7 @@ public class JetTypeChecker {
}
commonSupertypes
=
computeCommonRawSupertypes
(
merge
);
}
assert
!
commonSupertypes
.
isEmpty
()
:
types
;
assert
!
commonSupertypes
.
isEmpty
()
:
commonSupertypes
+
" <- "
+
types
;
Map
.
Entry
<
TypeConstructor
,
Set
<
JetType
>>
entry
=
commonSupertypes
.
entrySet
().
iterator
().
next
();
JetType
result
=
computeSupertypeProjections
(
entry
.
getKey
(),
entry
.
getValue
());
...
...
idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java
浏览文件 @
d4b1658b
...
...
@@ -378,23 +378,6 @@ public class JetTypeInferrer {
return
result
;
}
private
void
collectAllReturnTypes
(
JetWhenExpression
whenExpression
,
JetScope
scope
,
List
<
JetType
>
result
)
{
for
(
JetWhenEntry
entry
:
whenExpression
.
getEntries
())
{
JetWhenExpression
subWhen
=
entry
.
getSubWhen
();
if
(
subWhen
!=
null
)
{
collectAllReturnTypes
(
subWhen
,
scope
,
result
);
}
else
{
JetExpression
resultExpression
=
entry
.
getExpression
();
if
(
resultExpression
!=
null
)
{
JetType
type
=
getType
(
scope
,
resultExpression
,
true
);
if
(
type
!=
null
)
{
result
.
add
(
type
);
}
}
}
}
}
@Nullable
private
JetType
resolveCall
(
@NotNull
JetScope
scope
,
...
...
@@ -1105,96 +1088,102 @@ public class JetTypeInferrer {
// TODO :change scope according to the bound value in the when header
final
JetExpression
subjectExpression
=
expression
.
getSubjectExpression
();
JetType
subjectType
=
null
;
if
(
subjectExpression
!=
null
)
{
subjectType
=
getType
(
scope
,
subjectExpression
,
false
);
}
final
JetType
subjectType
=
subjectExpression
!=
null
?
safeGetType
(
scope
,
subjectExpression
,
false
)
:
ErrorUtils
.
createErrorType
(
"Unknown type"
);
final
VariableDescriptor
variableDescriptor
=
subjectExpression
!=
null
?
getVariableDescriptorFromSimpleName
(
subjectExpression
)
:
null
;
// TODO : exhaustive patterns
Set
<
JetType
>
expressionTypes
=
Sets
.
newHashSet
();
for
(
JetWhenEntry
whenEntry
:
expression
.
getEntries
())
{
final
JetType
finalSubjectType
=
subjectType
!=
null
?
subjectType
:
ErrorUtils
.
createErrorType
(
"Unknown type"
);
JetWhenCondition
condition
=
whenEntry
.
getCondition
();
WritableScope
scopeToExtend
=
new
WritableScopeImpl
(
scope
,
scope
.
getContainingDeclaration
(),
trace
.
getErrorHandler
());
DataFlowInfo
newDataFlowInfo
=
dataFlowInfo
;
if
(
condition
!=
null
)
{
condition
.
accept
(
new
JetVisitor
()
{
@Override
public
void
visitWhenConditionWithExpression
(
JetWhenConditionWithExpression
condition
)
{
JetExpression
conditionExpression
=
condition
.
getExpression
();
if
(
conditionExpression
!=
null
)
{
JetType
type
=
getType
(
scope
,
conditionExpression
,
false
);
if
(
type
!=
null
&&
finalSubjectType
!=
null
)
{
if
(
TypeUtils
.
intersect
(
semanticServices
.
getTypeChecker
(),
Sets
.
newHashSet
(
finalSubjectType
,
type
))
==
null
)
{
trace
.
getErrorHandler
().
genericError
(
conditionExpression
.
getNode
(),
"This condition can never hold"
);
}
}
}
}
@Override
public
void
visitWhenConditionCall
(
JetWhenConditionCall
condition
)
{
JetExpression
callSuffixExpression
=
condition
.
getCallSuffixExpression
();
JetScope
compositeScope
=
new
ScopeWithReceiver
(
scope
,
finalSubjectType
,
semanticServices
.
getTypeChecker
());
if
(
callSuffixExpression
!=
null
)
{
JetType
selectorReturnType
=
getType
(
compositeScope
,
callSuffixExpression
,
false
);
ensureBooleanResultWithCustomSubject
(
callSuffixExpression
,
selectorReturnType
,
"This expression"
);
checkNullSafety
(
finalSubjectType
,
condition
.
getOperationTokenNode
(),
getCalleeFunctionDescriptor
(
callSuffixExpression
));
}
}
@Override
public
void
visitWhenConditionInRange
(
JetWhenConditionInRange
condition
)
{
JetExpression
rangeExpression
=
condition
.
getRangeExpression
();
if
(
rangeExpression
!=
null
)
{
checkInExpression
(
condition
.
getOperationReference
(),
subjectExpression
,
rangeExpression
);
}
}
@Override
public
void
visitWhenConditionIsPattern
(
JetWhenConditionIsPattern
condition
)
{
JetPattern
pattern
=
condition
.
getPattern
();
if
(
pattern
!=
null
)
{
checkPatternType
(
pattern
,
finalSubjectType
);
}
}
@Override
public
void
visitJetElement
(
JetElement
element
)
{
trace
.
getErrorHandler
().
genericError
(
element
.
getNode
(),
"Unsupported [JetTypeInferrer] : "
+
element
);
}
});
newDataFlowInfo
=
checkWhenCondition
(
subjectExpression
,
subjectType
,
variableDescriptor
,
condition
,
scopeToExtend
);
}
JetWhenExpression
subWhen
=
whenEntry
.
getSubWhen
();
JetExpression
bodyExpression
=
subWhen
==
null
?
whenEntry
.
getExpression
()
:
subWhen
;
if
(
bodyExpression
!=
null
)
{
JetType
type
=
getType
(
scopeToExtend
,
bodyExpression
,
false
,
newDataFlowInfo
);
if
(
type
!=
null
)
{
expressionTypes
.
add
(
type
);
}
}
}
List
<
JetType
>
expressionTypes
=
new
ArrayList
<
JetType
>();
collectAllReturnTypes
(
expression
,
scope
,
expressionTypes
);
if
(!
expressionTypes
.
isEmpty
())
{
result
=
semanticServices
.
getTypeChecker
().
commonSupertype
(
expressionTypes
);
}
else
{
else
if
(
expression
.
getEntries
().
isEmpty
())
{
trace
.
getErrorHandler
().
genericError
(
expression
.
getNode
(),
"Entries required for when-expression"
);
// TODO : Scope, and maybe this should not an error
}
}
private
void
checkPatternType
(
@NotNull
JetPattern
pattern
,
@NotNull
final
JetType
subjectType
)
{
pattern
.
accept
(
new
JetVisitor
()
{
private
DataFlowInfo
checkWhenCondition
(
@Nullable
final
JetExpression
subjectExpression
,
final
JetType
subjectType
,
final
VariableDescriptor
variableDescriptor
,
JetWhenCondition
condition
,
final
WritableScope
scopeToExtend
)
{
final
DataFlowInfo
[]
newDataFlowInfo
=
new
DataFlowInfo
[]{
dataFlowInfo
};
condition
.
accept
(
new
JetVisitor
()
{
@Override
public
void
visitTypePattern
(
JetTypePattern
typePattern
)
{
JetTypeReference
typeReference
=
typePattern
.
getTypeReference
();
if
(
typeReference
!=
null
)
{
JetType
type
=
typeResolver
.
resolveType
(
scope
,
typeReference
);
checkTypeCompatibility
(
type
,
subjectType
,
typePattern
);
public
void
visitWhenConditionWithExpression
(
JetWhenConditionWithExpression
condition
)
{
JetExpression
conditionExpression
=
condition
.
getExpression
();
if
(
conditionExpression
!=
null
)
{
JetType
type
=
getType
(
scope
,
conditionExpression
,
false
);
if
(
type
!=
null
&&
subjectType
!=
null
)
{
if
(
TypeUtils
.
intersect
(
semanticServices
.
getTypeChecker
(),
Sets
.
newHashSet
(
subjectType
,
type
))
==
null
)
{
trace
.
getErrorHandler
().
genericError
(
conditionExpression
.
getNode
(),
"This condition can never hold"
);
}
}
}
}
@Override
public
void
visitWildcardPattern
(
JetWildcardPattern
pattern
)
{
// Nothing
public
void
visitWhenConditionCall
(
JetWhenConditionCall
condition
)
{
JetExpression
callSuffixExpression
=
condition
.
getCallSuffixExpression
();
JetScope
compositeScope
=
new
ScopeWithReceiver
(
scope
,
subjectType
,
semanticServices
.
getTypeChecker
());
if
(
callSuffixExpression
!=
null
)
{
JetType
selectorReturnType
=
getType
(
compositeScope
,
callSuffixExpression
,
false
);
ensureBooleanResultWithCustomSubject
(
callSuffixExpression
,
selectorReturnType
,
"This expression"
);
checkNullSafety
(
subjectType
,
condition
.
getOperationTokenNode
(),
getCalleeFunctionDescriptor
(
callSuffixExpression
));
}
}
@Override
public
void
visitExpressionPattern
(
JetExpressionPattern
pattern
)
{
JetType
type
=
getType
(
scope
,
pattern
.
getExpression
(),
false
);
checkTypeCompatibility
(
type
,
subjectType
,
pattern
);
public
void
visitWhenConditionInRange
(
JetWhenConditionInRange
condition
)
{
JetExpression
rangeExpression
=
condition
.
getRangeExpression
();
if
(
rangeExpression
!=
null
)
{
assert
subjectExpression
!=
null
;
checkInExpression
(
condition
.
getOperationReference
(),
subjectExpression
,
rangeExpression
);
}
}
@Override
public
void
visitWhenConditionIsPattern
(
JetWhenConditionIsPattern
condition
)
{
JetPattern
pattern
=
condition
.
getPattern
();
if
(
pattern
!=
null
)
{
newDataFlowInfo
[
0
]
=
checkPatternType
(
variableDescriptor
,
pattern
,
subjectType
,
scopeToExtend
);
}
}
@Override
public
void
visitJetElement
(
JetElement
element
)
{
trace
.
getErrorHandler
().
genericError
(
element
.
getNode
(),
"Unsupported [JetTypeInferrer] : "
+
element
);
}
});
return
newDataFlowInfo
[
0
];
}
private
DataFlowInfo
checkPatternType
(
@Nullable
final
VariableDescriptor
subjectVariable
,
@NotNull
JetPattern
pattern
,
@NotNull
final
JetType
subjectType
,
@NotNull
final
WritableScope
scopeToExtend
)
{
final
DataFlowInfo
[]
result
=
new
DataFlowInfo
[]
{
dataFlowInfo
};
pattern
.
accept
(
new
JetVisitor
()
{
@Override
public
void
visitTypePattern
(
JetTypePattern
typePattern
)
{
JetTypeReference
typeReference
=
typePattern
.
getTypeReference
();
if
(
typeReference
!=
null
)
{
JetType
type
=
typeResolver
.
resolveType
(
scope
,
typeReference
);
checkTypeCompatibility
(
type
,
subjectType
,
typePattern
);
if
(
subjectVariable
!=
null
)
{
result
[
0
]
=
dataFlowInfo
.
isInstanceOf
(
subjectVariable
,
type
);
}
}
}
@Override
...
...
@@ -1202,7 +1191,7 @@ public class JetTypeInferrer {
List
<
JetTuplePatternEntry
>
entries
=
pattern
.
getEntries
();
TypeConstructor
typeConstructor
=
subjectType
.
getConstructor
();
if
(!
JetStandardClasses
.
getTuple
(
entries
.
size
()).
getTypeConstructor
().
equals
(
typeConstructor
)
||
typeConstructor
.
getParameters
().
size
()
!=
entries
.
size
())
{
||
typeConstructor
.
getParameters
().
size
()
!=
entries
.
size
())
{
trace
.
getErrorHandler
().
genericError
(
pattern
.
getNode
(),
"Type mismatch: subject is of type "
+
subjectType
+
" but the pattern is of type Tuple"
+
entries
.
size
());
// TODO : message
}
else
{
...
...
@@ -1218,7 +1207,7 @@ public class JetTypeInferrer {
JetPattern
entryPattern
=
entry
.
getPattern
();
if
(
entryPattern
!=
null
)
{
checkPatternType
(
entryPattern
,
type
);
result
[
0
]
=
checkPatternType
(
null
,
entryPattern
,
type
,
scopeToExtend
);
}
}
}
...
...
@@ -1228,10 +1217,41 @@ public class JetTypeInferrer {
public
void
visitDecomposerPattern
(
JetDecomposerPattern
pattern
)
{
JetType
selectorReturnType
=
getSelectorReturnType
(
subjectType
,
pattern
.
getDecomposerExpression
());
checkPatternType
(
pattern
.
getArgumentList
(),
selectorReturnType
==
null
?
ErrorUtils
.
createErrorType
(
"No type"
)
:
selectorReturnType
);
result
[
0
]
=
checkPatternType
(
null
,
pattern
.
getArgumentList
(),
selectorReturnType
==
null
?
ErrorUtils
.
createErrorType
(
"No type"
)
:
selectorReturnType
,
scopeToExtend
);
}
@Override
public
void
visitWildcardPattern
(
JetWildcardPattern
pattern
)
{
// Nothing
}
@Override
public
void
visitExpressionPattern
(
JetExpressionPattern
pattern
)
{
JetType
type
=
getType
(
scope
,
pattern
.
getExpression
(),
false
);
checkTypeCompatibility
(
type
,
subjectType
,
pattern
);
}
@Override
public
void
visitBindingPattern
(
JetBindingPattern
pattern
)
{
JetProperty
variableDeclaration
=
pattern
.
getVariableDeclaration
();
JetTypeReference
propertyTypeRef
=
variableDeclaration
.
getPropertyTypeRef
();
JetType
type
=
propertyTypeRef
==
null
?
subjectType
:
typeResolver
.
resolveType
(
scope
,
propertyTypeRef
);
VariableDescriptor
variableDescriptor
=
classDescriptorResolver
.
resolveLocalVariableDescriptorWithType
(
scope
.
getContainingDeclaration
(),
variableDeclaration
,
type
);
scopeToExtend
.
addVariableDescriptor
(
variableDescriptor
);
if
(
propertyTypeRef
!=
null
)
{
if
(!
semanticServices
.
getTypeChecker
().
isSubtypeOf
(
subjectType
,
type
))
{
trace
.
getErrorHandler
().
genericError
(
propertyTypeRef
.
getNode
(),
type
+
" must be a supertype of "
+
subjectType
+
". Use 'is' to match against "
+
type
);
}
}
JetWhenCondition
condition
=
pattern
.
getCondition
();
if
(
condition
!=
null
)
{
result
[
0
]
=
checkWhenCondition
(
null
,
subjectType
,
variableDescriptor
,
condition
,
scopeToExtend
);
}
}
private
void
checkTypeCompatibility
(
@Nullable
JetType
type
,
@NotNull
JetType
subjectType
,
@NotNull
JetElement
reportErrorOn
)
{
// TODO : Take auto casts into account?
if
(
type
==
null
)
{
return
;
}
...
...
@@ -1245,6 +1265,7 @@ public class JetTypeInferrer {
trace
.
getErrorHandler
().
genericError
(
element
.
getNode
(),
"Unsupported [JetTypeInferrer]"
);
}
});
return
result
[
0
];
}
@Override
...
...
@@ -1667,6 +1688,9 @@ public class JetTypeInferrer {
trace
.
recordAutoCast
(
receiverExpression
,
possibleType
);
break
;
}
else
{
errorHandler
.
closeAndReturnCurrentRegion
();
}
}
}
...
...
@@ -1789,6 +1813,7 @@ public class JetTypeInferrer {
@Override
public
void
visitIsExpression
(
JetIsExpression
expression
)
{
// TODO : patterns and everything
// TODO : Unify with WhenExpression
JetType
knownType
=
getType
(
scope
,
expression
.
getLeftHandSide
(),
false
);
JetPattern
pattern
=
expression
.
getPattern
();
if
(
pattern
instanceof
JetTypePattern
)
{
...
...
idea/testData/checker/infos/Autocasts.jet
浏览文件 @
d4b1658b
...
...
@@ -53,3 +53,25 @@ fun f10(a : A?) {
}
}
}
fun f11(a : A?) {
when (a) {
is B => <info descr="Automatically cast to B">a</info>.bar()
is A => a.foo()
is Any => a.foo()
is Any? => a.<error>bar</error>()
else => a?.foo()
}
}
fun f12(a : A?) {
when (a) {
is B => <info descr="Automatically cast to B">a</info>.bar()
is A => a.foo()
is Any => a.foo();
is Any? => a.<error>bar</error>()
is val c : <error>B</error> => c.foo()
is val c is C => c.foo()
else => a?.foo()
}
}
idea/testData/psi/AttributesOnPatterns.txt
浏览文件 @
d4b1658b
...
...
@@ -35,9 +35,10 @@ JetFile: AttributesOnPatterns.jet
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
...
...
@@ -58,17 +59,19 @@ JetFile: AttributesOnPatterns.jet
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(is)('is')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo')
WHEN_CONDITION_IS_PATTERN
PsiElement(is)('is')
PsiWhiteSpace(' ')
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
...
...
idea/testData/psi/When.txt
浏览文件 @
d4b1658b
...
...
@@ -327,17 +327,19 @@ JetFile: When.jet
PsiElement(is)('is')
PsiWhiteSpace(' ')
BINDING_PATTERN
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(is)('is')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Foo')
WHEN_CONDITION_IS_PATTERN
PsiElement(is)('is')
PsiWhiteSpace(' ')
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Foo')
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
...
...
@@ -352,17 +354,19 @@ JetFile: When.jet
PsiElement(LPAR)('(')
TUPLE_PATTERN_ENTRY
BINDING_PATTERN
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(is)('is')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Foo')
WHEN_CONDITION_IS_PATTERN
PsiElement(is)('is')
PsiWhiteSpace(' ')
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Foo')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
TUPLE_PATTERN_ENTRY
...
...
@@ -473,9 +477,10 @@ JetFile: When.jet
PsiWhiteSpace(' ')
TUPLE_PATTERN_ENTRY
BINDING_PATTERN
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('r')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('r')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
...
...
@@ -686,17 +691,19 @@ JetFile: When.jet
PsiElement(LPAR)('(')
TUPLE_PATTERN_ENTRY
BINDING_PATTERN
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(is)('is')
PsiWhiteSpace(' ')
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
WHEN_CONDITION_IS_PATTERN
PsiElement(is)('is')
PsiWhiteSpace(' ')
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
TUPLE_PATTERN_ENTRY
...
...
@@ -833,17 +840,19 @@ JetFile: When.jet
PsiWhiteSpace(' ')
TUPLE_PATTERN_ENTRY
BINDING_PATTERN
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(is)('is')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Foo')
WHEN_CONDITION_IS_PATTERN
PsiElement(is)('is')
PsiWhiteSpace(' ')
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Foo')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
TUPLE_PATTERN_ENTRY
...
...
@@ -888,19 +897,22 @@ JetFile: When.jet
PsiWhiteSpace(' ')
TUPLE_PATTERN_ENTRY
BINDING_PATTERN
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(in)('in')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
BINARY_EXPRESSION
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
WHEN_CONDITION_IN_RANGE
OPERATION_REFERENCE
PsiElement(RANGE)('..')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('2')
PsiElement(in)('in')
PsiWhiteSpace(' ')
BINARY_EXPRESSION
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
OPERATION_REFERENCE
PsiElement(RANGE)('..')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('2')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
TUPLE_PATTERN_ENTRY
...
...
@@ -910,55 +922,59 @@ JetFile: When.jet
PsiWhiteSpace(' ')
TUPLE_PATTERN_ENTRY
BINDING_PATTERN
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('_')
PsiWhiteSpace(' ')
PsiElement(NOT_IS)('!is')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('_')
PsiWhiteSpace(' ')
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Foo')
WHEN_CONDITION_IS_PATTERN
PsiElement(NOT_IS)('!is')
PsiWhiteSpace(' ')
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Foo')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
TUPLE_PATTERN_ENTRY
BINDING_PATTERN
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('bar')
PsiWhiteSpace(' ')
PsiElement(is)('is')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('bar')
PsiWhiteSpace(' ')
DECOMPOSER_PATTERN
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
CALL_EXPRESSION
WHEN_CONDITION_IS_PATTERN
PsiElement(is)('is')
PsiWhiteSpace(' ')
DECOMPOSER_PATTERN
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_PROJECTION
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(GT)('>')
PsiWhiteSpace(' ')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
DECOMPOSER_ARGUMENT_LIST
PsiElement(LPAR)('(')
TUPLE_PATTERN_ENTRY
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(GT)('>')
PsiWhiteSpace(' ')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
DECOMPOSER_ARGUMENT_LIST
PsiElement(LPAR)('(')
TUPLE_PATTERN_ENTRY
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(RPAR)(')')
PsiElement(RPAR)(')')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
...
...
@@ -998,16 +1014,17 @@ JetFile: When.jet
PsiElement(is)('is')
PsiWhiteSpace(' ')
BINDING_PATTERN
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Foo')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Foo')
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
...
...
@@ -1088,9 +1105,10 @@ JetFile: When.jet
PsiWhiteSpace(' ')
TUPLE_PATTERN_ENTRY
BINDING_PATTERN
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('r')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('r')
PsiElement(RPAR)(')')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
...
...
@@ -1208,9 +1226,10 @@ JetFile: When.jet
PsiElement(LPAR)('(')
TUPLE_PATTERN_ENTRY
BINDING_PATTERN
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('b')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('b')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
TUPLE_PATTERN_ENTRY
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录