/**
* Report the errors of a Java CompilationUnit
*
* @author Martin Bravenboer <martin@cs.uu.nl>
* @author Lennart Kats <lennart add lclnet.nl>
*/
module dryad/errors/Main
imports
dryad/type-check/-
libjava-front
libstratego-lib
signature
constructors
DryadError : String * Expr -> DryadError
DryadWarning : String * Expr -> DryadWarning
strategies
/**
* Collect all type checker errors and report them using
* dryad-simple-error-report.
*/
dryad-errors =
dryad-collect-errors
; list-loop(dryad-simple-error-report)
dryad-collect-errors =
collect-all(dryad-fetch-error)
/**
* Collect (type) errors
*/
strategies
/**
* @type Error -> Error
*/
dryad-simple-error-report =
if ?DryadError(msg, e) then
severity := Error()
else
?DryadWarning(msg, e)
; severity := Warning()
end
; where(
pp := <try(pp-java5-to-string)> e
; log(|severity, msg)
; log(|severity, <prefix-lines(|" ")> pp)
; if <sub-expressions> e => args; not([]) then
log(|severity, " inferred types of arguments: ")
; !args
; map({e1, ppe1, pptype1:
?e1
; <pp-java5-to-string> e1 => ppe1
; <type-attr; pp-java5-to-string> e1 => pptype1
; <conc-strings> (" ", <trim-chars('\n' + ' ')> ppe1, ": ", pptype1)
; log(|severity, <id>)
})
end
)
strategies
/**
* Innermost type error in expression.
*/
dryad-fetch-error =
is-Expr
; ?e
; where(
<not(type-attr)> e
; <sub-expressions; map(type-attr)> e
)
; if ?ExprName(_) then
!DryadError("Cannot find symbol.", e)
else
!DryadError("Unable to assign a type to this expression.", e)
end
/**
* Variable assigned without an assignment conversion.
* @todo Change from 'warning' to 'error' once this gets annotated.
*/
dryad-fetch-error =
(?VarDec(_, e) + ?Assign(_, e)) => assign
; where(<type-attr> e)
; where(get-annos; not(fetch(?AssignmentConversion(_))))
; !DryadWarning("Incompatible types.", assign)
/**
* Foreach assignment without conversion.
*/
dryad-fetch-error =
?ForEach(param, iterator, _) => for
; where(<type-attr> iterator)
; where(!param; get-annos; not(fetch(?AssignmentConversion(_))))
; !DryadError("For loop identifier cannot be converted to the expected type.", for)
/**
* @todo error for: Return without conversion.
*
dryad-fetch-error =
?Return(Some(e)) => return
; where(<type-attr> e)
; where(get-annos; not(fetch(AssignmentConversion(id))))
; !DryadError("Incompatible return type.", return)
*/
strategies
/**
* Apply 'ifthen' if this is an innermost error.
*/
dryad-if-innermost-error(ifthen) =
dryad-if-innermost-error(ifthen, id)
/**
* Apply 'ifthen' if this is an innermost error. Otherwise apply ifelse.
*/
dryad-if-innermost-error(ifthen, ifelse) =
if dryad-fetch-error then ifthen else ifelse end
strategies
/**
* Returns the sub-expressions of an expression.
*
* @type Expr -> List(Expr)
*/
sub-expressions =
get-arguments-of-invocation
<+ ?_#(<id>)
; filter(is-Expr)