From 3cf133bff728807c33bc3bfda69b44abca43cb82 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Fri, 7 Jun 2013 13:41:57 +0400 Subject: [PATCH] changed local extensions priority local extensions aren't longer chosen before members --- .../calls/tasks/ResolutionTaskHolder.java | 35 +-------- .../resolve/calls/tasks/TaskPrioritizer.java | 23 +++--- .../codegen/box/classes/resolveOrder.kt | 75 ------------------- .../closerReceiver1.resolve | 9 +++ .../closerReceiver2.resolve | 9 +++ .../closerReceiver3.resolve | 7 ++ .../candidatesPriority/closerScope.resolve | 8 ++ .../extensionToCloserReceiverVsMember.resolve | 16 ++++ ...solve => implicitThisVsNoReceiver.resolve} | 0 .../implicitThisVsNoReceiver2.resolve | 12 +++ .../localVsImplicitThis.resolve | 8 ++ .../memberVsExtension1.resolve | 9 +++ .../memberVsExtension2.resolve | 10 +++ .../memberVsExtension3.resolve | 13 ++++ .../memberVsLocalExtension.resolve | 8 ++ .../receiverVsThisObject.resolve | 9 +++ .../receiverVsThisObject2.resolve | 9 +++ .../BlackBoxCodegenTestGenerated.java | 5 -- .../jet/resolve/JetResolveTestGenerated.java | 73 +++++++++++++++++- .../additional/cases/resolveOrder.jet | 75 ------------------- 20 files changed, 210 insertions(+), 203 deletions(-) delete mode 100644 compiler/testData/codegen/box/classes/resolveOrder.kt create mode 100644 compiler/testData/resolve/candidatesPriority/closerReceiver1.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/closerReceiver2.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/closerReceiver3.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/closerScope.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/extensionToCloserReceiverVsMember.resolve rename compiler/testData/resolve/candidatesPriority/{preferImplicitThisToNoReceiver.resolve => implicitThisVsNoReceiver.resolve} (100%) create mode 100644 compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver2.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/localVsImplicitThis.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/memberVsExtension1.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/memberVsExtension2.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/memberVsExtension3.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/memberVsLocalExtension.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/receiverVsThisObject.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/receiverVsThisObject2.resolve delete mode 100644 js/js.translator/testFiles/additional/cases/resolveOrder.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java index ee25d9ef892..b9162fa9ff5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java @@ -36,9 +36,7 @@ public class ResolutionTaskHolder { private final PriorityProvider> priorityProvider; private final boolean isSafeCall; - private final Collection>> localExtensions = Sets.newLinkedHashSet(); - private final Collection>> members = Sets.newLinkedHashSet(); - private final Collection>> nonLocalExtensions = Sets.newLinkedHashSet(); + private final Collection>> candidatesList = Lists.newArrayList(); private List> tasks = null; @@ -59,44 +57,19 @@ public class ResolutionTaskHolder { return candidates; } - public void addLocalExtensions(@NotNull Collection> candidates) { + public void addCandidates(@NotNull Collection> candidates) { if (!candidates.isEmpty()) { - localExtensions.add(setIsSafeCall(candidates)); - } - } - - public void addMembers(@NotNull Collection> candidates) { - if (!candidates.isEmpty()) { - members.add(setIsSafeCall(candidates)); - } - } - - public void addNonLocalExtensions(@NotNull Collection> candidates) { - if (!candidates.isEmpty()) { - nonLocalExtensions.add(setIsSafeCall(candidates)); + candidatesList.add(setIsSafeCall(candidates)); } } public List> getTasks() { if (tasks == null) { tasks = Lists.newArrayList(); - List>> candidateList = Lists.newArrayList(); - // If the call is of the form super.foo(), it can actually be only a member - // But if there's no appropriate member, we would like to report that super cannot be a receiver for an extension - // Thus, put members first - if (TaskPrioritizer.getReceiverSuper(basicCallResolutionContext.call.getExplicitReceiver()) != null) { - candidateList.addAll(members); - candidateList.addAll(localExtensions); - } - else { - candidateList.addAll(localExtensions); - candidateList.addAll(members); - } - candidateList.addAll(nonLocalExtensions); for (int priority = priorityProvider.getMaxPriority(); priority >= 0; priority--) { final int finalPriority = priority; - for (Collection> candidates : candidateList) { + for (Collection> candidates : candidatesList) { Collection> filteredCandidates = Collections2.filter(candidates, new Predicate>() { @Override public boolean apply(@Nullable ResolutionCandidate input) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java index 20272763406..85db61fa34f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java @@ -147,29 +147,26 @@ public class TaskPrioritizer { if (receiver.exists()) { List variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver); - Collection> extensionFunctions = convertWithImpliedThis(scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(scope, name)); - List> nonlocals = Lists.newArrayList(); - List> locals = Lists.newArrayList(); - //noinspection unchecked,RedundantTypeArguments - TaskPrioritizer.splitLexicallyLocalDescriptors(extensionFunctions, scope.getContainingDeclaration(), locals, nonlocals); - Collection> members = Lists.newArrayList(); for (ReceiverValue variant : variantsForExplicitReceiver) { Collection membersForThisVariant = callableDescriptorCollector.getMembersByName(variant.getType(), name); - convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), Collections.singletonList(NO_RECEIVER), members, hasExplicitThisObject); + convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), + Collections.singletonList(NO_RECEIVER), members, hasExplicitThisObject); } - result.addLocalExtensions(locals); - result.addMembers(members); + result.addCandidates(members); for (ReceiverValue implicitReceiver : implicitReceivers) { Collection memberExtensions = callableDescriptorCollector.getNonMembersByName( implicitReceiver.getType().getMemberScope(), name); List variantsForImplicitReceiver = autoCastService.getVariantsForReceiver(implicitReceiver); - result.addNonLocalExtensions(convertWithReceivers(memberExtensions, variantsForImplicitReceiver, variantsForExplicitReceiver, hasExplicitThisObject)); + result.addCandidates(convertWithReceivers(memberExtensions, variantsForImplicitReceiver, + variantsForExplicitReceiver, hasExplicitThisObject)); } - result.addNonLocalExtensions(nonlocals); + Collection> extensionFunctions = convertWithImpliedThis( + scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(scope, name)); + result.addCandidates(extensionFunctions); } else { Collection> functions = convertWithImpliedThis(scope, Collections.singletonList(receiver), callableDescriptorCollector @@ -180,12 +177,12 @@ public class TaskPrioritizer { //noinspection unchecked,RedundantTypeArguments TaskPrioritizer.splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals); - result.addLocalExtensions(locals); + result.addCandidates(locals); for (ReceiverValue implicitReceiver : implicitReceivers) { doComputeTasks(scope, implicitReceiver, name, result, context, callableDescriptorCollector); } - result.addNonLocalExtensions(nonlocals); + result.addCandidates(nonlocals); } } diff --git a/compiler/testData/codegen/box/classes/resolveOrder.kt b/compiler/testData/codegen/box/classes/resolveOrder.kt deleted file mode 100644 index 3770367675d..00000000000 --- a/compiler/testData/codegen/box/classes/resolveOrder.kt +++ /dev/null @@ -1,75 +0,0 @@ -fun box() : String { - if (!B().test()) return "fail 1"; - if (!D().test()) return "fail 2" - if (!F().test()) return "fail 3" - if (!L().test()) return "fail 4" - if (!H().test()) return "fail 5" - if (!N().test()) return "fail 6" - return "OK" -} - -class A { - fun foo() = 1 -} - -class B { - fun foo() = 2 - - fun A.bar() = foo() - - fun test() = A().bar() == 1 -} - - -class C { - fun D.foo() = 2 -} - -class D { - fun C.foo() = 1 - - fun C.bar() = foo() - - fun test() = C().bar() == 1 -} - -class E -fun E.foo() = 2 - -class F { - fun foo() = 1 - - fun E.bar() = foo() - - fun test() = E().bar() == 1 -} - -class G -fun G.foo() = 2 - -class H { - fun G.foo() = 1 - - fun G.bar() = foo() - - fun test() = G().bar() == 1 -} - -class K -class L { - fun K.bar() = foo() - - fun test() = K().bar() == 1 -} -fun K.foo() = 1 -fun L.foo() = 2 - -class M -class N { - fun foo() = 1 - fun M.foo() = 2 - - fun M.bar() = foo() - - fun test() = M().bar() == 1 -} diff --git a/compiler/testData/resolve/candidatesPriority/closerReceiver1.resolve b/compiler/testData/resolve/candidatesPriority/closerReceiver1.resolve new file mode 100644 index 00000000000..bcb86152e0c --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/closerReceiver1.resolve @@ -0,0 +1,9 @@ +class A { + fun B.foo() = 2 +} + +class B { + ~A.foo~fun A.foo() = 1 + + fun A.bar() = `A.foo`foo() +} diff --git a/compiler/testData/resolve/candidatesPriority/closerReceiver2.resolve b/compiler/testData/resolve/candidatesPriority/closerReceiver2.resolve new file mode 100644 index 00000000000..9d188e283a4 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/closerReceiver2.resolve @@ -0,0 +1,9 @@ +class A + +class B { + fun A.bar() = `A.foo`foo() +} + +~A.foo~fun A.foo() = 1 + +fun B.foo() = 2 diff --git a/compiler/testData/resolve/candidatesPriority/closerReceiver3.resolve b/compiler/testData/resolve/candidatesPriority/closerReceiver3.resolve new file mode 100644 index 00000000000..d82516cf5f7 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/closerReceiver3.resolve @@ -0,0 +1,7 @@ +class A +class B { + fun foo() = 1 + ~A.foo~fun A.foo() = 2 + + fun A.bar() = `A.foo`foo() +} diff --git a/compiler/testData/resolve/candidatesPriority/closerScope.resolve b/compiler/testData/resolve/candidatesPriority/closerScope.resolve new file mode 100644 index 00000000000..9741fc8bd11 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/closerScope.resolve @@ -0,0 +1,8 @@ +class A +fun A.foo() = 2 + +class B { + ~foo~fun A.foo() = 1 + + fun A.bar() = `foo`foo() +} diff --git a/compiler/testData/resolve/candidatesPriority/extensionToCloserReceiverVsMember.resolve b/compiler/testData/resolve/candidatesPriority/extensionToCloserReceiverVsMember.resolve new file mode 100644 index 00000000000..bb339f7a3bc --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/extensionToCloserReceiverVsMember.resolve @@ -0,0 +1,16 @@ +class A { + fun foo() = 1 +} +class B { +} +~B.foo~fun B.foo() = 2 + +fun test(a: A, b: B) { + with (a) { + with (b) { + `B.foo`foo() + } + } +} + +fun with(receiver: T, f: T.() -> R) : R = receiver.f() \ No newline at end of file diff --git a/compiler/testData/resolve/candidatesPriority/preferImplicitThisToNoReceiver.resolve b/compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver.resolve similarity index 100% rename from compiler/testData/resolve/candidatesPriority/preferImplicitThisToNoReceiver.resolve rename to compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver.resolve diff --git a/compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver2.resolve b/compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver2.resolve new file mode 100644 index 00000000000..499b78dab00 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver2.resolve @@ -0,0 +1,12 @@ +class A { +} +~extension~fun A.foo() = 1 +fun foo() = 2 + +fun test(a: A) { + with (a) { + `extension`foo() + } +} + +fun with(receiver: T, f: T.() -> R) : R = receiver.f() \ No newline at end of file diff --git a/compiler/testData/resolve/candidatesPriority/localVsImplicitThis.resolve b/compiler/testData/resolve/candidatesPriority/localVsImplicitThis.resolve new file mode 100644 index 00000000000..894852280f5 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/localVsImplicitThis.resolve @@ -0,0 +1,8 @@ +class A { + fun foo() = 1 + + fun test() { + fun ~local~foo() = 2 + `local`foo() + } +} \ No newline at end of file diff --git a/compiler/testData/resolve/candidatesPriority/memberVsExtension1.resolve b/compiler/testData/resolve/candidatesPriority/memberVsExtension1.resolve new file mode 100644 index 00000000000..2d5a8a04e2b --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/memberVsExtension1.resolve @@ -0,0 +1,9 @@ +class A { + fun ~member~foo() = 1 + + fun test() { + this.`member`foo() + } +} + +fun A.foo() = 2 \ No newline at end of file diff --git a/compiler/testData/resolve/candidatesPriority/memberVsExtension2.resolve b/compiler/testData/resolve/candidatesPriority/memberVsExtension2.resolve new file mode 100644 index 00000000000..1ad5c09c458 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/memberVsExtension2.resolve @@ -0,0 +1,10 @@ +class A { + fun ~member~foo() = 1 + + fun test() { + this.`member`foo() + } + + fun A.foo() = 2 +} + diff --git a/compiler/testData/resolve/candidatesPriority/memberVsExtension3.resolve b/compiler/testData/resolve/candidatesPriority/memberVsExtension3.resolve new file mode 100644 index 00000000000..2750e411746 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/memberVsExtension3.resolve @@ -0,0 +1,13 @@ +class A { + fun ~member~foo() = 1 +} + +fun A.foo() = 2 + +fun test(a: A) { + with (a) { + this.`member`foo() + } +} + +fun with(receiver: T, f: T.() -> R) : R = receiver.f() \ No newline at end of file diff --git a/compiler/testData/resolve/candidatesPriority/memberVsLocalExtension.resolve b/compiler/testData/resolve/candidatesPriority/memberVsLocalExtension.resolve new file mode 100644 index 00000000000..730ab9ad946 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/memberVsLocalExtension.resolve @@ -0,0 +1,8 @@ +class A { + fun ~member~foo() = 1 + + fun test() { + fun A.foo() = 2 + this.`member`foo() + } +} \ No newline at end of file diff --git a/compiler/testData/resolve/candidatesPriority/receiverVsThisObject.resolve b/compiler/testData/resolve/candidatesPriority/receiverVsThisObject.resolve new file mode 100644 index 00000000000..74f1c30c928 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/receiverVsThisObject.resolve @@ -0,0 +1,9 @@ +class A { + ~A.foo~fun foo() = 1 +} + +class B { + fun foo() = 2 + + fun A.bar() = `A.foo`foo() +} diff --git a/compiler/testData/resolve/candidatesPriority/receiverVsThisObject2.resolve b/compiler/testData/resolve/candidatesPriority/receiverVsThisObject2.resolve new file mode 100644 index 00000000000..3d79b298f28 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/receiverVsThisObject2.resolve @@ -0,0 +1,9 @@ +class A + +class B { + fun foo() = 2 + + fun A.bar() = `A.foo`foo() +} + +~A.foo~fun A.foo() = 1 diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index 42001930d01..81f312778e2 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -1105,11 +1105,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/classes/propertyInInitializer.kt"); } - @TestMetadata("resolveOrder.kt") - public void testResolveOrder() throws Exception { - doTest("compiler/testData/codegen/box/classes/resolveOrder.kt"); - } - @TestMetadata("rightHandOverride.kt") public void testRightHandOverride() throws Exception { doTest("compiler/testData/codegen/box/classes/rightHandOverride.kt"); diff --git a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java index 677f28521d0..3da417da3a5 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java @@ -162,15 +162,80 @@ public class JetResolveTestGenerated extends AbstractResolveTest { public void testAllFilesPresentInCandidatesPriority() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/resolve/candidatesPriority"), Pattern.compile("^(.+)\\.resolve$"), true); } - + @TestMetadata("classObjectOuterResolve.resolve") public void testClassObjectOuterResolve() throws Exception { doTest("compiler/testData/resolve/candidatesPriority/classObjectOuterResolve.resolve"); } - @TestMetadata("preferImplicitThisToNoReceiver.resolve") - public void testPreferImplicitThisToNoReceiver() throws Exception { - doTest("compiler/testData/resolve/candidatesPriority/preferImplicitThisToNoReceiver.resolve"); + @TestMetadata("closerReceiver1.resolve") + public void testCloserReceiver1() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/closerReceiver1.resolve"); + } + + @TestMetadata("closerReceiver2.resolve") + public void testCloserReceiver2() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/closerReceiver2.resolve"); + } + + @TestMetadata("closerReceiver3.resolve") + public void testCloserReceiver3() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/closerReceiver3.resolve"); + } + + @TestMetadata("closerScope.resolve") + public void testCloserScope() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/closerScope.resolve"); + } + + @TestMetadata("extensionToCloserReceiverVsMember.resolve") + public void testExtensionToCloserReceiverVsMember() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/extensionToCloserReceiverVsMember.resolve"); + } + + @TestMetadata("implicitThisVsNoReceiver.resolve") + public void testImplicitThisVsNoReceiver() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver.resolve"); + } + + @TestMetadata("implicitThisVsNoReceiver2.resolve") + public void testImplicitThisVsNoReceiver2() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver2.resolve"); + } + + @TestMetadata("localVsImplicitThis.resolve") + public void testLocalVsImplicitThis() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/localVsImplicitThis.resolve"); + } + + @TestMetadata("memberVsExtension1.resolve") + public void testMemberVsExtension1() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/memberVsExtension1.resolve"); + } + + @TestMetadata("memberVsExtension2.resolve") + public void testMemberVsExtension2() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/memberVsExtension2.resolve"); + } + + @TestMetadata("memberVsExtension3.resolve") + public void testMemberVsExtension3() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/memberVsExtension3.resolve"); + } + + @TestMetadata("memberVsLocalExtension.resolve") + public void testMemberVsLocalExtension() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/memberVsLocalExtension.resolve"); + } + + @TestMetadata("receiverVsThisObject.resolve") + public void testReceiverVsThisObject() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/receiverVsThisObject.resolve"); + } + + @TestMetadata("receiverVsThisObject2.resolve") + public void testReceiverVsThisObject2() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/receiverVsThisObject2.resolve"); } } diff --git a/js/js.translator/testFiles/additional/cases/resolveOrder.jet b/js/js.translator/testFiles/additional/cases/resolveOrder.jet deleted file mode 100644 index 3770367675d..00000000000 --- a/js/js.translator/testFiles/additional/cases/resolveOrder.jet +++ /dev/null @@ -1,75 +0,0 @@ -fun box() : String { - if (!B().test()) return "fail 1"; - if (!D().test()) return "fail 2" - if (!F().test()) return "fail 3" - if (!L().test()) return "fail 4" - if (!H().test()) return "fail 5" - if (!N().test()) return "fail 6" - return "OK" -} - -class A { - fun foo() = 1 -} - -class B { - fun foo() = 2 - - fun A.bar() = foo() - - fun test() = A().bar() == 1 -} - - -class C { - fun D.foo() = 2 -} - -class D { - fun C.foo() = 1 - - fun C.bar() = foo() - - fun test() = C().bar() == 1 -} - -class E -fun E.foo() = 2 - -class F { - fun foo() = 1 - - fun E.bar() = foo() - - fun test() = E().bar() == 1 -} - -class G -fun G.foo() = 2 - -class H { - fun G.foo() = 1 - - fun G.bar() = foo() - - fun test() = G().bar() == 1 -} - -class K -class L { - fun K.bar() = foo() - - fun test() = K().bar() == 1 -} -fun K.foo() = 1 -fun L.foo() = 2 - -class M -class N { - fun foo() = 1 - fun M.foo() = 2 - - fun M.bar() = foo() - - fun test() = M().bar() == 1 -}