Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

fix(resolving/completion): for methods on T? #229

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions server/src/e2e/suite/testcases/completion/methods.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
========================================================================
Completion for method on T?
========================================================================
primitive Int;

extends fun foo(self: Int) {}
extends fun fooOpt(self: Int?) {}

fun test() {
let a = 10;
a.<caret>;
}
------------------------------------------------------------------------
2 foo(self: Int)
2 fooOpt(self: Int?)
14 call Use as function argument
14 do Create do-until loop
14 if Create if statement
14 let Create variable
14 not Negate expression
14 repeat Create repeat loop
67 changes: 67 additions & 0 deletions server/src/e2e/suite/testcases/resolve/methods.test
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,73 @@ fun test() {
------------------------------------------------------------------------
8:6 -> 2:12 resolved

========================================================================
Extends method resolve on T? with non Option qualifier
========================================================================
primitive Int;

extends fun add(self: Int?, other: Int): Int {
return self + other;
}

fun test() {
let x: Int = 5;
x.<caret>add(3);
}
------------------------------------------------------------------------
8:6 -> 2:12 resolved

========================================================================
Extends method resolve on T? with Option qualifier
========================================================================
primitive Int;

extends fun add(self: Int?, other: Int): Int {
return self + other;
}

fun test() {
let x: Int? = 5;
x.<caret>add(3);
}
------------------------------------------------------------------------
8:6 -> 2:12 resolved

========================================================================
Extends method resolve on T and T? with the same name
========================================================================
primitive Int;

struct SomeStruct {}

extends fun equal(self: SomeStruct?, other: SomeStruct?): Bool {
if (self == null && other == null) { return true }
if (self == null || other == null) { return false }
return self!!.i == other!!.i && self!!.b == other!!.b;
}

extends fun equal(self: SomeStruct, other: SomeStruct): Bool {
return self.i == other.i && self.b == other.b;
}

contract Test {
receive() {}

get fun test1(): Bool {
let s1 = SomeStruct { i: 42, b: true };
return s1.<caret>equal(s1)
}

get fun test2(): Bool {
let s2 = SomeStruct { i: 42, b: false };
let s3: SomeStruct? = null;
return !s3.<caret>equal(s2);
}
}
------------------------------------------------------------------------
19:18 -> 10:12 resolved
25:19 -> 4:12 resolved

========================================================================
Contract method resolve
========================================================================
Expand Down
6 changes: 5 additions & 1 deletion server/src/psi/Reference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,16 @@ export class Reference {
return this.processType(qualifier, qualifierType.innerTy, proc, state)
}

if (!this.processType(qualifier, qualifierType, proc, state)) return false

// process unwrapped T? later to correctly resolve in case of same name method for T and T?
if (qualifierType instanceof OptionTy) {
// show completion and resolve without explicit unwrapping
return this.processType(qualifier, qualifierType.innerTy, proc, state)
}

return this.processType(qualifier, qualifierType, proc, state)
// last resort, trying to find methods of T?
return this.processType(qualifier, new OptionTy(qualifierType), proc, state)
}

private processType(
Expand Down