Refactor PSI for destructuring declarations in for: they are now children of KtParameter and not instead of it
This commit is contained in:
@@ -735,7 +735,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
public void beforeLoop() {
|
public void beforeLoop() {
|
||||||
KtParameter loopParameter = forExpression.getLoopParameter();
|
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()
|
// E e = tmp<iterator>.next()
|
||||||
final VariableDescriptor parameterDescriptor = bindingContext.get(VALUE_PARAMETER, loopParameter);
|
final VariableDescriptor parameterDescriptor = bindingContext.get(VALUE_PARAMETER, loopParameter);
|
||||||
loopParameterType = asmType(parameterDescriptor.getType());
|
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);
|
public abstract void checkEmptyLoop(@NotNull Label loopExit);
|
||||||
@@ -769,10 +768,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
assignToLoopParameter();
|
assignToLoopParameter();
|
||||||
v.mark(loopParameterStartLabel);
|
v.mark(loopParameterStartLabel);
|
||||||
|
|
||||||
if (forExpression.getLoopParameter() == null) {
|
KtDestructuringDeclaration multiParameter = forExpression.getDestructuringDeclaration();
|
||||||
KtDestructuringDeclaration multiParameter = forExpression.getDestructuringParameter();
|
if (multiParameter != null) {
|
||||||
assert multiParameter != null;
|
|
||||||
|
|
||||||
generateMultiVariables(multiParameter.getEntries());
|
generateMultiVariables(multiParameter.getEntries());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -773,18 +773,19 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
|||||||
|
|
||||||
private fun declareLoopParameter(expression: KtForExpression) {
|
private fun declareLoopParameter(expression: KtForExpression) {
|
||||||
val loopParameter = expression.loopParameter
|
val loopParameter = expression.loopParameter
|
||||||
val multiDeclaration = expression.destructuringParameter
|
|
||||||
if (loopParameter != null) {
|
if (loopParameter != null) {
|
||||||
builder.declareParameter(loopParameter)
|
val destructuringDeclaration = loopParameter.destructuringDeclaration
|
||||||
}
|
if (destructuringDeclaration != null) {
|
||||||
else if (multiDeclaration != null) {
|
visitDestructuringDeclaration(destructuringDeclaration, false)
|
||||||
visitDestructuringDeclaration(multiDeclaration, false)
|
}
|
||||||
|
else {
|
||||||
|
builder.declareParameter(loopParameter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun writeLoopParameterAssignment(expression: KtForExpression) {
|
private fun writeLoopParameterAssignment(expression: KtForExpression) {
|
||||||
val loopParameter = expression.loopParameter
|
val loopParameter = expression.loopParameter
|
||||||
val multiDeclaration = expression.destructuringParameter
|
|
||||||
val loopRange = expression.loopRange
|
val loopRange = expression.loopRange
|
||||||
|
|
||||||
val value = builder.magic(
|
val value = builder.magic(
|
||||||
@@ -795,11 +796,14 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
|||||||
).outputValue
|
).outputValue
|
||||||
|
|
||||||
if (loopParameter != null) {
|
if (loopParameter != null) {
|
||||||
generateInitializer(loopParameter, value)
|
val destructuringDeclaration = loopParameter.destructuringDeclaration
|
||||||
}
|
if (destructuringDeclaration != null) {
|
||||||
else if (multiDeclaration != null) {
|
for (entry in destructuringDeclaration.entries) {
|
||||||
for (entry in multiDeclaration.entries) {
|
generateInitializer(entry, value)
|
||||||
generateInitializer(entry, value)
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
generateInitializer(loopParameter, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -744,7 +744,6 @@ public interface Errors {
|
|||||||
DiagnosticFactory3<KtExpression, DeclarationDescriptor, Visibility, DeclarationDescriptor> INVISIBLE_SETTER = DiagnosticFactory3.create(ERROR);
|
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_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_FUN_PARAMETER = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory1<PsiElement, KtKeywordToken> VAL_OR_VAR_ON_CATCH_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);
|
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(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_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_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_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);
|
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(VAL_KEYWORD) || at(VAR_KEYWORD)) advance(); // VAL_KEYWORD or VAR_KEYWORD
|
||||||
|
|
||||||
if (at(LPAR)) {
|
if (at(LPAR)) {
|
||||||
|
PsiBuilder.Marker destructuringDeclaration = mark();
|
||||||
myKotlinParsing.parseMultiDeclarationName(TokenSet.create(IN_KEYWORD, LBRACE));
|
myKotlinParsing.parseMultiDeclarationName(TokenSet.create(IN_KEYWORD, LBRACE));
|
||||||
parameter.done(DESTRUCTURING_DECLARATION);
|
destructuringDeclaration.done(DESTRUCTURING_DECLARATION);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
expect(IDENTIFIER, "Expecting a variable name", TokenSet.create(COLON, IN_KEYWORD));
|
expect(IDENTIFIER, "Expecting a variable name", TokenSet.create(COLON, IN_KEYWORD));
|
||||||
@@ -1396,8 +1397,8 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
advance(); // COLON
|
advance(); // COLON
|
||||||
myKotlinParsing.parseTypeRef(TokenSet.create(IN_KEYWORD));
|
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))) {
|
if (expect(IN_KEYWORD, "Expecting 'in'", TokenSet.create(LPAR, LBRACE, RPAR))) {
|
||||||
PsiBuilder.Marker range = mark();
|
PsiBuilder.Marker range = mark();
|
||||||
|
|||||||
@@ -33,14 +33,16 @@ public class KtForExpression extends KtLoopExpression {
|
|||||||
return visitor.visitForExpression(this, data);
|
return visitor.visitForExpression(this, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable @IfNotParsed
|
||||||
public KtParameter getLoopParameter() {
|
public KtParameter getLoopParameter() {
|
||||||
return (KtParameter) findChildByType(KtNodeTypes.VALUE_PARAMETER);
|
return (KtParameter) findChildByType(KtNodeTypes.VALUE_PARAMETER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public KtDestructuringDeclaration getDestructuringParameter() {
|
public KtDestructuringDeclaration getDestructuringDeclaration() {
|
||||||
return (KtDestructuringDeclaration) findChildByType(KtNodeTypes.DESTRUCTURING_DECLARATION);
|
KtParameter loopParameter = getLoopParameter();
|
||||||
|
if (loopParameter == null) return null;
|
||||||
|
return loopParameter.getDestructuringDeclaration();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable @IfNotParsed
|
@Nullable @IfNotParsed
|
||||||
|
|||||||
@@ -244,9 +244,9 @@ class KtPsiFactory(private val project: Project) {
|
|||||||
return (createFunction("fun foo() {$text}").bodyExpression as KtBlockExpression).statements.first() as KtDestructuringDeclaration
|
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) {} }")
|
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 {
|
fun createDestructuringParameterForLambda(text: String): KtParameter {
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ public class KtPsiUtil {
|
|||||||
if (declaration instanceof KtProperty) return true;
|
if (declaration instanceof KtProperty) return true;
|
||||||
assert declaration instanceof KtDestructuringDeclarationEntry;
|
assert declaration instanceof KtDestructuringDeclarationEntry;
|
||||||
KtDestructuringDeclarationEntry multiDeclarationEntry = (KtDestructuringDeclarationEntry) declaration;
|
KtDestructuringDeclarationEntry multiDeclarationEntry = (KtDestructuringDeclarationEntry) declaration;
|
||||||
return !(multiDeclarationEntry.getParent().getParent() instanceof KtForExpression);
|
return !(multiDeclarationEntry.getParent().getParent().getParent() instanceof KtForExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -184,7 +184,10 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
|
|||||||
TargetLists.T_TOP_LEVEL_PROPERTY(descriptor.hasBackingField(trace), annotated.hasDelegate())
|
TargetLists.T_TOP_LEVEL_PROPERTY(descriptor.hasBackingField(trace), annotated.hasDelegate())
|
||||||
}
|
}
|
||||||
is KtParameter -> {
|
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
|
TargetLists.T_VALUE_PARAMETER_WITH_VAL
|
||||||
else
|
else
|
||||||
TargetLists.T_VALUE_PARAMETER_WITHOUT_VAL
|
TargetLists.T_VALUE_PARAMETER_WITHOUT_VAL
|
||||||
|
|||||||
+5
-8
@@ -401,22 +401,19 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
KtParameter loopParameter = expression.getLoopParameter();
|
KtParameter loopParameter = expression.getLoopParameter();
|
||||||
if (loopParameter != null) {
|
if (loopParameter != null) {
|
||||||
VariableDescriptor variableDescriptor = createLoopParameterDescriptor(loopParameter, expectedParameterType, context);
|
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);
|
components.identifierChecker.checkDeclaration(loopParameter, context.trace);
|
||||||
|
|
||||||
loopScope.addVariableDescriptor(variableDescriptor);
|
loopScope.addVariableDescriptor(variableDescriptor);
|
||||||
}
|
KtDestructuringDeclaration multiParameter = loopParameter.getDestructuringDeclaration();
|
||||||
else {
|
|
||||||
KtDestructuringDeclaration multiParameter = expression.getDestructuringParameter();
|
|
||||||
if (multiParameter != null) {
|
if (multiParameter != null) {
|
||||||
KotlinType elementType = expectedParameterType == null ? ErrorUtils.createErrorType("Loop range has no type") : expectedParameterType;
|
KotlinType elementType = expectedParameterType == null ? ErrorUtils.createErrorType("Loop range has no type") : expectedParameterType;
|
||||||
TransientReceiver iteratorNextAsReceiver = new TransientReceiver(elementType);
|
TransientReceiver iteratorNextAsReceiver = new TransientReceiver(elementType);
|
||||||
components.annotationResolver.resolveAnnotationsWithArguments(loopScope, multiParameter.getModifierList(), context.trace);
|
components.annotationResolver.resolveAnnotationsWithArguments(loopScope, loopParameter.getModifierList(), context.trace);
|
||||||
components.destructuringDeclarationResolver.defineLocalVariablesFromDestructuringDeclaration(
|
components.destructuringDeclarationResolver.defineLocalVariablesFromDestructuringDeclaration(
|
||||||
loopScope, multiParameter, iteratorNextAsReceiver, loopRange, context
|
loopScope, multiParameter, iteratorNextAsReceiver, loopRange, context
|
||||||
);
|
);
|
||||||
components.modifiersChecker.withTrace(context.trace).checkModifiersForDestructuringDeclaration(multiParameter);
|
modifiersCheckingProcedure.checkModifiersForDestructuringDeclaration(multiParameter);
|
||||||
components.modifiersChecker.withTrace(context.trace).checkParameterHasNoValOrVar(multiParameter, VAL_OR_VAR_ON_LOOP_MULTI_PARAMETER);
|
|
||||||
components.identifierChecker.checkDeclaration(multiParameter, context.trace);
|
components.identifierChecker.checkDeclaration(multiParameter, context.trace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -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()) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -8,8 +8,8 @@ class A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun foo(list: List<A>) {
|
fun foo(list: List<A>) {
|
||||||
for (<!VAL_OR_VAR_ON_LOOP_MULTI_PARAMETER!>var<!> (c1, c2, c3) in list) {
|
for (<!VAL_OR_VAR_ON_LOOP_PARAMETER!>var<!> (c1, c2, c3) in list) {
|
||||||
<!UNUSED_VALUE!>c1 =<!> 1
|
<!UNUSED_VALUE!><!VAL_REASSIGNMENT!>c1<!> =<!> 1
|
||||||
c3 + 1
|
c3 + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+608
-586
File diff suppressed because it is too large
Load Diff
+86
-82
@@ -93,39 +93,40 @@ JetFile: forParameters.kt
|
|||||||
PsiElement(for)('for')
|
PsiElement(for)('for')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(LPAR)('(')
|
PsiElement(LPAR)('(')
|
||||||
DESTRUCTURING_DECLARATION
|
VALUE_PARAMETER
|
||||||
PsiElement(LPAR)('(')
|
DESTRUCTURING_DECLARATION
|
||||||
DESTRUCTURING_DECLARATION_ENTRY
|
PsiElement(LPAR)('(')
|
||||||
PsiElement(IDENTIFIER)('x')
|
DESTRUCTURING_DECLARATION_ENTRY
|
||||||
PsiElement(COMMA)(',')
|
PsiElement(IDENTIFIER)('x')
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(COMMA)(',')
|
||||||
DESTRUCTURING_DECLARATION_ENTRY
|
PsiWhiteSpace(' ')
|
||||||
MODIFIER_LIST
|
DESTRUCTURING_DECLARATION_ENTRY
|
||||||
PsiElement(private)('private')
|
MODIFIER_LIST
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(private)('private')
|
||||||
PsiElement(data)('data')
|
PsiWhiteSpace(' ')
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(data)('data')
|
||||||
ANNOTATION_ENTRY
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(AT)('@')
|
|
||||||
CONSTRUCTOR_CALLEE
|
|
||||||
TYPE_REFERENCE
|
|
||||||
USER_TYPE
|
|
||||||
REFERENCE_EXPRESSION
|
|
||||||
PsiElement(IDENTIFIER)('ann')
|
|
||||||
PsiWhiteSpace(' ')
|
|
||||||
ANNOTATION
|
|
||||||
PsiElement(AT)('@')
|
|
||||||
PsiElement(LBRACKET)('[')
|
|
||||||
ANNOTATION_ENTRY
|
ANNOTATION_ENTRY
|
||||||
|
PsiElement(AT)('@')
|
||||||
CONSTRUCTOR_CALLEE
|
CONSTRUCTOR_CALLEE
|
||||||
TYPE_REFERENCE
|
TYPE_REFERENCE
|
||||||
USER_TYPE
|
USER_TYPE
|
||||||
REFERENCE_EXPRESSION
|
REFERENCE_EXPRESSION
|
||||||
PsiElement(IDENTIFIER)('ann')
|
PsiElement(IDENTIFIER)('ann')
|
||||||
PsiElement(RBRACKET)(']')
|
PsiWhiteSpace(' ')
|
||||||
PsiWhiteSpace(' ')
|
ANNOTATION
|
||||||
PsiElement(IDENTIFIER)('y')
|
PsiElement(AT)('@')
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(LBRACKET)('[')
|
||||||
|
ANNOTATION_ENTRY
|
||||||
|
CONSTRUCTOR_CALLEE
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('ann')
|
||||||
|
PsiElement(RBRACKET)(']')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('y')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(in)('in')
|
PsiElement(in)('in')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
@@ -143,27 +144,28 @@ JetFile: forParameters.kt
|
|||||||
PsiElement(for)('for')
|
PsiElement(for)('for')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(LPAR)('(')
|
PsiElement(LPAR)('(')
|
||||||
DESTRUCTURING_DECLARATION
|
VALUE_PARAMETER
|
||||||
PsiElement(LPAR)('(')
|
DESTRUCTURING_DECLARATION
|
||||||
DESTRUCTURING_DECLARATION_ENTRY
|
PsiElement(LPAR)('(')
|
||||||
MODIFIER_LIST
|
DESTRUCTURING_DECLARATION_ENTRY
|
||||||
ANNOTATION
|
MODIFIER_LIST
|
||||||
PsiElement(AT)('@')
|
ANNOTATION
|
||||||
PsiElement(LBRACKET)('[')
|
PsiElement(AT)('@')
|
||||||
ANNOTATION_ENTRY
|
PsiElement(LBRACKET)('[')
|
||||||
CONSTRUCTOR_CALLEE
|
ANNOTATION_ENTRY
|
||||||
TYPE_REFERENCE
|
CONSTRUCTOR_CALLEE
|
||||||
USER_TYPE
|
TYPE_REFERENCE
|
||||||
REFERENCE_EXPRESSION
|
USER_TYPE
|
||||||
PsiElement(IDENTIFIER)('ann')
|
REFERENCE_EXPRESSION
|
||||||
PsiElement(RBRACKET)(']')
|
PsiElement(IDENTIFIER)('ann')
|
||||||
PsiErrorElement:Expecting a name
|
PsiElement(RBRACKET)(']')
|
||||||
<empty list>
|
PsiErrorElement:Expecting a name
|
||||||
PsiElement(COMMA)(',')
|
<empty list>
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(COMMA)(',')
|
||||||
DESTRUCTURING_DECLARATION_ENTRY
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(IDENTIFIER)('x')
|
DESTRUCTURING_DECLARATION_ENTRY
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(IDENTIFIER)('x')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(in)('in')
|
PsiElement(in)('in')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
@@ -253,7 +255,7 @@ JetFile: forParameters.kt
|
|||||||
PsiElement(for)('for')
|
PsiElement(for)('for')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(LPAR)('(')
|
PsiElement(LPAR)('(')
|
||||||
DESTRUCTURING_DECLARATION
|
VALUE_PARAMETER
|
||||||
MODIFIER_LIST
|
MODIFIER_LIST
|
||||||
ANNOTATION_ENTRY
|
ANNOTATION_ENTRY
|
||||||
PsiElement(AT)('@')
|
PsiElement(AT)('@')
|
||||||
@@ -266,23 +268,24 @@ JetFile: forParameters.kt
|
|||||||
PsiElement(LPAR)('(')
|
PsiElement(LPAR)('(')
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(RPAR)(')')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(LPAR)('(')
|
DESTRUCTURING_DECLARATION
|
||||||
DESTRUCTURING_DECLARATION_ENTRY
|
PsiElement(LPAR)('(')
|
||||||
PsiElement(IDENTIFIER)('x')
|
DESTRUCTURING_DECLARATION_ENTRY
|
||||||
PsiElement(COMMA)(',')
|
PsiElement(IDENTIFIER)('x')
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(COMMA)(',')
|
||||||
DESTRUCTURING_DECLARATION_ENTRY
|
|
||||||
MODIFIER_LIST
|
|
||||||
ANNOTATION_ENTRY
|
|
||||||
PsiElement(AT)('@')
|
|
||||||
CONSTRUCTOR_CALLEE
|
|
||||||
TYPE_REFERENCE
|
|
||||||
USER_TYPE
|
|
||||||
REFERENCE_EXPRESSION
|
|
||||||
PsiElement(IDENTIFIER)('Volatile')
|
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(IDENTIFIER)('y')
|
DESTRUCTURING_DECLARATION_ENTRY
|
||||||
PsiElement(RPAR)(')')
|
MODIFIER_LIST
|
||||||
|
ANNOTATION_ENTRY
|
||||||
|
PsiElement(AT)('@')
|
||||||
|
CONSTRUCTOR_CALLEE
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('Volatile')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('y')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(in)('in')
|
PsiElement(in)('in')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
@@ -377,7 +380,7 @@ JetFile: forParameters.kt
|
|||||||
PsiElement(for)('for')
|
PsiElement(for)('for')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(LPAR)('(')
|
PsiElement(LPAR)('(')
|
||||||
DESTRUCTURING_DECLARATION
|
VALUE_PARAMETER
|
||||||
MODIFIER_LIST
|
MODIFIER_LIST
|
||||||
PsiElement(private)('private')
|
PsiElement(private)('private')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
@@ -391,23 +394,24 @@ JetFile: forParameters.kt
|
|||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(val)('val')
|
PsiElement(val)('val')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(LPAR)('(')
|
DESTRUCTURING_DECLARATION
|
||||||
DESTRUCTURING_DECLARATION_ENTRY
|
PsiElement(LPAR)('(')
|
||||||
PsiElement(IDENTIFIER)('x')
|
DESTRUCTURING_DECLARATION_ENTRY
|
||||||
PsiElement(COMMA)(',')
|
PsiElement(IDENTIFIER)('x')
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(COMMA)(',')
|
||||||
DESTRUCTURING_DECLARATION_ENTRY
|
|
||||||
MODIFIER_LIST
|
|
||||||
ANNOTATION_ENTRY
|
|
||||||
PsiElement(AT)('@')
|
|
||||||
CONSTRUCTOR_CALLEE
|
|
||||||
TYPE_REFERENCE
|
|
||||||
USER_TYPE
|
|
||||||
REFERENCE_EXPRESSION
|
|
||||||
PsiElement(IDENTIFIER)('Volatile')
|
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(IDENTIFIER)('y')
|
DESTRUCTURING_DECLARATION_ENTRY
|
||||||
PsiElement(RPAR)(')')
|
MODIFIER_LIST
|
||||||
|
ANNOTATION_ENTRY
|
||||||
|
PsiElement(AT)('@')
|
||||||
|
CONSTRUCTOR_CALLEE
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('Volatile')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('y')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(in)('in')
|
PsiElement(in)('in')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
|
|||||||
@@ -18,15 +18,16 @@ JetFile: WithWithoutInAndMultideclaration.kt
|
|||||||
PsiElement(for)('for')
|
PsiElement(for)('for')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(LPAR)('(')
|
PsiElement(LPAR)('(')
|
||||||
DESTRUCTURING_DECLARATION
|
VALUE_PARAMETER
|
||||||
PsiElement(LPAR)('(')
|
DESTRUCTURING_DECLARATION
|
||||||
DESTRUCTURING_DECLARATION_ENTRY
|
PsiElement(LPAR)('(')
|
||||||
PsiElement(IDENTIFIER)('i')
|
DESTRUCTURING_DECLARATION_ENTRY
|
||||||
PsiElement(COMMA)(',')
|
PsiElement(IDENTIFIER)('i')
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(COMMA)(',')
|
||||||
DESTRUCTURING_DECLARATION_ENTRY
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(IDENTIFIER)('j')
|
DESTRUCTURING_DECLARATION_ENTRY
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(IDENTIFIER)('j')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
PsiErrorElement:Expecting 'in'
|
PsiErrorElement:Expecting 'in'
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(RPAR)(')')
|
||||||
|
|||||||
+1
-1
@@ -62,7 +62,7 @@ class DestructuringDeclarationReferenceSearcher(
|
|||||||
|
|
||||||
is KtContainerNode -> {
|
is KtContainerNode -> {
|
||||||
if (parent.node.elementType == KtNodeTypes.LOOP_RANGE) {
|
if (parent.node.elementType == KtNodeTypes.LOOP_RANGE) {
|
||||||
(parent.parent as KtForExpression).destructuringParameter
|
(parent.parent as KtForExpression).destructuringDeclaration
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
null
|
null
|
||||||
|
|||||||
+1
-1
@@ -543,7 +543,7 @@ class ExpressionsOfTypeProcessor(
|
|||||||
is KtContainerNode -> {
|
is KtContainerNode -> {
|
||||||
if (parent.node.elementType == KtNodeTypes.LOOP_RANGE) { // "for (x in <expr>) ..."
|
if (parent.node.elementType == KtNodeTypes.LOOP_RANGE) { // "for (x in <expr>) ..."
|
||||||
val forExpression = parent.parent as KtForExpression
|
val forExpression = parent.parent as KtForExpression
|
||||||
(forExpression.destructuringParameter ?: forExpression.loopParameter as KtDeclaration?)?.let {
|
(forExpression.destructuringDeclaration ?: forExpression.loopParameter as KtDeclaration?)?.let {
|
||||||
processSuspiciousDeclaration(it)
|
processSuspiciousDeclaration(it)
|
||||||
}
|
}
|
||||||
break@ParentsLoop
|
break@ParentsLoop
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ class KotlinBreadcrumbsInfoProvider : BreadcrumbsInfoProvider() {
|
|||||||
|
|
||||||
private fun KtContainerNode.buildText(kind: TextKind): String {
|
private fun KtContainerNode.buildText(kind: TextKind): String {
|
||||||
with (bodyOwner() as KtForExpression) {
|
with (bodyOwner() as KtForExpression) {
|
||||||
val parameterText = loopParameter?.nameAsName?.render() ?: destructuringParameter?.text ?: return "for"
|
val parameterText = loopParameter?.nameAsName?.render() ?: destructuringDeclaration?.text ?: return "for"
|
||||||
val collectionText = loopRange?.text ?: ""
|
val collectionText = loopRange?.text ?: ""
|
||||||
val text = (parameterText + " in " + collectionText).truncateEnd(kind)
|
val text = (parameterText + " in " + collectionText).truncateEnd(kind)
|
||||||
return labelText() + "for($text)"
|
return labelText() + "for($text)"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class KotlinForConditionFixer: MissingConditionFixer<KtForExpression>() {
|
|||||||
override val keyword = "for"
|
override val keyword = "for"
|
||||||
override fun getElement(element: PsiElement?) = element as? KtForExpression
|
override fun getElement(element: PsiElement?) = element as? KtForExpression
|
||||||
override fun getCondition(element: KtForExpression) =
|
override fun getCondition(element: KtForExpression) =
|
||||||
element.loopRange ?: element.loopParameter ?: element.destructuringParameter
|
element.loopRange ?: element.loopParameter ?: element.destructuringDeclaration
|
||||||
override fun getLeftParenthesis(element: KtForExpression) = element.leftParenthesis
|
override fun getLeftParenthesis(element: KtForExpression) = element.leftParenthesis
|
||||||
override fun getRightParenthesis(element: KtForExpression) = element.rightParenthesis
|
override fun getRightParenthesis(element: KtForExpression) = element.rightParenthesis
|
||||||
override fun getBody(element: KtForExpression) = element.body
|
override fun getBody(element: KtForExpression) = element.body
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class AddForLoopIndicesIntention : SelfTargetingRangeIntention<KtForExpression>(
|
|||||||
|
|
||||||
loopRange.replace(createWithIndexExpression(loopRange))
|
loopRange.replace(createWithIndexExpression(loopRange))
|
||||||
|
|
||||||
var multiParameter = (psiFactory.createExpressionByPattern("for((index, $0) in x){}", loopParameter.text) as KtForExpression).destructuringParameter!!
|
var multiParameter = (psiFactory.createExpressionByPattern("for((index, $0) in x){}", loopParameter.text) as KtForExpression).destructuringDeclaration!!
|
||||||
|
|
||||||
multiParameter = loopParameter.replaced(multiParameter)
|
multiParameter = loopParameter.replaced(multiParameter)
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
|
|||||||
names.add(name)
|
names.add(name)
|
||||||
}
|
}
|
||||||
if (forLoop != null) {
|
if (forLoop != null) {
|
||||||
element.replace(factory.createDestructuringParameter("(${names.joinToString()})"))
|
element.replace(factory.createDestructuringParameterForLoop("(${names.joinToString()})"))
|
||||||
|
|
||||||
if (removeSelectorInLoopRange && loopRange is KtDotQualifiedExpression) {
|
if (removeSelectorInLoopRange && loopRange is KtDotQualifiedExpression) {
|
||||||
loopRange.replace(loopRange.receiverExpression)
|
loopRange.replace(loopRange.receiverExpression)
|
||||||
|
|||||||
@@ -81,14 +81,14 @@ class IterateExpressionIntention : SelfTargetingIntention<KtExpression>(KtExpres
|
|||||||
}
|
}
|
||||||
|
|
||||||
val paramPattern = (names.singleOrNull()?.first()
|
val paramPattern = (names.singleOrNull()?.first()
|
||||||
?: psiFactory.createDestructuringParameter(names.indices.joinToString(prefix = "(", postfix = ")") { "p$it" }))
|
?: psiFactory.createDestructuringParameterForLoop(names.indices.joinToString(prefix = "(", postfix = ")") { "p$it" }))
|
||||||
var forExpression = psiFactory.createExpressionByPattern("for($0 in $1) {\nx\n}", paramPattern, element) as KtForExpression
|
var forExpression = psiFactory.createExpressionByPattern("for($0 in $1) {\nx\n}", paramPattern, element) as KtForExpression
|
||||||
forExpression = element.replaced(forExpression)
|
forExpression = element.replaced(forExpression)
|
||||||
|
|
||||||
PsiDocumentManager.getInstance(forExpression.project).doPostponedOperationsAndUnblockDocument(editor.document)
|
PsiDocumentManager.getInstance(forExpression.project).doPostponedOperationsAndUnblockDocument(editor.document)
|
||||||
|
|
||||||
val bodyPlaceholder = (forExpression.body as KtBlockExpression).statements.single()
|
val bodyPlaceholder = (forExpression.body as KtBlockExpression).statements.single()
|
||||||
val parameters = forExpression.loopParameter?.singletonList() ?: forExpression.destructuringParameter!!.entries
|
val parameters = forExpression.destructuringDeclaration?.entries ?: forExpression.loopParameter!!.singletonList()
|
||||||
|
|
||||||
val templateBuilder = TemplateBuilderImpl(forExpression)
|
val templateBuilder = TemplateBuilderImpl(forExpression)
|
||||||
for ((parameter, parameterNames) in (parameters zip names)) {
|
for ((parameter, parameterNames) in (parameters zip names)) {
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class RemoveForLoopIndicesIntention : SelfTargetingRangeIntention<KtForExpressio
|
|||||||
|
|
||||||
override fun applicabilityRange(element: KtForExpression): TextRange? {
|
override fun applicabilityRange(element: KtForExpression): TextRange? {
|
||||||
val loopRange = element.loopRange as? KtDotQualifiedExpression ?: return null
|
val loopRange = element.loopRange as? KtDotQualifiedExpression ?: return null
|
||||||
val multiParameter = element.destructuringParameter ?: return null
|
val multiParameter = element.destructuringDeclaration ?: return null
|
||||||
if (multiParameter.entries.size != 2) return null
|
if (multiParameter.entries.size != 2) return null
|
||||||
|
|
||||||
val bindingContext = element.analyze(BodyResolveMode.PARTIAL)
|
val bindingContext = element.analyze(BodyResolveMode.PARTIAL)
|
||||||
@@ -60,12 +60,12 @@ class RemoveForLoopIndicesIntention : SelfTargetingRangeIntention<KtForExpressio
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun applyTo(element: KtForExpression, editor: Editor?) {
|
override fun applyTo(element: KtForExpression, editor: Editor?) {
|
||||||
val multiParameter = element.destructuringParameter!!
|
val multiParameter = element.destructuringDeclaration!!
|
||||||
val loopRange = element.loopRange as KtDotQualifiedExpression
|
val loopRange = element.loopRange as KtDotQualifiedExpression
|
||||||
|
|
||||||
val elementVar = multiParameter.entries[1]
|
val elementVar = multiParameter.entries[1]
|
||||||
val loop = KtPsiFactory(element).createExpressionByPattern("for ($0 in _) {}", elementVar.text) as KtForExpression
|
val loop = KtPsiFactory(element).createExpressionByPattern("for ($0 in _) {}", elementVar.text) as KtForExpression
|
||||||
multiParameter.replace(loop.loopParameter!!)
|
element.loopParameter!!.replace(loop.loopParameter!!)
|
||||||
|
|
||||||
loopRange.replace(loopRange.receiverExpression)
|
loopRange.replace(loopRange.receiverExpression)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -45,7 +45,7 @@ class UseWithIndexIntention : SelfTargetingRangeIntention<KtForExpression>(
|
|||||||
val newLoopRange = factory.createExpressionByPattern("$0.withIndex()", loopRange)
|
val newLoopRange = factory.createExpressionByPattern("$0.withIndex()", loopRange)
|
||||||
loopRange.replace(newLoopRange)
|
loopRange.replace(newLoopRange)
|
||||||
|
|
||||||
val multiParameter = (factory.createExpressionByPattern("for(($0, $1) in x){}", indexVariable.nameAsSafeName, loopParameter.text) as KtForExpression).destructuringParameter!!
|
val multiParameter = (factory.createExpressionByPattern("for(($0, $1) in x){}", indexVariable.nameAsSafeName, loopParameter.text) as KtForExpression).loopParameter!!
|
||||||
loopParameter.replace(multiParameter)
|
loopParameter.replace(multiParameter)
|
||||||
|
|
||||||
initializationStatement.delete()
|
initializationStatement.delete()
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ data class LoopData(
|
|||||||
private fun extractLoopData(loop: KtForExpression): LoopData? {
|
private fun extractLoopData(loop: KtForExpression): LoopData? {
|
||||||
val loopRange = loop.loopRange ?: return null
|
val loopRange = loop.loopRange ?: return null
|
||||||
|
|
||||||
val destructuringParameter = loop.destructuringParameter
|
val destructuringParameter = loop.destructuringDeclaration
|
||||||
if (destructuringParameter != null && destructuringParameter.entries.size == 2) {
|
if (destructuringParameter != null && destructuringParameter.entries.size == 2) {
|
||||||
val qualifiedExpression = loopRange as? KtDotQualifiedExpression
|
val qualifiedExpression = loopRange as? KtDotQualifiedExpression
|
||||||
if (qualifiedExpression != null) {
|
if (qualifiedExpression != null) {
|
||||||
|
|||||||
@@ -184,7 +184,6 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
|
|
||||||
VAL_OR_VAR_ON_FUN_PARAMETER.registerFactory(RemoveValVarFromParameterFix)
|
VAL_OR_VAR_ON_FUN_PARAMETER.registerFactory(RemoveValVarFromParameterFix)
|
||||||
VAL_OR_VAR_ON_LOOP_PARAMETER.registerFactory(RemoveValVarFromParameterFix)
|
VAL_OR_VAR_ON_LOOP_PARAMETER.registerFactory(RemoveValVarFromParameterFix)
|
||||||
VAL_OR_VAR_ON_LOOP_MULTI_PARAMETER.registerFactory(RemoveValVarFromParameterFix)
|
|
||||||
VAL_OR_VAR_ON_CATCH_PARAMETER.registerFactory(RemoveValVarFromParameterFix)
|
VAL_OR_VAR_ON_CATCH_PARAMETER.registerFactory(RemoveValVarFromParameterFix)
|
||||||
VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER.registerFactory(RemoveValVarFromParameterFix)
|
VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER.registerFactory(RemoveValVarFromParameterFix)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.types.Variance
|
|||||||
object CreateComponentFunctionActionFactory : CreateCallableMemberFromUsageFactory<KtDestructuringDeclaration>() {
|
object CreateComponentFunctionActionFactory : CreateCallableMemberFromUsageFactory<KtDestructuringDeclaration>() {
|
||||||
override fun getElementOfInterest(diagnostic: Diagnostic): KtDestructuringDeclaration? {
|
override fun getElementOfInterest(diagnostic: Diagnostic): KtDestructuringDeclaration? {
|
||||||
QuickFixUtil.getParentElementOfType(diagnostic, KtDestructuringDeclaration::class.java)?.let { return it }
|
QuickFixUtil.getParentElementOfType(diagnostic, KtDestructuringDeclaration::class.java)?.let { return it }
|
||||||
return QuickFixUtil.getParentElementOfType(diagnostic, KtForExpression::class.java)?.destructuringParameter
|
return QuickFixUtil.getParentElementOfType(diagnostic, KtForExpression::class.java)?.destructuringDeclaration
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createCallableInfo(element: KtDestructuringDeclaration, diagnostic: Diagnostic): CallableInfo? {
|
override fun createCallableInfo(element: KtDestructuringDeclaration, diagnostic: Diagnostic): CallableInfo? {
|
||||||
|
|||||||
+1
-1
@@ -40,7 +40,7 @@ object CreateIteratorFunctionActionFactory : CreateCallableMemberFromUsageFactor
|
|||||||
override fun createCallableInfo(element: KtForExpression, diagnostic: Diagnostic): CallableInfo? {
|
override fun createCallableInfo(element: KtForExpression, diagnostic: Diagnostic): CallableInfo? {
|
||||||
val file = diagnostic.psiFile as? KtFile ?: return null
|
val file = diagnostic.psiFile as? KtFile ?: return null
|
||||||
val iterableExpr = element.loopRange ?: return null
|
val iterableExpr = element.loopRange ?: return null
|
||||||
val variableExpr: KtExpression = ((element.loopParameter ?: element.destructuringParameter) ?: return null) as KtExpression
|
val variableExpr: KtExpression = ((element.loopParameter ?: element.destructuringDeclaration) ?: return null) as KtExpression
|
||||||
val iterableType = TypeInfo(iterableExpr, Variance.IN_VARIANCE)
|
val iterableType = TypeInfo(iterableExpr, Variance.IN_VARIANCE)
|
||||||
|
|
||||||
val (bindingContext, moduleDescriptor) = file.analyzeFullyAndGetResult()
|
val (bindingContext, moduleDescriptor) = file.analyzeFullyAndGetResult()
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ object CreateNextFunctionActionFactory : CreateCallableMemberFromUsageFactory<Kt
|
|||||||
val diagnosticWithParameters = DiagnosticFactory.cast(diagnostic, Errors.NEXT_MISSING, Errors.NEXT_NONE_APPLICABLE)
|
val diagnosticWithParameters = DiagnosticFactory.cast(diagnostic, Errors.NEXT_MISSING, Errors.NEXT_NONE_APPLICABLE)
|
||||||
val ownerType = TypeInfo(diagnosticWithParameters.a, Variance.IN_VARIANCE)
|
val ownerType = TypeInfo(diagnosticWithParameters.a, Variance.IN_VARIANCE)
|
||||||
|
|
||||||
val variableExpr = element.loopParameter ?: element.destructuringParameter ?: return null
|
val variableExpr = element.loopParameter ?: element.destructuringDeclaration ?: return null
|
||||||
val returnType = TypeInfo(variableExpr as KtExpression, Variance.OUT_VARIANCE)
|
val returnType = TypeInfo(variableExpr as KtExpression, Variance.OUT_VARIANCE)
|
||||||
return FunctionInfo(OperatorNameConventions.NEXT.asString(), ownerType, returnType, isOperator = true)
|
return FunctionInfo(OperatorNameConventions.NEXT.asString(), ownerType, returnType, isOperator = true)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -40,7 +40,8 @@ class KotlinComponentUsageInDestructuring(element: KtDestructuringDeclarationEnt
|
|||||||
|
|
||||||
val newDestructuring = KtPsiFactory(element).buildDestructuringDeclaration {
|
val newDestructuring = KtPsiFactory(element).buildDestructuringDeclaration {
|
||||||
val lastIndex = newParameterInfos.indexOfLast { it.oldIndex in currentEntries.indices }
|
val lastIndex = newParameterInfos.indexOfLast { it.oldIndex in currentEntries.indices }
|
||||||
val nameValidator = CollectingNameValidator(filter = NewDeclarationNameValidator(declaration.parent, null, Target.VARIABLES))
|
val nameValidator = CollectingNameValidator(
|
||||||
|
filter = NewDeclarationNameValidator(declaration.parent.parent, null, Target.VARIABLES))
|
||||||
|
|
||||||
appendFixedText("val (")
|
appendFixedText("val (")
|
||||||
for (i in 0..lastIndex) {
|
for (i in 0..lastIndex) {
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ fun KtElement.renderTrimmed(): String {
|
|||||||
|
|
||||||
override fun visitForExpression(expression: KtForExpression) {
|
override fun visitForExpression(expression: KtForExpression) {
|
||||||
builder.append("for (")
|
builder.append("for (")
|
||||||
(expression.loopParameter ?: expression.destructuringParameter)?.accept(this)
|
(expression.loopParameter ?: expression.destructuringDeclaration)?.accept(this)
|
||||||
builder.append(" in ")
|
builder.append(" in ")
|
||||||
expression.loopRange?.accept(this)
|
expression.loopRange?.accept(this)
|
||||||
builder.append(")")
|
builder.append(")")
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
data class XY(val x: Int, val y: Int)
|
||||||
|
|
||||||
|
fun convert(xy: XY, f: (XY) -> Int) = f(xy)
|
||||||
|
|
||||||
|
fun foo() = <error>convert</error> { (<error>x</error><error><error>,</error> y)</error> }
|
||||||
@@ -502,6 +502,12 @@ public class PsiCheckerTestGenerated extends AbstractPsiCheckerTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("DestructuringDeclarationInLambda.kt")
|
||||||
|
public void testDestructuringDeclarationInLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/DestructuringDeclarationInLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("DollarsInName.kt")
|
@TestMetadata("DollarsInName.kt")
|
||||||
public void testDollarsInName() throws Exception {
|
public void testDollarsInName() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/DollarsInName.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/DollarsInName.kt");
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getIteratorFunction
|
|||||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getNextFunction
|
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getNextFunction
|
||||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getTypeForExpression
|
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getTypeForExpression
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.*
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.*
|
||||||
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getLoopParameter
|
|
||||||
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getLoopRange
|
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getLoopRange
|
||||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
|
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
@@ -99,14 +98,13 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont
|
|||||||
getClassDescriptorForType(rangeType).name.asString() == "IntArray"
|
getClassDescriptorForType(rangeType).name.asString() == "IntArray"
|
||||||
}
|
}
|
||||||
|
|
||||||
val destructuringParameter: KtDestructuringDeclaration? = expression.destructuringParameter
|
|
||||||
|
|
||||||
val loopParameter = getLoopParameter(expression)
|
val loopParameter = expression.loopParameter!!
|
||||||
val parameterName = if (loopParameter != null) {
|
val destructuringParameter: KtDestructuringDeclaration? = loopParameter?.destructuringDeclaration
|
||||||
|
val parameterName = if (destructuringParameter == null) {
|
||||||
context.getNameForElement(loopParameter)
|
context.getNameForElement(loopParameter)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(destructuringParameter != null) { "If loopParameter is null, multi parameter must be not null ${expression.text}" }
|
|
||||||
context.scope().declareTemporary()
|
context.scope().declareTemporary()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,11 +111,6 @@ public final class PsiUtils {
|
|||||||
return (binaryExpression.getOperationToken() == KtTokens.IN_KEYWORD);
|
return (binaryExpression.getOperationToken() == KtTokens.IN_KEYWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static KtParameter getLoopParameter(@NotNull KtForExpression expression) {
|
|
||||||
return expression.getLoopParameter();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static List<KtParameter> getPrimaryConstructorParameters(@NotNull KtClassOrObject classDeclaration) {
|
public static List<KtParameter> getPrimaryConstructorParameters(@NotNull KtClassOrObject classDeclaration) {
|
||||||
if (classDeclaration instanceof KtClass) {
|
if (classDeclaration instanceof KtClass) {
|
||||||
|
|||||||
Reference in New Issue
Block a user