/** * Copyright (c) 2009-2011, The HATS Consortium. All rights reserved. * This file is licensed under the terms of the Modified BSD License. */ package abs.frontend.analyser; import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; import java.io.PrintWriter; import java.io.StringReader; import java.io.StringWriter; import org.junit.Test; import abs.frontend.FrontendTest; import abs.frontend.antlr.parser.ABSParserWrapper; import abs.frontend.ast.ASTNode; import abs.frontend.ast.AwaitAsyncCall; import abs.frontend.ast.ClassDecl; import abs.frontend.ast.CompilationUnit; import abs.frontend.ast.DeltaDecl; import abs.frontend.ast.Model; import abs.frontend.ast.ReturnStmt; import abs.frontend.ast.Stmt; import abs.frontend.ast.VarDeclStmt; import abs.frontend.tests.ABSFormatter; import abs.frontend.tests.EmptyFormatter; import abs.frontend.typechecker.DataTypeType; import abs.frontend.typechecker.Type; public class OtherAnalysisTests extends FrontendTest { @Test public void countCOG() { Model m = assertParseOk("interface I { } class C { { I i = new C(); } Unit m() { I i = new C(); } } { I i; i = new C(); i = new local C(); while (true) { i = new C(); }}"); assertEquals(4, m.getNumberOfNewCogExpr()); } @Test public void finalTest() { assertParse("interface I { } { [Final] I i; i = null; }", Config.TYPE_CHECK, Config.WITH_STD_LIB, Config.EXPECT_TYPE_ERROR); } @Test public void fullcopyTest() { Model m = assertParseOk("module M; class C {}", Config.WITH_STD_LIB); Model m2 = m.treeCopyNoTransform(); assertFalse(m.hasErrors()); assertFalse(m2.hasErrors()); } @Test public void fullcopyTest1() { Model m = assertParseOk("module M; class C {}", Config.WITH_STD_LIB); Model m2 = m.treeCopyNoTransform(); assertFalse(m.hasErrors()); assertFalse(m2.hasErrors()); assertTrue(!m.typeCheck().containsErrors()); assertTrue(!m2.typeCheck().containsErrors()); } @Test public void fullcopyTest2() { Model m = assertParseOk("module M; class C {}", Config.WITH_STD_LIB); assertFalse(m.hasErrors()); assertTrue(m.typeCheck().toString(),!m.typeCheck().containsErrors()); Model m2 = m.treeCopyNoTransform(); assertFalse(m2.hasErrors()); assertTrue(m2.typeCheck().toString(),!m2.typeCheck().containsErrors()); } @Test public void parsetreecopyTest() { Model m = assertParseOk("module M; class C {}", Config.WITH_STD_LIB); Model m2 = m.parseTreeCopy(); assertEquals(prettyPrint(m), prettyPrint(m2)); assertFalse(m.hasErrors()); assertFalse(m2.hasErrors()); } @Test public void parsetreecopyTest2() { Model m = assertParseOk("module M; productline TestPL;" + "features A, B, C; ", Config.WITH_STD_LIB); Model m2 = m.parseTreeCopy(); assertEquals(prettyPrint(m), prettyPrint(m2)); assertFalse(m.hasErrors()); assertFalse(m2.hasErrors()); } public static String prettyPrint(Model m2) { StringWriter writer = new StringWriter(); PrintWriter w = new PrintWriter(writer); ABSFormatter f = new EmptyFormatter(); m2.doPrettyPrint(w,f); return writer.toString(); } //@Test public void awaitTest2() { Model.doAACrewrite = true; Model m = assertParseOk("data Unit; interface I { Unit m(Unit x); } class C implements I {{Unit x = await this!m(Unit());}}"); assertFalse(m.hasErrors()); final String p1 = prettyPrint(m); Model.doAACrewrite = false; // Model m2 = assertParseOk("data Unit; interface I { Unit m(); } class C implements I {{Unit x = await this!m();}}"); Model m2 = assertParseOk("data Unit; interface I { Unit m(Unit x); } class C implements I {{Unit x = await this!m(Unit());}}"); assertFalse(m2.hasErrors()); assertEquals(p1, prettyPrint(m2)); } //@Test public void awaitTest3() { Model.doAACrewrite = true; Model m = assertParseOk("data Unit; interface I { Unit m(Unit x); } class C implements I {{Unit x = await this!n(Unit());}}"); assertFalse(m.hasErrors()); final String p1 = prettyPrint(m); Model.doAACrewrite = false; Model m2 = assertParseOk("data Unit; interface I { Unit m(Unit x); } class C implements I {{Unit x = await this!n(Unit());}}"); assertFalse(m2.hasErrors()); assertEquals(p1, prettyPrint(m2)); } @Test public void testContext1() { Model m = assertParseOk("data Unit; interface I { Unit m(); } class C implements I {{Unit x = await this!m();}}"); ClassDecl cd = (ClassDecl) m.lookupModule("UnitTest").getDecl(2); AwaitAsyncCall n = (AwaitAsyncCall) down(cd); assertNull("Rewrite failed!", n); } @Test public void testContext2() { Model m = assertParseOk("data Unit; interface I { Unit m(); } class C implements I {{Unit x = await this!m();}}"); ClassDecl cd = (ClassDecl) m.lookupModule("UnitTest").getDecl(2); AwaitAsyncCall n = (AwaitAsyncCall) down(cd); assertNull("Rewriting failed!",n); } private static ASTNode<?> down(ASTNode<?> n) { ASTNode<?> x = null; for(int i =0; i<n.getNumChild(); i++) { x = n.getChild(i); if (x == null) continue; if (x instanceof AwaitAsyncCall) return x; else { x = down(x); if (x != null) return x; } } return null; } @Test public void awaitRewriteModule1() { Model.doAACrewrite = false; Model m = assertParseOk("module A; export *; data X; module B; export *; data X; module C; import * from A; import B.X; class C { X m() { return await this!m();}}"); ClassDecl c = (ClassDecl) m.lookupModule("C").getDecl(0); ReturnStmt ret = (ReturnStmt) c.getMethod(0).getBlock().getStmt(0); assertThat(ret.getRetExp().getType(), instanceOf(DataTypeType.class)); assertEquals("A.X",ret.getRetExp().getType().getQualifiedName()); Model.doAACrewrite = true; m = assertParseOk("module A; export *; data X; module B; export *; data X; module C; import * from A; import B.X; class C { X m() { return await this!m();}}", Config.WITH_STD_LIB); c = (ClassDecl) m.lookupModule("C").getDecl(0); Stmt s = c.getMethod(0).getBlock().getStmt(0); VarDeclStmt b = (VarDeclStmt) s; Type t = ((DataTypeType) b.getVarDecl().getType()).getTypeArg(0); assertEquals("A.X",t.getQualifiedName()); } @Test public void awaitRewriteTwice() { assertTypeOK("module Test; interface I { I m(); } class C implements I { I m() { I x = await this!m(); await x!m(); return this; }}"); } @Test public void awaitRewriteDecl1() { Model m = assertParseOk("module A; class C { } delta D; modifies class C { adds Unit m() { return await this!m();}}", Config.WITH_STD_LIB); DeltaDecl c = m.getDeltaDecls().iterator().next(); AwaitAsyncCall a = (AwaitAsyncCall) down(c); assertNotNull(a); // pity, would like this to work. } @Test public void awaitRewriteDecl2() throws Exception { String deltaDecl = "delta D; modifies class C { adds Unit m() { return await this!m();}}"; CompilationUnit u = new ABSParserWrapper(null, true, false) .parse(new StringReader(deltaDecl)); DeltaDecl d = u.getDeltaDecl(0); AwaitAsyncCall a = (AwaitAsyncCall) down(d); assertNotNull(a); // pity, would like this to work. } }