Refactor PSI for destructuring declarations in for: they are now children of KtParameter and not instead of it
This commit is contained in:
@@ -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);
|
||||
|
||||
-1
@@ -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
|
||||
|
||||
+5
-8
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user