Refactor PSI for destructuring declarations in for: they are now children of KtParameter and not instead of it

This commit is contained in:
Mikhail Glukhikh
2016-10-03 17:19:41 +03:00
parent 48437d5965
commit e7d290f726
35 changed files with 786 additions and 753 deletions
@@ -735,7 +735,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
public void beforeLoop() {
KtParameter loopParameter = forExpression.getLoopParameter();
if (loopParameter != null) {
if (loopParameter == null) return;
KtDestructuringDeclaration multiParameter = loopParameter.getDestructuringDeclaration();
if (multiParameter != null) {
// E tmp<e> = tmp<iterator>.next()
loopParameterType = asmElementType;
loopParameterVar = createLoopTempVariable(asmElementType);
}
else {
// E e = tmp<iterator>.next()
final VariableDescriptor parameterDescriptor = bindingContext.get(VALUE_PARAMETER, loopParameter);
loopParameterType = asmType(parameterDescriptor.getType());
@@ -751,14 +758,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
});
}
else {
KtDestructuringDeclaration multiParameter = forExpression.getDestructuringParameter();
assert multiParameter != null;
// E tmp<e> = tmp<iterator>.next()
loopParameterType = asmElementType;
loopParameterVar = createLoopTempVariable(asmElementType);
}
}
public abstract void checkEmptyLoop(@NotNull Label loopExit);
@@ -769,10 +768,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
assignToLoopParameter();
v.mark(loopParameterStartLabel);
if (forExpression.getLoopParameter() == null) {
KtDestructuringDeclaration multiParameter = forExpression.getDestructuringParameter();
assert multiParameter != null;
KtDestructuringDeclaration multiParameter = forExpression.getDestructuringDeclaration();
if (multiParameter != null) {
generateMultiVariables(multiParameter.getEntries());
}
}
@@ -773,18 +773,19 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
private fun declareLoopParameter(expression: KtForExpression) {
val loopParameter = expression.loopParameter
val multiDeclaration = expression.destructuringParameter
if (loopParameter != null) {
builder.declareParameter(loopParameter)
}
else if (multiDeclaration != null) {
visitDestructuringDeclaration(multiDeclaration, false)
val destructuringDeclaration = loopParameter.destructuringDeclaration
if (destructuringDeclaration != null) {
visitDestructuringDeclaration(destructuringDeclaration, false)
}
else {
builder.declareParameter(loopParameter)
}
}
}
private fun writeLoopParameterAssignment(expression: KtForExpression) {
val loopParameter = expression.loopParameter
val multiDeclaration = expression.destructuringParameter
val loopRange = expression.loopRange
val value = builder.magic(
@@ -795,11 +796,14 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
).outputValue
if (loopParameter != null) {
generateInitializer(loopParameter, value)
}
else if (multiDeclaration != null) {
for (entry in multiDeclaration.entries) {
generateInitializer(entry, value)
val destructuringDeclaration = loopParameter.destructuringDeclaration
if (destructuringDeclaration != null) {
for (entry in destructuringDeclaration.entries) {
generateInitializer(entry, value)
}
}
else {
generateInitializer(loopParameter, value)
}
}
}
@@ -744,7 +744,6 @@ public interface Errors {
DiagnosticFactory3<KtExpression, DeclarationDescriptor, Visibility, DeclarationDescriptor> INVISIBLE_SETTER = DiagnosticFactory3.create(ERROR);
DiagnosticFactory1<PsiElement, KtKeywordToken> VAL_OR_VAR_ON_LOOP_PARAMETER = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, KtKeywordToken> VAL_OR_VAR_ON_LOOP_MULTI_PARAMETER = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, KtKeywordToken> VAL_OR_VAR_ON_FUN_PARAMETER = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, KtKeywordToken> VAL_OR_VAR_ON_CATCH_PARAMETER = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, KtKeywordToken> VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER = DiagnosticFactory1.create(ERROR);
@@ -287,7 +287,6 @@ public class DefaultErrorMessages {
MAP.put(VARIABLE_EXPECTED, "Variable expected");
MAP.put(VAL_OR_VAR_ON_LOOP_PARAMETER, "''{0}'' on loop parameter is not allowed", TO_STRING);
MAP.put(VAL_OR_VAR_ON_LOOP_MULTI_PARAMETER, "''{0}'' on loop multi parameter is not allowed", TO_STRING);
MAP.put(VAL_OR_VAR_ON_FUN_PARAMETER, "''{0}'' on function parameter is not allowed", TO_STRING);
MAP.put(VAL_OR_VAR_ON_CATCH_PARAMETER, "''{0}'' on catch parameter is not allowed", TO_STRING);
MAP.put(VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER, "''{0}'' on secondary constructor parameter is not allowed", TO_STRING);
@@ -1386,8 +1386,9 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) advance(); // VAL_KEYWORD or VAR_KEYWORD
if (at(LPAR)) {
PsiBuilder.Marker destructuringDeclaration = mark();
myKotlinParsing.parseMultiDeclarationName(TokenSet.create(IN_KEYWORD, LBRACE));
parameter.done(DESTRUCTURING_DECLARATION);
destructuringDeclaration.done(DESTRUCTURING_DECLARATION);
}
else {
expect(IDENTIFIER, "Expecting a variable name", TokenSet.create(COLON, IN_KEYWORD));
@@ -1396,8 +1397,8 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
advance(); // COLON
myKotlinParsing.parseTypeRef(TokenSet.create(IN_KEYWORD));
}
parameter.done(VALUE_PARAMETER);
}
parameter.done(VALUE_PARAMETER);
if (expect(IN_KEYWORD, "Expecting 'in'", TokenSet.create(LPAR, LBRACE, RPAR))) {
PsiBuilder.Marker range = mark();
@@ -33,14 +33,16 @@ public class KtForExpression extends KtLoopExpression {
return visitor.visitForExpression(this, data);
}
@Nullable
@Nullable @IfNotParsed
public KtParameter getLoopParameter() {
return (KtParameter) findChildByType(KtNodeTypes.VALUE_PARAMETER);
}
@Nullable
public KtDestructuringDeclaration getDestructuringParameter() {
return (KtDestructuringDeclaration) findChildByType(KtNodeTypes.DESTRUCTURING_DECLARATION);
public KtDestructuringDeclaration getDestructuringDeclaration() {
KtParameter loopParameter = getLoopParameter();
if (loopParameter == null) return null;
return loopParameter.getDestructuringDeclaration();
}
@Nullable @IfNotParsed
@@ -244,9 +244,9 @@ class KtPsiFactory(private val project: Project) {
return (createFunction("fun foo() {$text}").bodyExpression as KtBlockExpression).statements.first() as KtDestructuringDeclaration
}
fun createDestructuringParameter(text: String): KtDestructuringDeclaration {
fun createDestructuringParameterForLoop(text: String): KtParameter {
val dummyFun = createFunction("fun foo() { for ($text in foo) {} }")
return ((dummyFun.bodyExpression as KtBlockExpression).statements.first() as KtForExpression).destructuringParameter!!
return ((dummyFun.bodyExpression as KtBlockExpression).statements.first() as KtForExpression).loopParameter!!
}
fun createDestructuringParameterForLambda(text: String): KtParameter {
@@ -281,7 +281,7 @@ public class KtPsiUtil {
if (declaration instanceof KtProperty) return true;
assert declaration instanceof KtDestructuringDeclarationEntry;
KtDestructuringDeclarationEntry multiDeclarationEntry = (KtDestructuringDeclarationEntry) declaration;
return !(multiDeclarationEntry.getParent().getParent() instanceof KtForExpression);
return !(multiDeclarationEntry.getParent().getParent().getParent() instanceof KtForExpression);
}
@Nullable
@@ -184,7 +184,10 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
TargetLists.T_TOP_LEVEL_PROPERTY(descriptor.hasBackingField(trace), annotated.hasDelegate())
}
is KtParameter -> {
if (annotated.hasValOrVar())
val destructuringDeclaration = annotated.destructuringDeclaration
if (destructuringDeclaration != null)
TargetLists.T_DESTRUCTURING_DECLARATION
else if (annotated.hasValOrVar())
TargetLists.T_VALUE_PARAMETER_WITH_VAL
else
TargetLists.T_VALUE_PARAMETER_WITHOUT_VAL
@@ -401,22 +401,19 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
KtParameter loopParameter = expression.getLoopParameter();
if (loopParameter != null) {
VariableDescriptor variableDescriptor = createLoopParameterDescriptor(loopParameter, expectedParameterType, context);
components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(loopParameter, variableDescriptor);
ModifiersChecker.ModifiersCheckingProcedure modifiersCheckingProcedure = components.modifiersChecker.withTrace(context.trace);
modifiersCheckingProcedure.checkModifiersForLocalDeclaration(loopParameter, variableDescriptor);
components.identifierChecker.checkDeclaration(loopParameter, context.trace);
loopScope.addVariableDescriptor(variableDescriptor);
}
else {
KtDestructuringDeclaration multiParameter = expression.getDestructuringParameter();
KtDestructuringDeclaration multiParameter = loopParameter.getDestructuringDeclaration();
if (multiParameter != null) {
KotlinType elementType = expectedParameterType == null ? ErrorUtils.createErrorType("Loop range has no type") : expectedParameterType;
TransientReceiver iteratorNextAsReceiver = new TransientReceiver(elementType);
components.annotationResolver.resolveAnnotationsWithArguments(loopScope, multiParameter.getModifierList(), context.trace);
components.annotationResolver.resolveAnnotationsWithArguments(loopScope, loopParameter.getModifierList(), context.trace);
components.destructuringDeclarationResolver.defineLocalVariablesFromDestructuringDeclaration(
loopScope, multiParameter, iteratorNextAsReceiver, loopRange, context
);
components.modifiersChecker.withTrace(context.trace).checkModifiersForDestructuringDeclaration(multiParameter);
components.modifiersChecker.withTrace(context.trace).checkParameterHasNoValOrVar(multiParameter, VAL_OR_VAR_ON_LOOP_MULTI_PARAMETER);
modifiersCheckingProcedure.checkModifiersForDestructuringDeclaration(multiParameter);
components.identifierChecker.checkDeclaration(multiParameter, context.trace);
}
}
@@ -22,11 +22,11 @@ fun f() {
}
for (<!VAL_OR_VAR_ON_LOOP_MULTI_PARAMETER!>val<!> (i,j) in Coll()) {
for (<!VAL_OR_VAR_ON_LOOP_PARAMETER!>val<!> (i,j) in Coll()) {
}
for (<!VAL_OR_VAR_ON_LOOP_MULTI_PARAMETER!>var<!> (i,j) in Coll()) {
for (<!VAL_OR_VAR_ON_LOOP_PARAMETER!>var<!> (i,j) in Coll()) {
}
}
@@ -8,8 +8,8 @@ class A {
}
fun foo(list: List<A>) {
for (<!VAL_OR_VAR_ON_LOOP_MULTI_PARAMETER!>var<!> (c1, c2, c3) in list) {
<!UNUSED_VALUE!>c1 =<!> 1
for (<!VAL_OR_VAR_ON_LOOP_PARAMETER!>var<!> (c1, c2, c3) in list) {
<!UNUSED_VALUE!><!VAL_REASSIGNMENT!>c1<!> =<!> 1
c3 + 1
}
}
File diff suppressed because it is too large Load Diff
+86 -82
View File
@@ -93,39 +93,40 @@ JetFile: forParameters.kt
PsiElement(for)('for')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION_ENTRY
PsiElement(IDENTIFIER)('x')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
DESTRUCTURING_DECLARATION_ENTRY
MODIFIER_LIST
PsiElement(private)('private')
PsiWhiteSpace(' ')
PsiElement(data)('data')
PsiWhiteSpace(' ')
ANNOTATION_ENTRY
PsiElement(AT)('@')
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('ann')
PsiWhiteSpace(' ')
ANNOTATION
PsiElement(AT)('@')
PsiElement(LBRACKET)('[')
VALUE_PARAMETER
DESTRUCTURING_DECLARATION
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION_ENTRY
PsiElement(IDENTIFIER)('x')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
DESTRUCTURING_DECLARATION_ENTRY
MODIFIER_LIST
PsiElement(private)('private')
PsiWhiteSpace(' ')
PsiElement(data)('data')
PsiWhiteSpace(' ')
ANNOTATION_ENTRY
PsiElement(AT)('@')
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('ann')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('y')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
ANNOTATION
PsiElement(AT)('@')
PsiElement(LBRACKET)('[')
ANNOTATION_ENTRY
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('ann')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('y')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(in)('in')
PsiWhiteSpace(' ')
@@ -143,27 +144,28 @@ JetFile: forParameters.kt
PsiElement(for)('for')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION_ENTRY
MODIFIER_LIST
ANNOTATION
PsiElement(AT)('@')
PsiElement(LBRACKET)('[')
ANNOTATION_ENTRY
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('ann')
PsiElement(RBRACKET)(']')
PsiErrorElement:Expecting a name
<empty list>
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
DESTRUCTURING_DECLARATION_ENTRY
PsiElement(IDENTIFIER)('x')
PsiElement(RPAR)(')')
VALUE_PARAMETER
DESTRUCTURING_DECLARATION
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION_ENTRY
MODIFIER_LIST
ANNOTATION
PsiElement(AT)('@')
PsiElement(LBRACKET)('[')
ANNOTATION_ENTRY
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('ann')
PsiElement(RBRACKET)(']')
PsiErrorElement:Expecting a name
<empty list>
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
DESTRUCTURING_DECLARATION_ENTRY
PsiElement(IDENTIFIER)('x')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(in)('in')
PsiWhiteSpace(' ')
@@ -253,7 +255,7 @@ JetFile: forParameters.kt
PsiElement(for)('for')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION
VALUE_PARAMETER
MODIFIER_LIST
ANNOTATION_ENTRY
PsiElement(AT)('@')
@@ -266,23 +268,24 @@ JetFile: forParameters.kt
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION_ENTRY
PsiElement(IDENTIFIER)('x')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
DESTRUCTURING_DECLARATION_ENTRY
MODIFIER_LIST
ANNOTATION_ENTRY
PsiElement(AT)('@')
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Volatile')
DESTRUCTURING_DECLARATION
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION_ENTRY
PsiElement(IDENTIFIER)('x')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('y')
PsiElement(RPAR)(')')
DESTRUCTURING_DECLARATION_ENTRY
MODIFIER_LIST
ANNOTATION_ENTRY
PsiElement(AT)('@')
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Volatile')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('y')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(in)('in')
PsiWhiteSpace(' ')
@@ -377,7 +380,7 @@ JetFile: forParameters.kt
PsiElement(for)('for')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION
VALUE_PARAMETER
MODIFIER_LIST
PsiElement(private)('private')
PsiWhiteSpace(' ')
@@ -391,23 +394,24 @@ JetFile: forParameters.kt
PsiWhiteSpace(' ')
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION_ENTRY
PsiElement(IDENTIFIER)('x')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
DESTRUCTURING_DECLARATION_ENTRY
MODIFIER_LIST
ANNOTATION_ENTRY
PsiElement(AT)('@')
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Volatile')
DESTRUCTURING_DECLARATION
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION_ENTRY
PsiElement(IDENTIFIER)('x')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('y')
PsiElement(RPAR)(')')
DESTRUCTURING_DECLARATION_ENTRY
MODIFIER_LIST
ANNOTATION_ENTRY
PsiElement(AT)('@')
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Volatile')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('y')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(in)('in')
PsiWhiteSpace(' ')
@@ -18,15 +18,16 @@ JetFile: WithWithoutInAndMultideclaration.kt
PsiElement(for)('for')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION_ENTRY
PsiElement(IDENTIFIER)('i')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
DESTRUCTURING_DECLARATION_ENTRY
PsiElement(IDENTIFIER)('j')
PsiElement(RPAR)(')')
VALUE_PARAMETER
DESTRUCTURING_DECLARATION
PsiElement(LPAR)('(')
DESTRUCTURING_DECLARATION_ENTRY
PsiElement(IDENTIFIER)('i')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
DESTRUCTURING_DECLARATION_ENTRY
PsiElement(IDENTIFIER)('j')
PsiElement(RPAR)(')')
PsiErrorElement:Expecting 'in'
<empty list>
PsiElement(RPAR)(')')