uqbar-project / wollok

Wollok Programming Language
GNU General Public License v3.0
60 stars 16 forks source link

Type system does not report errors #1436

Closed npasserini closed 6 years ago

npasserini commented 6 years ago

After merging both builder PRs (last one is $1430) type system does not report any error.

I've found exceptions in WollokResourceUIValidatorExtension and I in my tests the URI comparison in line 30 there never returns true.

Also I see this code is unnecessary complex, and can be replaced by a (lot) more simple version:

    resource.resourceSet.resources.forEach[ res |
        println('''Processing «res.URI»''') 
        val f = res.IFile
        if (!doShouldProcess(file)) {
            addMarkers(f, res, mode, monitor)
        }
    ]

Still, after this change, the WollokTypeSystemBuilderParticipant does not seem to get executed and the only message the TS gets is validate, which now does not much:

    override validate(WFile file, ConfigurableDslValidator validator) {
        log.info('''Validating types of «file.eResource.URI.lastSegment» using «class.simpleName»''')
        // Dodain - only Builder now is responsible for analyzing and inferring types
        //this.analyse(file)
        //this.inferTypes
        file.reportErrors(validator)
    }
fdodino commented 6 years ago

Bueno, ahí estuve revisando un poco. Lo probé en Windows y en Linux y anda ok.

Una cosa que me llamó la atención es que el builder está en un package que tiene typesystem con minúscula, eso me tiró error en Windows, y acabo de renombrar el package en Linux.

Otra cosa que vi es que el ! por el que preguntaba no estaba bien, es al revés, originalmente estaba así. El código quedó

    override updateValidationMarkers(IFile file, Resource resource, CheckMode mode, IProgressMonitor monitor) throws OperationCanceledException {
        if (!file.shouldProcess) {
            return
        }
        addMarkers(file, resource, mode, monitor)
        resource.resourceSet.resources.forEach[ res |
            val f = res.IFile
            if (f !== null && f.shouldProcess) {
                addMarkers(f, res, mode, monitor)
            }
        ]
    }

Con eso no hace falta llamar a getReferenceDescriptions() que era el que tiraba error cuando alguno de los recursos era un CopiedResourceDescription.

Ahora lo que sí pasa es que algunos programas rompen el TS y con eso no se reportan dichos errores. Por ejemplo:

object pepita { 
    const energia = 4
    method volar() {
        energia = 2 + energia 
    }
    method typeError() = 2 * "4"
    method badIf() = if (2) 3 else 4 
}

Esto produce que se rompa el type system:

org.uqbar.project.wollok.typesystem.TypeSystemException: Missing type information for 3
    at org.uqbar.project.wollok.typesystem.constraints.variables.TypeVariablesRegistry.lambda$7(TypeVariablesRegistry.java:166)
    at org.eclipse.xtext.xbase.lib.ObjectExtensions.operator_doubleArrow(ObjectExtensions.java:139)
    at org.uqbar.project.wollok.typesystem.constraints.variables.TypeVariablesRegistry.tvar(TypeVariablesRegistry.java:169)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.AbstractInferenceStrategy.tvar(AbstractInferenceStrategy.java:115)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.GuessMinTypeFromMaxType._afterVisit(GuessMinTypeFromMaxType.java:126)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.GuessMinTypeFromMaxType.afterVisit(GuessMinTypeFromMaxType.java:374)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.GuessMinTypeFromMaxType.visit(GuessMinTypeFromMaxType.java:163)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.GuessMinTypeFromMaxType._visitChildren(GuessMinTypeFromMaxType.java:187)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.GuessMinTypeFromMaxType.visitChildren(GuessMinTypeFromMaxType.java:404)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.GuessMinTypeFromMaxType.visit(GuessMinTypeFromMaxType.java:162)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.GuessMinTypeFromMaxType._visitChildren(GuessMinTypeFromMaxType.java:274)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.GuessMinTypeFromMaxType.visitChildren(GuessMinTypeFromMaxType.java:458)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.GuessMinTypeFromMaxType.visit(GuessMinTypeFromMaxType.java:162)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.GuessMinTypeFromMaxType.lambda$2(GuessMinTypeFromMaxType.java:175)
    at java.lang.Iterable.forEach(Iterable.java:75)

Y lo mismo algo como

object pepita { 
    const energia = 4
    method volar() {
        energia = 2 + energia 
    }
    method typeError() = 2 * "4"
    method badIf() = if (pepita.volar()) 3 else 4 
}

De hecho rompe el IDE.

Por último, el código validate() del TS

    override validate(WFile file, ConfigurableDslValidator validator) {
        log.info('''Validating types of «file.eResource.URI.lastSegment» using «class.simpleName»''')
        // Dodain - only Builder now is responsible for analyzing and inferring types
        //this.analyse(file)
        //this.inferTypes
        file.reportErrors(validator)
    }

reporta los errores de la última vez que se grabó. Salvo que quieras que corra cuando el usuario escribe, me parece que está bien, no se come los errores cuando corre el validator, lo que no hace es refrescar la inferencia de tipos.

fdodino commented 6 years ago

Ahí le encontré la vuelta cuando arranca un proyecto con muchos archivos y también cuando grabás muy rápido. Otra cosa que detecté que rompe el TS es algo como ésto:

object pepita { 
    var energia = 4
    method volar() {
        energia = 2 + energia 
    }
//  method typeError() = 2 * "4"
    method badIf() = if (self.posible()) 3 else 4
    method posible() = energiaw
}

energiaw no existe y se rompe:

java.lang.RuntimeException: eResource null for org.uqbar.project.wollok.wollokDsl.impl.WReferenciableImpl@2f962cdd (eProxyURI: platform:/resource/pepe/src/example.wlk#|3) while verifying for core object
    at org.uqbar.project.wollok.scoping.WollokResourceCache.isCoreObject(WollokResourceCache.java:66)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.GuessMinTypeFromMaxType._shouldVisit(GuessMinTypeFromMaxType.java:104)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.GuessMinTypeFromMaxType.shouldVisit(GuessMinTypeFromMaxType.java:358)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.GuessMinTypeFromMaxType.visit(GuessMinTypeFromMaxType.java:162)
    at org.uqbar.project.wollok.typesystem.constraints.strategies.GuessMinTypeFromMaxType._visitChildren(GuessMinTypeFromMaxType.java:319)