diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/ATypeUtils.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/ATypeUtils.rsc index 5ca6ee00..d5dff58e 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/ATypeUtils.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/ATypeUtils.rsc @@ -875,7 +875,7 @@ AType getTupleFieldType(AType t, str fn) { @doc{Get the type of the tuple field at the given offset.} AType getTupleFieldType(AType t, int fn) { if (atuple(atypeList(tas)) := t) { - if (0 <= fn && fn < size(tas)) return unwrapAType(tas[fn]); + if (0 <= fn && fn < size(tas)) return tas[fn]; // unwrapAType(tas[fn]); throw rascalCheckerInternalError("Tuple does not have field "); } throw rascalCheckerInternalError("getTupleFieldType given unexpected type "); @@ -1004,10 +1004,10 @@ list[str] getMapFieldNames(AType t) { str getMapFieldName(AType t, int idx) = getMapFieldNames(t)[idx]; @doc{Get the domain type of the map.} -AType getMapDomainType(AType t) = unwrapAType(getMapFields(t)[0]); +AType getMapDomainType(AType t) = getMapFields(t)[0]; //unwrapAType(getMapFields(t)[0]); @doc{Get the range type of the map.} -AType getMapRangeType(AType t) = unwrapAType(getMapFields(t)[1]); +AType getMapRangeType(AType t) = getMapFields(t)[1]; //unwrapAType(getMapFields(t)[1]); // ---- bag @@ -1115,7 +1115,7 @@ list[AType] getFunctionArgumentTypes(AType ft) { set[AType] getFunctionTypeParameters(AType ft){ if (af: afunc(_, _, _) := unwrapAType(ft)){ - return {p | /p:aparameter(_,_) := af }; + return {unsetRec(p, "alabel") | /p:aparameter(_,_) := af }; } throw rascalCheckerInternalError("Cannot get Type parameters from non-function type, got "); } @@ -1173,7 +1173,7 @@ AType getFunctionArgumentTypesAsTuple(AType ft) { AType getFunctionReturnType(AType ft) { if (afunc(rt, _, _) := unwrapAType(ft)) return rt; if(overloadedAType(rel[loc, IdRole, AType] _) := unwrapAType(ft)) { - return getResult( unwrapAType(ft)); + return getResult(ft); //getResult( unwrapAType(ft)); } throw rascalCheckerInternalError("Cannot get function return type from non-function type, got "); } diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/Checker.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/Checker.rsc index 310df5b2..5a72f8fa 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/Checker.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/Checker.rsc @@ -224,13 +224,8 @@ ModuleStatus rascalTModelForLocs( topModuleNames = {}; for(mloc <- mlocs){ - //try { m = getModuleName(mloc, pcfg); topModuleNames += {m}; - //} catch str e: { - // ms.messages += [ error("Cannot get module name for , reason: ", mloc) ]; - // return ms; - //} } try { @@ -279,9 +274,6 @@ ModuleStatus rascalTModelForLocs( if(found){ ms.status[m] += {tpl_uptodate(), checked()}; } - //else { - // ms.status[m] += not_found(); - //} } } } @@ -291,7 +283,7 @@ ModuleStatus rascalTModelForLocs( map[str,TModel] tmodels_for_component = (); map[str,set[str]] m_imports = (); map[str,set[str]] m_extends = (); - for(m <- component, not_found() notin ms.status[m]){ + for(m <- component, not_found() notin ms.status[m], MStatus::ignored() notin ms.status[m]){ imports = { imp | <- ms.strPaths, m1 == m }; m_imports[m] = imports; extends = { ext | <- ms.strPaths, m1 == m }; @@ -351,7 +343,7 @@ ModuleStatus rascalTModelForLocs( // generate code for the modules in this component - for(str m <- component){ + for(str m <- component, MStatus::ignored() notin ms.status[m]){ = getModuleParseTree(m, ms); if(success){ msgs = codgen(m, pt, ms, compilerConfig); @@ -418,7 +410,14 @@ tuple[TModel, ModuleStatus] rascalTModelComponent(set[str] moduleNames, ModuleSt for(str nm <- moduleNames){ = getModuleParseTree(nm, ms); if(success){ - namedTrees[nm] = pt; + tagsMap = getTags(pt.header.tags); + + if(ignoreCompiler(tagsMap)) { + ms.messages[nm] ? [] += [ Message::info("Ignoring module ", pt@\loc) ]; + ms.status[nm] += MStatus::ignored(); + } else { + namedTrees[nm] = pt; + } } //else { // ms.messages[nm] += error("Cannot get parse tree for module ``", ms.moduleLocs[nm]); @@ -435,7 +434,7 @@ tuple[TModel, ModuleStatus] rascalTModelComponent(set[str] moduleNames, ModuleSt rascalPreCollectInitialization(namedTrees, c); added = {}; - for(str nm <- moduleNames){ + for(str nm <- domain(namedTrees)){ = loadImportsAndExtends(nm, ms, c, added); added += a; } @@ -447,8 +446,10 @@ tuple[TModel, ModuleStatus] rascalTModelComponent(set[str] moduleNames, ModuleSt tm.paths = ms.paths; - s = newSolver(namedTrees, tm); - tm = s.run(); + if(!isEmpty(namedTrees)){ + s = newSolver(namedTrees, tm); + tm = s.run(); + } check_time = (cpuTime() - start_check)/1000000; diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDataDeclaration.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDataDeclaration.rsc index 738077a7..f68a1153 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDataDeclaration.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDataDeclaration.rsc @@ -25,11 +25,16 @@ void collect (current: (Declaration) ` data < = dataDeclaration(tags, current, [v | v <- variants], c); void dataDeclaration(Tags tags, Declaration current, list[Variant] variants, Collector c){ - tagsMap = getTags(tags); - if(ignoreCompiler(tagsMap)) { println("*** ignore: "); return; } - userType = current.user; adtName = prettyPrintName(userType.name); + + tagsMap = getTags(tags); + if(ignoreCompiler(tagsMap)) { + c.report(info(current, "Ignoring declaration of ``")); + return; + } + + commonKeywordParameterList = getCommonKwFormals(current); typeParameters = getTypeParameters(userType); diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDeclaration.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDeclaration.rsc index 63de5235..e3284679 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDeclaration.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDeclaration.rsc @@ -42,7 +42,10 @@ void collect(Module current: (Module) `
`, Collector c tagsMap = getTags(header.tags); - //if(ignoreCompiler(tagsMap)) {println("*** ignore module "); return; } + if(ignoreCompiler(tagsMap)) { + c.report(info(current, "Ignoring module ")); + return; + } = getDeprecated(tagsMap); tmod = deprecated ? amodule(mname, deprecationMessage=deprecationMessage) : amodule(mname); @@ -55,7 +58,6 @@ void collect(Module current: (Module) `
`, Collector c c.enterScope(current); collect(header, body, c); c.leaveScope(current); - //c.pop(key_current_module); // leave it there for all following phases to see } void checkModuleName(loc mloc, QualifiedName qualifiedModuleName, Collector c){ @@ -149,11 +151,14 @@ void collect(Tag tg, Collector c){ // Deprecated void collect(current: (Declaration) ` anno @ ;`, Collector c){ c.report(warning(current, "Annotations are deprecated, use keyword parameters instead")); + pname = prettyPrintName(name); tagsMap = getTags(tags); - if(ignoreCompiler(tagsMap)) { println("*** ignore: "); return; } + if(ignoreCompiler(tagsMap)) { + c.report(info(current, "Ignoring anno declaration for ``")); + return; + } - pname = prettyPrintName(name); dt = defType([annoType, onType], AType(Solver s) { return aanno(pname, s.getType(onType), s.getType(annoType)); }); dt.vis = getVis(current.visibility, publicVis()); dt.md5 = md5Hash(""); @@ -194,7 +199,10 @@ void collect(current: (FunctionDeclaration) ``, Collec fname = signature.name; modifiers = ["" | m <- signature.modifiers.modifiers]; tagsMap = getTags(decl.tags); - if(ignoreCompiler(tagsMap)) { println("ignore: function "); return; } + if(ignoreCompiler(tagsMap)) { + c.report(info(current, "Ignoring function declaration for ``")); + return; + } = getExpected(decl.tags); if(expected){ @@ -583,58 +591,34 @@ void collect(Parameters parameters, Collector c){ endPatternScope(c); } -void(Solver) makeReturnRequirement(Tree returnExpr, Type declaredReturnType) +void(Solver) makeReturnRequirement(Tree returnExpr, Type returnType) = void(Solver s){ - theDeclaredReturnType = s.getType(declaredReturnType); - returnRequirement(returnExpr, theDeclaredReturnType, s); + returnRequirement(returnExpr, s.getType(returnType), s); }; -void(Solver) makeReturnRequirement(Tree returnExpr, AType declaredReturnAType) +void(Solver) makeReturnRequirement(Tree returnExpr, AType returnAType) = void(Solver s){ - returnRequirement(returnExpr, declaredReturnAType, s); + returnRequirement(returnExpr, returnAType, s); }; -bool isParameterized(AType t){ - return /aparameter(_,_) := t; -} -void returnRequirement(Tree returnExpr, AType declaredReturnType, Solver s){ - +void returnRequirement(Tree returnExpr, AType declaredReturnType, Solver s){ returnExprType = s.getType(returnExpr); - + allTypeParametersInReturnType = { unsetRec(p, "alabel") | /p:aparameter(_,_) := declaredReturnType }; + allTypeParametersInExpr = { unsetRec(p, "alabel") | /Expression e := returnExpr, /p:aparameter(_,_) := s.getType(e) }; + missingTypeParameters = allTypeParametersInReturnType - allTypeParametersInExpr; + + if(!isEmpty(missingTypeParameters)){ + s.report(error(returnExpr, "Return expression does not bind %v in return type", missingTypeParameters)); + } + Bindings bindings = (); - try bindings = matchRascalTypeParams(returnExprType, declaredReturnType, bindings); + try bindings = matchRascalTypeParams(declaredReturnType, returnExprType, bindings); catch invalidMatch(str reason): s.report(error(returnExpr, reason)); - - if(isParameterized(returnExprType)){ - if(!isParameterized(declaredReturnType)){ - if(!s.subtype(returnExprType, declaredReturnType)){ - s.report(error(returnExpr, "Cannot return a parameterized type %t, when declared return type %t is not parameterized", returnExprType, declaredReturnType)); - } - } - } else if(isParameterized(declaredReturnType)){ - if(!s.subtype(returnExprType, declaredReturnType)){ - s.report(error(returnExpr, "Cannot return a non-parameterized type %t, when declared return type %t is parameterized", returnExprType, declaredReturnType)); - } - } - actualReturnType = returnExprType; - try { - actualReturnType = instantiateRascalTypeParameters(returnExpr, returnExprType, bindings, s); - } catch invalidInstantiation(str reason):{ - s.report(error(returnExpr, "Returned type %t does not match declared type %t: %v", returnExprType, declaredReturnType, reason)); - } - - if(s.isFullyInstantiated(actualReturnType)){ - s.requireTrue(s.equal(actualReturnType, avoid()) ? s.equal(declaredReturnType, avoid()) - : s.subtype(actualReturnType, declaredReturnType), - error(returnExpr, "Return type %t expected, found %t", declaredReturnType, actualReturnType)); - } else - if(!s.unify(actualReturnType, declaredReturnType)){ - s.requireTrue(s.equal(actualReturnType, avoid()) ? s.equal(declaredReturnType, avoid()) - : s.subtype(actualReturnType, declaredReturnType), - error(returnExpr, "Return type %t expected, found %t", declaredReturnType, actualReturnType)); - } + s.requireTrue(s.equal(returnExprType, avoid()) ? s.equal(declaredReturnType, avoid()) + : s.subtype(returnExprType, declaredReturnType), + error(returnExpr, "Return type %t expected, found %t", declaredReturnType, returnExprType)); } // ---- return statement (closely interacts with function declaration) -------- @@ -644,7 +628,7 @@ void collect(current: (Statement) `return `, Collector c){ assert !isEmpty(functionScopes); for(<_, scopeInfo> <- functionScopes){ if(returnInfo(Type returnType) := scopeInfo){ - c.require("check return type", current, [returnType], makeReturnRequirement(statement, returnType)); + c.require("check return type", current, [statement], makeReturnRequirement(statement, returnType)); c.fact(current, returnType); // Note that type of the return statement as a whole is the function's return type collect(statement, c); return; @@ -658,10 +642,13 @@ void collect(current: (Statement) `return `, Collector c){ // ---- alias declaration ----------------------------------------------------- void collect (current: (Declaration) ` alias = ;`, Collector c){ + aliasName = prettyPrintName(name); tagsMap = getTags(tags); - if(ignoreCompiler(tagsMap)) { println("*** ignore: "); return; } + if(ignoreCompiler(tagsMap)) { + c.report(info(current, "Ignoring alias declaration for ``")); + return; + } - aliasName = prettyPrintName(name); c.define(aliasName, aliasId(), current, defType([base], AType(Solver s) { return s.getType(base); })[md5 = md5Hash("")]); c.enterScope(current); collect(base, c); @@ -669,11 +656,14 @@ void collect (current: (Declaration) ` alias } void collect (current: (Declaration) ` alias [ <{Type ","}+ parameters> ] = ;`, Collector c){ + aliasName = prettyPrintName(name); tagsMap = getTags(tags); - if(ignoreCompiler(tagsMap)) { println("*** ignore: "); return; } - aliasName = prettyPrintName(name); - + if(ignoreCompiler(tagsMap)) { + c.report(info(current, "Ignoring alias declaration for ``")); + return; + } + typeVars = for(tp <- parameters){ if(!(tp has typeVar)) c.report(error(tp, "Only type parameter allowed")); append tp.typeVar; diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectExpression.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectExpression.rsc index 6a0f5b58..6d3b8814 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectExpression.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectExpression.rsc @@ -1010,7 +1010,6 @@ void collect(current:(Expression) ` \< <{Field ","}+ fiel checkNonVoid(expression, s, "Base expression of field projection"); return computeFieldProjectionType(current, s.getType(expression), flds, s); }); - //collectParts(current, c); collect(expression, fields, c); } diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectPattern.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectPattern.rsc index 7bef0031..ef54c6d0 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectPattern.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectPattern.rsc @@ -348,7 +348,7 @@ void collect(current: (Pattern) `[ ] `, Collector c){ c.require("asType", current, [tp, p], void(Solver s){ if(!isStrAType(s.getType(p))){ - s.requireSubType(p, tp, error(p, "Pattern should be subtype of %t, found %t", tp, p)); + s.requireComparable(p, tp, error(p, "Pattern should be subtype of %t, found %t", tp, p)); } }); collect(tp, c); diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/Import.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/Import.rsc index e4c3ec91..7c2e02ab 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/Import.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/Import.rsc @@ -215,6 +215,7 @@ data MStatus = | code_generated() | tpl_uptodate() | tpl_saved() + | ignored() ; data ModuleStatus = @@ -408,7 +409,7 @@ set[loc] getImportLocsOfModule(str qualifiedModuleName, set[Module] modules) // ---- Save modules ---------------------------------------------------------- map[str, loc] getModuleScopes(TModel tm) - = (id: defined | <- tm.defines); + = (id: defined | <- tm.defines); loc getModuleScope(str qualifiedModuleName, map[str, loc] moduleScopes, PathConfig pcfg){ if(moduleScopes[qualifiedModuleName]?){ @@ -427,12 +428,12 @@ ModuleStatus preSaveModule(set[str] component, map[str,set[str]] m_imports, map[ pcfg = ms.pathConfig; dependencies_ok = true; - for(m <- component, not_found() notin ms.status[m]){ + for(m <- component, not_found() notin ms.status[m], MStatus::ignored() notin ms.status[m]){ if(parse_error() in ms.status[m]){ ms.tmodels[m] = tmodel(modelName=m,messages=ms.messages[m]); return ms; } - for(imp <- m_imports[m] + m_extends[m], not_found() notin ms.status[imp]){ + for(imp <- m_imports[m] + m_extends[m], not_found() notin ms.status[imp], MStatus::ignored() notin ms.status[m]){ imp_status = ms.status[imp]; if(parse_error() in imp_status || checked() notin imp_status){ dependencies_ok = false; @@ -445,7 +446,7 @@ ModuleStatus preSaveModule(set[str] component, map[str,set[str]] m_imports, map[ return ms; } } - for(m <- component, not_found() notin ms.status[m]){ + for(m <- component, not_found() notin ms.status[m], MStatus::ignored() notin ms.status[m]){ tm.modelName = m; mScope = getModuleScope(m, moduleScopes, pcfg); tm.moduleLocs = (m : mScope); @@ -464,7 +465,7 @@ ModuleStatus doSaveModule(set[str] component, map[str,set[str]] m_imports, map[s map[str,datetime] moduleLastModified = ms.moduleLastModified; pcfg = ms.pathConfig; - if(any(c <- component, !isEmpty({parse_error(), not_found()} & ms.status[c]))){ + if(any(c <- component, !isEmpty({parse_error(), not_found(), MStatus::ignored()} & ms.status[c]))){ return ms; } //println("doSaveModule: , , , "); diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/tests/StaticTestingUtils.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/tests/StaticTestingUtils.rsc index 46032199..b817b96f 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/tests/StaticTestingUtils.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/tests/StaticTestingUtils.rsc @@ -105,6 +105,7 @@ bool unexpectedType(str stmts, list[str] importedModules = [], list[str] initial "_ is defined as _ and cannot be applied to argument", "Missing return statement", "Return type _ expected, found _", + "Return expression does not bind _", "Type of generator should be _, found _", "Pattern should be comparable with _, found _", "Argument of _ should be _, found _", diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst5.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst5.rsc index e32c2466..6f58adc7 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst5.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst5.rsc @@ -1,6 +1,14 @@ module lang::rascalcore::compile::Examples::Tst5 - + +&T <: num makeSmallerThan(&T <: num n) { + &T <: num res; + if (int i := n) { + res = i; + return res; + } + return n; +} //import List; // //value main(){ @@ -14,9 +22,3 @@ module lang::rascalcore::compile::Examples::Tst5 //} - -//import util::Maybe; -// -// &T testFunction(Maybe[&T] _, &T x) = x; -// -// value main() = testFunction(just(3), 5);