Skip to content

Commit

Permalink
Merge a80682b into 75ef9d3
Browse files Browse the repository at this point in the history
  • Loading branch information
PalumboN committed Aug 2, 2020
2 parents 75ef9d3 + a80682b commit 6ce32e6
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,42 @@
/* XPECT_SETUP org.uqbar.project.wollok.tests.typesystem.xpect.TypeSystemXpectTestCase END_SETUP */

object advancedClosures {
// XPECT methodType at next --> (Number) => Number
// XPECT methodType at next --> (Number) => Number
method next(n) {
return { a => a + 1 }.apply(n)
}
}

object incompatibility {
//const numbers = [1,2,3]

method closure_vs_basic_type() {
// XPECT warnings --> "Type system: expected <<{(Number) => Boolean}>> but found <<String>>" at ""ERROR""
return [1,2,3].filter("ERROR")
}

method basic_vs_closure_type() {
// XPECT warnings --> "Type system: expected <<Number>> but found <<{() => String}>>" at "{"ERROR"}"
return [1,2,3].contains({"ERROR"})
}

method closure_type_with_different_params() {
// XPECT warnings --> "Type system: expected <<{(Number) => Boolean}>> but found <<{() => Boolean}>>" at "{true}"
return [1,2,3].filter({true})
}

method incompatible_param_closure_type() {
// XPECT warnings --> "Number does not understand startsWith("ERROR")" at "n.startsWith("ERROR")"
return [1,2,3].filter({n => n.startsWith("ERROR")})
}

method incompatible_return_closure_type() {
// XPECT warnings --> "Type system: expected <<Boolean>> but found <<String>>" at "{n => "ERROR"}"
return [1,2,3].any({n => "ERROR"})
}

method infinite_closure_type(c) {
// XPECT warnings --> "Type system: Infinite recursive type" at "c"
return [c].filter(c)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class Messages extends NLS {
public static String TypeSystemException_NOT_VALID_SUBSTITUTE;
public static String TypeSystemException_MISSING_TYPE_INFORMATION;
public static String TypeSystemException_REJECTED_MIN_TYPE_MESSAGE;
public static String TypeSystemException_INFINITE_RECURSIVE_TYPE;

public static String RuntimeTypeSystemException_CANT_FIND_MIN_TYPE;
public static String RuntimeTypeSystemException_CANT_EXTRACT_METHOD_TYPE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import org.uqbar.project.wollok.typesystem.WollokType
import static org.uqbar.project.wollok.sdk.WollokSDK.*

import static extension org.uqbar.project.wollok.model.WollokModelExtensions.*
import org.uqbar.project.wollok.typesystem.constraints.variables.GenericTypeInstance

class CompatibilityTypes {
static val basicTypes = newArrayList(NUMBER, BOOLEAN, STRING)
static val basicTypes = newArrayList(NUMBER, BOOLEAN, STRING, DATE, CLOSURE)

static def boolean isBasic(ClassInstanceType type) {
basicTypes.contains(type.clazz.fqn)
Expand All @@ -21,6 +22,12 @@ class CompatibilityTypes {
static def dispatch boolean isCompatible(WollokType supertype, WollokType subtype) {
return true
}

static def dispatch boolean isCompatible(GenericTypeInstance supertype, GenericTypeInstance subtype) {
val supertypeParams = supertype.typeParameters.keySet
val subtypeParams = subtype.typeParameters.keySet
return supertypeParams.length == subtypeParams.length && supertypeParams.containsAll(subtypeParams)
}

/** Basic type is only compatible with itself */
static def dispatch boolean isCompatible(ClassInstanceType supertype, ClassInstanceType subtype) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import static extension org.uqbar.project.wollok.typesystem.constraints.types.Me
import static extension org.uqbar.project.wollok.typesystem.constraints.types.SubtypingRules.isSuperTypeOf
import static extension org.uqbar.project.wollok.typesystem.constraints.variables.AnalysisResultReporter.*
import static extension org.uqbar.project.wollok.typesystem.constraints.variables.ConcreteTypeStateExtensions.*
import org.uqbar.project.wollok.typesystem.exceptions.InfiniteRecursiveTypeException

class GenericTypeInfo extends TypeInfo {
@Accessors
Expand Down Expand Up @@ -93,12 +94,14 @@ class GenericTypeInfo extends TypeInfo {
if (matchingMaxType !== null) {
type.beSubtypeOf(matchingMaxType)
} else {
error(new RejectedMinTypeException(offender, type, maxTypes.maximalConcreteTypes))
error(new RejectedMinTypeException(offender, type, maxTypes.maximalConcreteTypes, !users.contains(offender)))
maxTypes.state = Error
}
}
]

maxTypes.forEach[validateInfiniteRecursiveType(offender, maxTypes)]

if (maxTypes.state == Error) {
false
} else if (maximalConcreteTypes === null) {
Expand All @@ -108,6 +111,20 @@ class GenericTypeInfo extends TypeInfo {
maximalConcreteTypes.restrictTo(maxTypes)
}
}

def dispatch validateInfiniteRecursiveType(WollokType type, TypeVariable offender, MaximalConcreteTypes maxTypes) {
// No possible
}

def dispatch validateInfiniteRecursiveType(GenericTypeInstance it, TypeVariable offender, MaximalConcreteTypes maxTypes) {
typeParameters.values.forEach[paramVar |
if (users.contains(paramVar)) {
offender.addError(new InfiniteRecursiveTypeException(offender))
maxTypes.state = Error
}
]

}

/**
* Join maxtype information coming from two different tvar's. Null information has to be taken care from both sides,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.uqbar.project.wollok.typesystem.exceptions

import org.uqbar.project.wollok.typesystem.Messages
import org.uqbar.project.wollok.typesystem.TypeSystemException
import org.uqbar.project.wollok.typesystem.constraints.variables.TypeVariable

class InfiniteRecursiveTypeException extends TypeSystemException {

new(TypeVariable variable) {
super(variable)
}

override getMessage() { Messages.TypeSystemException_INFINITE_RECURSIVE_TYPE }
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import static extension org.uqbar.project.wollok.typesystem.constraints.variable
class RejectedMinTypeException extends TypeSystemException {
WollokType type
Set<WollokType> expectedTypes = newHashSet

Boolean reverse = false // Expected vs actual

new(TypeVariable variable, WollokType type) {
super(variable)
this.type = type
Expand All @@ -25,6 +26,11 @@ class RejectedMinTypeException extends TypeSystemException {
this.expectedTypes = expectedTypes
}

new(TypeVariable variable, WollokType type, Set<WollokType> expectedTypes, Boolean reverse) {
this(variable, type, expectedTypes)
this.reverse = reverse
}

/**
* This constructor allows for a later assignment of the offending variable,
* for cases in which we want a more sophisticated algorithm for determining it.
Expand All @@ -37,16 +43,19 @@ class RejectedMinTypeException extends TypeSystemException {
// Support null `variable`. While it should not happen and means
// a program error, it is not nice to throw a NPE inside the toString
// of a previous exception.
NLS.bind(Messages.TypeSystemException_REJECTED_MIN_TYPE_MESSAGE, expectedType, type)
if (reverse)
NLS.bind(Messages.TypeSystemException_REJECTED_MIN_TYPE_MESSAGE, type, expectedType)
else
NLS.bind(Messages.TypeSystemException_REJECTED_MIN_TYPE_MESSAGE, expectedType, type)
}

def expectedType() {
if (!expectedTypes.isEmpty) return expectedTypes.join("|")
if (variable !== null) variable.expectedType else Constants.UNKNOWN
if(!expectedTypes.isEmpty) return expectedTypes.join("|")
if(variable !== null) variable.expectedType else Constants.UNKNOWN
}

override relatedToType(WollokType typeRelated) {
type == typeRelated
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ TypeSystemException_INCOMPATIBLE_TYPE_NOT_SUPPORTED_MESSAGES = Type system: Inco
TypeSystemException_NOT_VALID_SUBSTITUTE = Type system: <<{0}>> is not a valid substitute for <<{1}>>
TypeSystemException_MISSING_TYPE_INFORMATION = Type system: Missing type information for {0}
TypeSystemException_REJECTED_MIN_TYPE_MESSAGE = Type system: expected <<{0}>> but found <<{1}>>
TypeSystemException_INFINITE_RECURSIVE_TYPE = Type system: Infinite recursive type

RuntimeTypeSystemException_CANT_FIND_MIN_TYPE = ConstraintBasedTypeSystem: can't find a minType compatible with {0}.{1}, known minTypes are {2}
RuntimeTypeSystemException_CANT_EXTRACT_METHOD_TYPE = ConstraintBasedTypeSystem: can't extract MethodTypeSchema for methods of {0}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ TypeSystemException_INCOMPATIBLE_TYPE_EXPECTED = Sistema de tipos: Tipos incompa
TypeSystemException_INCOMPATIBLE_TYPE_NOT_SUPPORTED_MESSAGES = Sistema de tipos: Tipos incompatibles. El tipo <<{0}>> no soporta los siguientes mensajes {1}
TypeSystemException_NOT_VALID_SUBSTITUTE = Sistema de tipos: El tipo <<{0}>> no es un sustituto v\u00E1lido para <<{1}>>
TypeSystemException_MISSING_TYPE_INFORMATION = Sistema de tipos: Falta informaci\u00F3n de tipos para {0}
TypeSystemException_REJECTED_MIN_TYPE_MESSAGE = Sistema de tipos: se esperaba <<{0}>> pero se encontr\u00F3 <<{1}>>
TypeSystemException_REJECTED_MIN_TYPE_MESSAGE = Sistema de tipos: Se esperaba <<{0}>> pero se encontr\u00F3 <<{1}>>
TypeSystemException_INFINITE_RECURSIVE_TYPE = Sistema de tipos: El tipo es recursivamente infinito

RuntimeTypeSystemException_CANT_FIND_MIN_TYPE = ConstraintBasedTypeSystem: no es posible encontrar un minType compatible con {0}.{1}, los minTypes conocidos son {2}
RuntimeTypeSystemException_CANT_EXTRACT_METHOD_TYPE = ConstraintBasedTypeSystem: no se puede extraer el MethodTypeSchema para los m\u00E9todos de {0}
Expand Down

0 comments on commit 6ce32e6

Please sign in to comment.