helium-1.8: src/Helium/StaticAnalysis/StaticChecks/StaticChecks.ag
-----------------------------------------------------------------------------
-- |The Helium Compiler : Static Analysis
--
-- Maintainer : bastiaan@cs.uu.nl
-- Stability : experimental
-- Portability : unknown
--
-- A static analyzer. The checks are defined in the included ag-modules.
--
-----------------------------------------------------------------------------
ATTR Module
[ baseName : String
importEnvironments : ImportEnvironments
options : {[Option]}
|
| collectEnvironment : ImportEnvironment
errors : Errors
typeSignatures : {[(Name,TpScheme)]}
warnings : Warnings
]
ATTR Module -> Type [ options : {[Option]} || ]
INCLUDE "Collect.ag"
INCLUDE "UHA_Syntax.ag"
INCLUDE "Scope.ag"
INCLUDE "KindChecking.ag"
INCLUDE "Warnings.ag"
INCLUDE "TopLevelErrors.ag"
INCLUDE "MiscErrors.ag"
INCLUDE "ExportErrors.ag"
INCLUDE "HeliumPartialSyntax.ag"
INCLUDE "ScopeErrors.ag"
imports {
import Helium.Utils.Similarity ( similar )
import Helium.Main.Args
import Helium.Syntax.UHA_Syntax
import Helium.Syntax.UHA_Utils
import Helium.Syntax.UHA_Range
import Top.Types
import Helium.StaticAnalysis.Messages.StaticErrors
import Helium.StaticAnalysis.Messages.Warnings
import Helium.StaticAnalysis.Messages.Messages
import Data.List
import Helium.Utils.Utils ( internalError, minInt, maxInt )
import Helium.StaticAnalysis.Miscellaneous.TypeConversion
import Helium.CodeGeneration.DerivingShow
import qualified Data.Map as M
import Helium.ModuleSystem.ImportEnvironment
import Helium.Parser.OperatorTable
import Data.Char ( isUpper )
}
-- combine all the collected errors, then filter out the "entity is undefined"
-- errors that are caused by the removal of "duplicated entities"
SEM Module
| Module lhs . errors = filter (\err -> filterRemovedNames @removedEntities err
&& filterDerivedNames @derivedRanges err) @allErrors
. warnings = @scopeWarnings ++ @warnings
loc . allErrors = concat [ @exportErrors
, @scopeErrors
, @miscerrors
, if KindInferencing `elem` @lhs.options then [] else @kindErrors
, @topLevelErrors
]
. removedEntities = [ (name,TypeConstructor) | name:_ <- @duplicatedTypeConstructors ] ++
[ (name,Constructor ) | name:_ <- @duplicatedValueConstructors ]
. derivedRanges = map getNameRange (map fst @derivedFunctions)
. initialScope = map fst @derivedFunctions ++
concatMap (M.keys . typeEnvironment) @lhs.importEnvironments
{
-- filter undefined errors that are caused by the removal of a duplicate definition
filterRemovedNames :: [(Name,Entity)] -> Error -> Bool
filterRemovedNames list err =
case err of
Undefined entity name _ _ -> (name,entity) `notElem` list
_ -> True
filterDerivedNames :: [Range] -> Error -> Bool
filterDerivedNames ranges err =
case err of
Duplicated Definition names -> any (`notElem` ranges) (map getNameRange names)
_ -> True
}
ATTR FunctionBinding FunctionBindings LeftHandSide [ | | name:Name ]
ATTR Patterns LeftHandSide [ | | numberOfPatterns : Int ]
SEM FunctionBindings
| Cons lhs . name = @hd.name
| Nil lhs . name = internalError "StaticChecks.ag" "n/a" "empty FunctionBindings"
SEM FunctionBinding
| Hole lhs . name = internalError "StaticChecks.ag" "n/a" "empty FunctionBindings"
SEM LeftHandSide
| Function lhs . name = @name.self
| Infix lhs . name = @operator.self
. numberOfPatterns = 2
| Parenthesized lhs . numberOfPatterns = @lefthandside.numberOfPatterns + @patterns.numberOfPatterns
SEM Patterns
| Cons lhs . numberOfPatterns = 1 + @tl.numberOfPatterns
| Nil lhs . numberOfPatterns = 0