Add labels for extension properties
#KT-2824 Fixed
This commit is contained in:
@@ -108,7 +108,7 @@ public interface LocalLookup {
|
||||
RECEIVER {
|
||||
@Override
|
||||
public boolean isCase(DeclarationDescriptor d, GenerationState state) {
|
||||
return d instanceof FunctionDescriptor;
|
||||
return d instanceof CallableDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,7 +130,7 @@ public interface LocalLookup {
|
||||
|
||||
@Override
|
||||
public StackValue outerValue(EnclosedValueDescriptor d, ExpressionCodegen expressionCodegen) {
|
||||
CallableDescriptor descriptor = (FunctionDescriptor) d.getDescriptor();
|
||||
CallableDescriptor descriptor = (CallableDescriptor) d.getDescriptor();
|
||||
return StackValue.local(descriptor.getExpectedThisObject() != null ? 1 : 0, d.getType());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -434,7 +434,7 @@ public class BodyResolver {
|
||||
JetScope declaringScope = context.getDeclaringScopes().apply(accessor);
|
||||
|
||||
JetScope propertyDeclarationInnerScope = descriptorResolver.getPropertyDeclarationInnerScope(
|
||||
declaringScope, propertyDescriptor.getTypeParameters(), propertyDescriptor.getReceiverParameter(), trace);
|
||||
propertyDescriptor, declaringScope, propertyDescriptor.getTypeParameters(), propertyDescriptor.getReceiverParameter(), trace);
|
||||
WritableScope accessorScope = new WritableScopeImpl(
|
||||
propertyDeclarationInnerScope, declaringScope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(trace), "Accessor scope");
|
||||
accessorScope.changeLockLevel(WritableScope.LockLevel.READING);
|
||||
@@ -479,7 +479,8 @@ public class BodyResolver {
|
||||
|
||||
public void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) {
|
||||
JetType expectedTypeForInitializer = property.getTypeRef() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE;
|
||||
JetScope propertyDeclarationInnerScope = descriptorResolver.getPropertyDeclarationInnerScope(scope, propertyDescriptor.getTypeParameters(), NO_RECEIVER_PARAMETER, trace);
|
||||
JetScope propertyDeclarationInnerScope = descriptorResolver.getPropertyDeclarationInnerScopeForInitializer(
|
||||
scope, propertyDescriptor.getTypeParameters(), NO_RECEIVER_PARAMETER, trace);
|
||||
expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer, DataFlowInfo.EMPTY, trace);
|
||||
}
|
||||
|
||||
|
||||
@@ -839,12 +839,39 @@ public class DescriptorResolver {
|
||||
}
|
||||
|
||||
public JetScope getPropertyDeclarationInnerScope(
|
||||
@NotNull JetScope outerScope, @NotNull List<? extends TypeParameterDescriptor> typeParameters,
|
||||
@Nullable ReceiverParameterDescriptor receiver, BindingTrace trace
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull JetScope outerScope,
|
||||
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
|
||||
@Nullable ReceiverParameterDescriptor receiver,
|
||||
BindingTrace trace
|
||||
) {
|
||||
return getPropertyDeclarationInnerScope(propertyDescriptor, outerScope, typeParameters, receiver, trace, true);
|
||||
}
|
||||
|
||||
public JetScope getPropertyDeclarationInnerScopeForInitializer(
|
||||
@NotNull JetScope outerScope,
|
||||
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
|
||||
@Nullable ReceiverParameterDescriptor receiver,
|
||||
BindingTrace trace
|
||||
) {
|
||||
return getPropertyDeclarationInnerScope(null, outerScope, typeParameters, receiver, trace, false);
|
||||
}
|
||||
|
||||
private JetScope getPropertyDeclarationInnerScope(
|
||||
@Nullable PropertyDescriptor propertyDescriptor, // PropertyDescriptor can be null for property scope which hasn't label to property (in this case addLabelForProperty parameter must be false
|
||||
@NotNull JetScope outerScope,
|
||||
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
|
||||
@Nullable ReceiverParameterDescriptor receiver,
|
||||
BindingTrace trace,
|
||||
boolean addLabelForProperty
|
||||
) {
|
||||
WritableScopeImpl result = new WritableScopeImpl(
|
||||
outerScope, outerScope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(trace),
|
||||
"Property declaration inner scope");
|
||||
if (addLabelForProperty) {
|
||||
assert propertyDescriptor != null : "PropertyDescriptor can be null for property scope which hasn't label to property";
|
||||
result.addLabeledDeclaration(propertyDescriptor);
|
||||
}
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||
result.addTypeParameterDescriptor(typeParameterDescriptor);
|
||||
}
|
||||
@@ -909,7 +936,8 @@ public class DescriptorResolver {
|
||||
|
||||
ReceiverParameterDescriptor receiverDescriptor = resolveReceiverParameterFor(propertyDescriptor, receiverType);
|
||||
|
||||
JetScope propertyScope = getPropertyDeclarationInnerScope(scope, typeParameterDescriptors, NO_RECEIVER_PARAMETER, trace);
|
||||
JetScope propertyScope = getPropertyDeclarationInnerScope(propertyDescriptor, scope, typeParameterDescriptors,
|
||||
NO_RECEIVER_PARAMETER, trace);
|
||||
|
||||
JetType type = getVariableType(propertyScope, property, DataFlowInfo.EMPTY, true, trace);
|
||||
|
||||
|
||||
@@ -19,10 +19,7 @@ package org.jetbrains.jet.lang.types.expressions;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
@@ -140,6 +137,10 @@ public class LabelResolver {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor;
|
||||
thisReceiver = functionDescriptor.getReceiverParameter();
|
||||
}
|
||||
else if (declarationDescriptor instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) declarationDescriptor;
|
||||
thisReceiver = propertyDescriptor.getReceiverParameter();
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unsupported descriptor: " + declarationDescriptor); // TODO
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
val Int.getter: Int
|
||||
get() {
|
||||
return this@getter
|
||||
}
|
||||
|
||||
var Int.setter1: Int = 2
|
||||
get() {
|
||||
return this@setter1
|
||||
}
|
||||
set(i: Int) {
|
||||
$setter1 = this@setter1
|
||||
}
|
||||
|
||||
var Int.setter2: Int = 2
|
||||
set(i: Int) {
|
||||
$setter2 = this@setter2
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val i = 1
|
||||
if (i.getter != 1) return "getter failed"
|
||||
|
||||
i.setter1 = 2
|
||||
if (i.setter1 != 1) return "setter1 failed"
|
||||
i.setter2 = 2
|
||||
if (i.setter2 != 1) return "setter2 failed"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
val Int.getter: Int
|
||||
get() {
|
||||
return {
|
||||
this@getter
|
||||
}.invoke()
|
||||
}
|
||||
|
||||
var Int.setter: Int = 1
|
||||
set(i: Int) {
|
||||
$setter = {
|
||||
this@setter
|
||||
}.invoke()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val i = 1
|
||||
if (i.getter != 1) return "getter failed"
|
||||
|
||||
i.setter = 2
|
||||
if (i.setter != 1) return "setter failed"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
val Int.getter: Int
|
||||
get() {
|
||||
val extFun = { Int.() ->
|
||||
this@getter
|
||||
}
|
||||
return this@getter.extFun()
|
||||
}
|
||||
|
||||
|
||||
var Int.setter: Int = 1
|
||||
set(i: Int) {
|
||||
val extFun = { Int.() ->
|
||||
this@setter
|
||||
}
|
||||
this@setter.extFun()
|
||||
}
|
||||
|
||||
|
||||
fun box(): String {
|
||||
val i = 1
|
||||
if (i.getter != 1) return "getter failed"
|
||||
|
||||
i.setter = 1
|
||||
if (i.setter != 1) return "setter failed"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
trait Base {
|
||||
fun foo(): Int
|
||||
}
|
||||
|
||||
val Int.getter: Int
|
||||
get() {
|
||||
return object: Base {
|
||||
override fun foo(): Int {
|
||||
return this@getter
|
||||
}
|
||||
}.foo()
|
||||
}
|
||||
|
||||
var Int.setter1: Int = 2
|
||||
set(i: Int) {
|
||||
$setter1 = object: Base {
|
||||
override fun foo(): Int {
|
||||
this@setter1
|
||||
return 1
|
||||
}
|
||||
}.foo()
|
||||
}
|
||||
|
||||
|
||||
var Int.setter2: Int = 2
|
||||
get() {
|
||||
return object: Base {
|
||||
override fun foo(): Int {
|
||||
return this@setter2
|
||||
}
|
||||
}.foo()
|
||||
}
|
||||
set(i: Int) {
|
||||
$setter2 = object: Base {
|
||||
override fun foo(): Int {
|
||||
this@setter2
|
||||
return 1
|
||||
}
|
||||
}.foo()
|
||||
}
|
||||
|
||||
|
||||
fun box(): String {
|
||||
val i = 1
|
||||
if (i.getter != 1) return "getter failed"
|
||||
|
||||
i.setter1 = 2
|
||||
if (i.setter1 != 1) return "setter1 failed"
|
||||
i.setter2 = 2
|
||||
if (i.setter2 != 1) return "setter2 failed"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
class Test {
|
||||
val Int.innerGetter: Int
|
||||
get() {
|
||||
return this@innerGetter
|
||||
}
|
||||
|
||||
fun test(): Int {
|
||||
val i = 1
|
||||
if (i.innerGetter != 1) return 0
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (Test().test() != 1) return "inner getter or setter failed"
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
trait Base {
|
||||
fun foo()
|
||||
}
|
||||
val String.test: Base = object: Base {
|
||||
override fun foo() {
|
||||
this<!UNRESOLVED_REFERENCE!>@test<!>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
trait Base {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
val ~getter1~Int.getter1: Int
|
||||
get() {
|
||||
return `getter1`this@getter1
|
||||
}
|
||||
|
||||
val ~getter2~Int.getter2: Base
|
||||
get() {
|
||||
return object: Base {
|
||||
override fun foo() {
|
||||
`getter2`this@getter2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val ~getter3~Int.getter3: Base
|
||||
get() = object: Base {
|
||||
override fun foo() {
|
||||
`getter3`this@getter3
|
||||
}
|
||||
}
|
||||
|
||||
val ~getter4~Int.getter4: Int
|
||||
get() {
|
||||
return {
|
||||
`getter4`this@getter4
|
||||
}.invoke()
|
||||
}
|
||||
|
||||
val ~getter5~Int.getter5: Int
|
||||
get() {
|
||||
val extFun = { Int.() ->
|
||||
`getter5`this@getter5
|
||||
}
|
||||
return `getter5`this@getter5.extFun()
|
||||
}
|
||||
|
||||
|
||||
class Test {
|
||||
val ~innerGetter1~Int.innerGetter1: Int
|
||||
get() {
|
||||
return `innerGetter1`this@innerGetter1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
trait Base {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
var ~setter1~Int.setter1: Int = 2
|
||||
set(i: Int) {
|
||||
$setter1 = `setter1`this@setter1
|
||||
}
|
||||
|
||||
var ~setter2~Int.setter2: Base? = null
|
||||
set(i: Base?) {
|
||||
$setter2 = object: Base {
|
||||
override fun foo() {
|
||||
`setter2`this@setter2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ~setter3~Int.setter3: Int = 1
|
||||
set(i: Int) {
|
||||
{
|
||||
`setter3`this@setter3
|
||||
}.invoke()
|
||||
}
|
||||
|
||||
var ~setter4~Int.setter4: Int = 1
|
||||
set(i: Int) {
|
||||
val extFun = { Int.() ->
|
||||
`setter4`this@setter4
|
||||
}
|
||||
`setter4`this@setter4.extFun()
|
||||
}
|
||||
@@ -3570,6 +3570,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/thisAndSuper/thisInNestedClasses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("thisInPropertyInitializer.kt")
|
||||
public void testThisInPropertyInitializer() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/thisAndSuper/thisInPropertyInitializer.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("thisInToplevelFunction.kt")
|
||||
public void testThisInToplevelFunction() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/thisAndSuper/thisInToplevelFunction.kt");
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.codegen.labels;
|
||||
|
||||
import org.jetbrains.jet.ConfigurationKind;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.codegen.CodegenTestCase;
|
||||
import org.jetbrains.jet.test.generator.SimpleTestClassModel;
|
||||
import org.jetbrains.jet.test.generator.TestGenerator;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
public abstract class AbstractLabelGenTest extends CodegenTestCase {
|
||||
|
||||
private static final String REDUNDANT_PATH_PREFIX = "compiler/testData/codegen";
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_AND_ANNOTATIONS);
|
||||
}
|
||||
|
||||
protected void doTest(String path) throws IOException {
|
||||
String relativePath = path.substring(REDUNDANT_PATH_PREFIX.length());
|
||||
blackBoxFile(relativePath);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
String aPackage = "org.jetbrains.jet.codegen.labels";
|
||||
Class<AbstractLabelGenTest> thisClass = AbstractLabelGenTest.class;
|
||||
new TestGenerator(
|
||||
"compiler/tests/",
|
||||
aPackage,
|
||||
"LabelGenTestGenerated",
|
||||
thisClass,
|
||||
Arrays.asList(
|
||||
new SimpleTestClassModel(new File("compiler/testData/codegen/label"), true, "kt", "doTest")
|
||||
),
|
||||
thisClass
|
||||
).generateAndSave();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.jet.codegen.labels;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import java.io.File;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.test.InnerTestClasses;
|
||||
import org.jetbrains.jet.test.TestMetadata;
|
||||
|
||||
import org.jetbrains.jet.codegen.labels.AbstractLabelGenTest;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.jet.codegen.labels.AbstractLabelGenTest}. DO NOT MODIFY MANUALLY */
|
||||
@TestMetadata("compiler/testData/codegen/label")
|
||||
public class LabelGenTestGenerated extends AbstractLabelGenTest {
|
||||
public void testAllFilesPresentInLabel() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.codegen.labels.AbstractLabelGenTest", new File("compiler/testData/codegen/label"), "kt", true);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyAccessor.kt")
|
||||
public void testPropertyAccessor() throws Exception {
|
||||
doTest("compiler/testData/codegen/label/propertyAccessor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyAccessorFunctionLiteral.kt")
|
||||
public void testPropertyAccessorFunctionLiteral() throws Exception {
|
||||
doTest("compiler/testData/codegen/label/propertyAccessorFunctionLiteral.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyAccessorInnerExtensionFun.kt")
|
||||
public void testPropertyAccessorInnerExtensionFun() throws Exception {
|
||||
doTest("compiler/testData/codegen/label/propertyAccessorInnerExtensionFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyAccessorObject.kt")
|
||||
public void testPropertyAccessorObject() throws Exception {
|
||||
doTest("compiler/testData/codegen/label/propertyAccessorObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyInClassAccessor.kt")
|
||||
public void testPropertyInClassAccessor() throws Exception {
|
||||
doTest("compiler/testData/codegen/label/propertyInClassAccessor.kt");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user