-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Polymorphic method type #1889
Polymorphic method type #1889
Changes from all commits
c8735ba
28cec53
ac0615e
a651c7f
26b8ea9
5b40c01
2f306ad
8d6a389
2b76082
c967291
c49a523
56f0352
5077cda
0ced321
82426ee
e34b5f3
1b53953
3170e08
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package org.uqbar.project.wollok.tests.typesystem | ||
|
||
import org.eclipse.emf.ecore.EObject | ||
import org.junit.Test | ||
import org.junit.runners.Parameterized.Parameters | ||
import org.uqbar.project.wollok.typesystem.constraints.ConstraintBasedTypeSystem | ||
import org.uqbar.project.wollok.wollokDsl.WMemberFeatureCall | ||
|
||
class CompatibleTypeInferenceTestCase extends AbstractWollokTypeSystemTestCase { | ||
|
||
@Parameters(name="{index}: {0}") | ||
static def Object[] typeSystems() { | ||
#[ | ||
ConstraintBasedTypeSystem | ||
] | ||
} | ||
|
||
@Test | ||
def void variableWithBasicTypes() { | ||
''' | ||
program { | ||
var x = "" | ||
x = 0 | ||
} | ||
'''.parseAndInfer.asserting [ | ||
findByText("x").assertIncompatibleTypesIssue("String", "Number") | ||
assertTypeOfAsString("(Number|String)", "x") | ||
] | ||
} | ||
|
||
@Test | ||
def void variableWithWKOs() { | ||
''' | ||
object obj1 { } | ||
object obj2 { } | ||
program { | ||
var x = obj1 | ||
x = obj2 | ||
} | ||
'''.parseAndInfer.asserting [ | ||
noIssues | ||
assertTypeOfAsString("(obj1|obj2)", "x") | ||
] | ||
} | ||
|
||
@Test | ||
def void variableWithBasicTypeAndWKO() { | ||
''' | ||
object obj { } | ||
program { | ||
var x = 0 | ||
x = obj | ||
} | ||
'''.parseAndInfer.asserting [ | ||
noIssues | ||
assertTypeOfAsString("(Number|obj)", "x") | ||
] | ||
} | ||
|
||
@Test | ||
def void propertyWithBasicTypes() { | ||
''' | ||
object testing { | ||
method test1() { | ||
obj.n("") | ||
} | ||
} | ||
object obj { | ||
var property n = 0 | ||
} | ||
'''.parseAndInfer.asserting [ | ||
findByText('''""''').assertIncompatibleTypesIssue("String", "Number") | ||
] | ||
} | ||
|
||
@Test | ||
def void propertyWithWKOs() { | ||
''' | ||
object obj1 { } | ||
object obj2 { } | ||
object testing { | ||
method test1() { | ||
obj.x(obj2) | ||
} | ||
} | ||
object obj { | ||
var property x = obj1 | ||
} | ||
'''.parseAndInfer.asserting [ | ||
// FIXME | ||
// noIssues | ||
findByText('''obj2''').assertIncompatibleTypesIssue("obj1", "obj2") | ||
] | ||
} | ||
|
||
@Test | ||
def void parameterType() { | ||
''' | ||
object testing { | ||
method test1() { | ||
obj.boolean("") | ||
} | ||
} | ||
object obj { | ||
method boolean(bool) { return if (bool) 2 else 3 } | ||
} | ||
'''.parseAndInfer.asserting [ | ||
findByText('''""''').assertIncompatibleTypesIssue("String", "Boolean") | ||
assertMethodSignature("(Boolean) => Number", "obj.boolean") | ||
] | ||
} | ||
|
||
@Test | ||
def void returnType() { | ||
''' | ||
object obj { | ||
var bool | ||
method boolean() { return if (bool) 2 else "error" } | ||
} | ||
'''.parseAndInfer.asserting [ | ||
findByText('''if (bool) 2 else "error"''').assertIncompatibleTypesIssue("String", "Number") | ||
assertMethodSignature("() => (Number|String)", "obj.boolean") | ||
] | ||
} | ||
|
||
@Test | ||
def void methodParamVarType() { | ||
''' | ||
program { | ||
const n = 0 | ||
const s = "" | ||
assert.equals(n, s) | ||
} | ||
'''.parseAndInfer.asserting [ | ||
findByText("assert.equals(n, s)", WMemberFeatureCall).assertIncompatibleTypesIssue("String", "Number") | ||
] | ||
} | ||
|
||
def assertIncompatibleTypesIssue(EObject element, String type1, String type2) { | ||
element.assertAnyIssueInElement( | ||
'''Type system: expected <<«type1»>> but found <<«type2»>>''', | ||
'''Type system: expected <<«type2»>> but found <<«type1»>>''' | ||
) | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,10 +27,10 @@ program p { | |
// XPECT type at c6 --> {() => Number} | ||
const c6 = { if (bool) return 1 else return 2 } | ||
|
||
// XPECT type at c7 --> {() => (Number|String)} | ||
// XPECT type at c7 --> {() => Number} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. acá no entendí si corregiste el type system para que tire error cuando hacés if (bool) { return 1 }
return "2" lo cual me parece razonable y piola. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sí, exactamente eso, porque Number y String ahora no son "compatibles". Esta es una regla media arbitraria, pero había varios tests en donde se esperaba este comportamiento, y no me parecían mal. Ahora el TS es más restrictivo, pero no creo que haya casos así en pdep/obj1 y que no impliquen un "error de diseño". |
||
const c7 = { | ||
if (bool) { return 1 } | ||
return "2" | ||
return 2 | ||
} | ||
|
||
// XPECT type at c8 --> {() => Number} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#1891
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Muy bueno!!! 🥇