diff --git a/sources/zweic/Analyzer.scala b/sources/zweic/Analyzer.scala index 2d97877..9e63688 100755 --- a/sources/zweic/Analyzer.scala +++ b/sources/zweic/Analyzer.scala @@ -90,8 +90,8 @@ checkSubtype(tree.pos, "redefinition of class method '"+name+"' has incompatible returntype", m.restype, rt); if ( !m.paramtypes.zip(paramtypes).forall(x:Pair[Type,Type] => x._1.isSubtype(x._2)) ) { - Report.error(tree.pos, "incompatible argument types for class method redefinition: \nrequired:" + paramtypes.foldLeft(" ")((a,b)=>a + b) + - "\nfound:" + m.paramtypes.foldLeft(" ")((a,b)=>a + b) ); + Report.error(tree.pos, "incompatible argument types for class method redefinition: \n required: " + paramtypes.foldLeft("")((a,b)=>a + " " + b) + + "\n found: " + m.paramtypes.foldLeft("")((a,b)=>a + " " + b) ); } ownerClass.enterMethod(name.sym.asInstanceOf[MethodSymbol]); @@ -206,8 +206,8 @@ } val argtypes = args.map(x => analyzeExpr(varScope, x)); if ( !argtypes.zip(v.paramtypes).forall( x:Pair[Type,Type] => x._1.isSubtype(x._2)) ) { - Report.error(tree.pos, "incompatible argument types for class method: \nrequired:" + v.paramtypes.foldLeft(" ")((a,b)=>a + b) + - "\nfound:" + argtypes.foldLeft(" ")((a,b)=>a + b) ); + Report.error(tree.pos, "incompatible argument types for class method: \n required: " + v.paramtypes.foldLeft("")((a,b)=>a + " " + b) + + "\n found: " + argtypes.foldLeft("")((a,b)=>a + " " + b) ); IBadType; } name.sym = v; @@ -232,8 +232,8 @@ val argtypes = args.map(x => analyzeExpr(varScope, x)); val fieldtypes = v.allFields.map(y => y.fieldtype); if ( !argtypes.zip(fieldtypes).forall( x:Pair[Type, Type] => x._1.isSubtype(x._2)) ) { - Report.error(tree.pos, "incompatible argument types for class constructor: \nrequired:" + fieldtypes.foldLeft(" ")((a,b) => a + b) + - "\nfound:" + argtypes.foldLeft(" ")((a,b) => a + b)); + Report.error(tree.pos, "incompatible argument types for class constructor: \n required: " + fieldtypes.foldLeft("")((a,b) => a + " " + b) + + "\n found: " + argtypes.foldLeft("")((a,b) => a + " " + b)); IBadType; } @@ -260,11 +260,9 @@ if ( op == EQ || op == NE ) { t1.lub(t2) match { case None => - Report.error(tree.pos, "incompatible types: '" + t1 + "' <=> '" + t2 + "'"); + Report.error(tree.pos, "incompatible types: " + t1 + " <=> " + t2); case _ => () } - //if ( !(t1.isSubtype(t2) || t2.isSubtype(t1)) ) - // Report.error(tree.pos, "incompatible types: '" + t1 + "' <=> '" + t2 + "'"); } else { checkIntType(left.pos, t1); checkIntType(right.pos, t2); @@ -284,7 +282,7 @@ ta.lub(tb) match { case Some(v) => v case None => - Report.error(tree.pos, "'if/else' block common has incompatible return types: '" + ta + "' <=> '" + tb + "'"); + Report.error(tree.pos, "if...else block has incompatible return types: " + ta + " <=> " + tb); IBadType } @@ -318,7 +316,7 @@ * Generates an error message for unexpected types. */ private def error(pos: Int, header: String, found: Type, expected: Type) = - Report.error(pos, header + "\nexpected type: " + expected + "\n" + - "actual type : " + found); + Report.error(pos, header + "\n expected type: " + expected + "\n" + + " actual type: " + found); } diff --git a/sources/zweic/Type.scala b/sources/zweic/Type.scala index 29f45c2..4767b35 100755 --- a/sources/zweic/Type.scala +++ b/sources/zweic/Type.scala @@ -18,11 +18,13 @@ case IClassType(c) => "ClassType(" + c.toString()+")"; case IIntType => "IntType" case INullType => "NullType" - case IBadType => "" + //case IBadType => "" + case IBadType => "" } def isSubtype(that: Type): Boolean = Pair(this, that) match { - case Pair(INullType, x) => true + case Pair(INullType, IClassType(c)) => true + case Pair(INullType, INullType) => true case Pair(x, INullType) => false case Pair(IIntType, IIntType) => true case Pair(IClassType(c1), IClassType(c2)) => c1.superclasses.contains(c2) @@ -39,8 +41,6 @@ def lub(that: Type): Option[Type] = Pair(this, that) match { case Pair(IIntType, IIntType) => Some(IIntType) case Pair(INullType, INullType) => Some(INullType) - case Pair(IIntType, INullType) => Some(IIntType) - case Pair(INullType, IIntType) => Some(IIntType) case Pair(c@IClassType(x), INullType) => Some(c) case Pair(INullType, c@IClassType(x)) => Some(c) case Pair(IClassType(c1), IClassType(c2)) => diff --git a/tests/4/method00-3.zwei b/tests/4/method00-3.zwei index a62d908..34cbc66 100755 --- a/tests/4/method00-3.zwei +++ b/tests/4/method00-3.zwei @@ -11,8 +11,8 @@ bar overrideTest(bar a, bar b) { return new bar() } // success of clause 3 - foo overrideTest(bar a, bar b) { // 3/5 failure of clauses 3 and 4 (return type not subtype of bar) - return new bar() + baz overrideTest(bar a, bar b) { // 3/5 failure of clauses 3 and 4 (return type not subtype of baz) + return new baz() } } diff --git a/tests/4/method00-7.zwei b/tests/4/method00-7.zwei index f912336..1cd1c86 100755 --- a/tests/4/method00-7.zwei +++ b/tests/4/method00-7.zwei @@ -11,7 +11,7 @@ bar overrideTest(bar a, bar b) { return new bar() } // success of clause 3 - baz overrideTest(foo a, foo b) { // successful override + foo overrideTest(foo a, foo b) { // successful override return new baz() // success (polymorphism) }