Skip to content

Commit

Permalink
Merge da6b0f8 into 02d7f28
Browse files Browse the repository at this point in the history
  • Loading branch information
JavierGelatti authored Dec 29, 2018
2 parents 02d7f28 + da6b0f8 commit b1e37f5
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
/* XPECT_SETUP org.uqbar.project.wollok.tests.xpect.WollokXPectTest END_SETUP */

class Arma {
method artefacto()
}

class EspadaConcreta inherits Arma {
const property artefacto = new Object()
}

class EspadaAbstracta inherits Arma {}

class A {
method m1(x)
}

class B inherits A {
var property m1
}

class C inherits A {
const property m1
}


describe "group of tests" {

var valor = 4
Expand All @@ -21,4 +44,22 @@ describe "group of tests" {
var property localVariable = 0
assert.notEquals(3, cuatro)
}

test "no se puede instanciar una clase a la que le falta implementar métodos abstractos" {
// XPECT errors --> "Class EspadaAbstracta cannot be instantiated because it has abstract methods: artefacto() (required by Arma)" at "EspadaAbstracta"
assert.notEquals(null, new EspadaAbstracta())

// XPECT errors --> "Class C cannot be instantiated because it has abstract methods: m1(x) (required by A)" at "C"
assert.notEquals(null, new C())
}

test "se puede instanciar una clase que define una const property como implementación de un método abstracto" {
assert.notEquals(null, new EspadaConcreta().artefacto())
}

test "se puede instanciar una clase que define una var property como implementación de un método abstracto" {
const b = new B()
b.m1(5)
assert.notEquals(5, b.m1())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,20 +134,37 @@ class WMethodContainerExtensions extends WollokModelExtensions {

// rename: should be non-implemented abstract methods
def static allAbstractMethods(WMethodContainer c) {
val hierarchy = c.linearizeHierarchy
val concreteMethods = <WMethodDeclaration>newArrayList
hierarchy.reverse.fold(<WMethodDeclaration>newArrayList) [unimplementedMethods, chunk |
concreteMethods.addAll(chunk.methods.filter[!abstract])
// remove implemented
unimplementedMethods.removeIf[chunk.overrides(it)]
// add NEW abstracts (abstracts on mixins can be overridden by an upper class / mixin in the chain!)
val newAbstractsNotImplementedUpInTheHierarchy = chunk.abstractMethods.filter[abstractM |
!concreteMethods.exists[m| abstractM.matches(m.name, m.parameters) ]
]
unimplementedMethods.addAll(newAbstractsNotImplementedUpInTheHierarchy)
c.linearizeHierarchy.reverse.fold(<WMethodDeclaration>newArrayList) [unimplementedMethods, methodContainer |
// remove implemented methods
unimplementedMethods.removeIf[methodContainer.overrides(it)]

unimplementedMethods.addAll(c.notImplementedMethodsOf(methodContainer))
unimplementedMethods
]
}

protected def static Iterable<WMethodDeclaration> notImplementedMethodsOf(WMethodContainer methodContainer, WMethodContainer abstractMethodContainer) {
val concreteMethods = methodContainer.allConcreteMethods
val propertyGetters = methodContainer.allPropertiesGetters
val propertySetters = methodContainer.allPropertiesSetters

abstractMethodContainer.abstractMethods.reject[abstractMethod |
abstractMethod.isImplementedBy(concreteMethods, propertyGetters, propertySetters)
]
}

protected def static ArrayList<WMethodDeclaration> allConcreteMethods(WMethodContainer c) {
c.linearizeHierarchy.reverse.fold(<WMethodDeclaration>newArrayList) [concreteMethods, methodContainer |
concreteMethods.addAll(methodContainer.methods.filter[!abstract])
concreteMethods
]
}

protected def static boolean isImplementedBy(WMethodDeclaration abstractMethod, List<WMethodDeclaration> concreteMethods, Iterable<WVariableDeclaration> propertyGetters, Iterable<WVariableDeclaration> propertySetters) {
concreteMethods.exists[m| abstractMethod.matches(m.name, m.parameters)] ||
propertyGetters.exists[property| abstractMethod.matches(property.variable.name, 0)] ||
propertySetters.exists[property| abstractMethod.matches(property.variable.name, 1)]
}

def static getAllMessageSentToThis(WMethodContainer it) {
eAllContents.filter(WMemberFeatureCall).filter[memberCallTarget.isThis].toIterable
Expand Down

0 comments on commit b1e37f5

Please sign in to comment.