diff options
author | Felix Mulder <felix.mulder@gmail.com> | 2016-11-02 11:08:28 +0100 |
---|---|---|
committer | Guillaume Martres <smarter@ubuntu.com> | 2016-11-22 01:35:07 +0100 |
commit | 8a61ff432543a29234193cd1f7c14abd3f3d31a0 (patch) | |
tree | a8147561d307af862c295cfc8100d271063bb0dd /compiler/test/dotty/tools/dotc/transform | |
parent | 6a455fe6da5ff9c741d91279a2dc6fe2fb1b472f (diff) | |
download | dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.tar.gz dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.tar.bz2 dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.zip |
Move compiler and compiler tests to compiler dir
Diffstat (limited to 'compiler/test/dotty/tools/dotc/transform')
4 files changed, 819 insertions, 0 deletions
diff --git a/compiler/test/dotty/tools/dotc/transform/CreateCompanionObjectsTest.scala b/compiler/test/dotty/tools/dotc/transform/CreateCompanionObjectsTest.scala new file mode 100644 index 000000000..18acb2105 --- /dev/null +++ b/compiler/test/dotty/tools/dotc/transform/CreateCompanionObjectsTest.scala @@ -0,0 +1,128 @@ +package dotty.tools +package dotc +package transform + +import org.junit.{Assert, Test} +import core._ +import ast.{tpd, Trees} +import Contexts._ +import Flags._ +import Denotations._ +import NameOps._ +import Symbols._ +import Types._ +import Decorators._ +import Trees._ +import TreeTransforms.{TreeTransform, TreeTransformer} + + +class CreateCompanionObjectsTest extends DottyTest { + /* FIXME: re-enable after adapting to new scheme + + import tpd._ + + type PostTyperTransformer = TreeTransformer // FIXME do without + + @Test + def shouldCreateNonExistingObjectsInPackage = checkCompile("frontend", "class A{} ") { + (tree, context) => + implicit val ctx = context + + val transformer = new PostTyperTransformer { + override def transformations = Array(new CreateCompanionObjects { + + override def name: String = "create all companion objects" + override def predicate(cts: TypeDef)(implicit ctx:Context): Boolean = true + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + }) + + override def name: String = "test" + } + val transformed = transformer.transform(tree).toString + val classPattern = "TypeDef(Modifiers(,,List()),A," + val classPos = transformed.indexOf(classPattern) + val moduleClassPattern = "TypeDef(Modifiers(final module <synthetic>,,List()),A$" + val modulePos = transformed.indexOf(moduleClassPattern) + + Assert.assertTrue("should create non-existing objects in package", + classPos < modulePos + ) + } + + @Test + def shouldCreateNonExistingObjectsInBlock = checkCompile("frontend", "class D {def p = {class A{}; 1}} ") { + (tree, context) => + implicit val ctx = context + val transformer = new PostTyperTransformer { + override def transformations = Array(new CreateCompanionObjects { + + override def name: String = "create all companion modules" + override def predicate(cts: TypeDef)(implicit ctx:Context): Boolean = true + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + }) + + override def name: String = "test" + } + val transformed = transformer.transform(tree).toString + val classPattern = "TypeDef(Modifiers(,,List()),A," + val classPos = transformed.indexOf(classPattern) + val moduleClassPattern = "TypeDef(Modifiers(final module <synthetic>,,List()),A$" + val modulePos = transformed.indexOf(moduleClassPattern) + + Assert.assertTrue("should create non-existing objects in block", + classPos < modulePos + ) + } + + @Test + def shouldCreateNonExistingObjectsInTemplate = checkCompile("frontend", "class D {class A{}; } ") { + (tree, context) => + implicit val ctx = context + val transformer = new PostTyperTransformer { + override def transformations = Array(new CreateCompanionObjects { + override def name: String = "create all companion modules" + override def predicate(cts: TypeDef)(implicit ctx:Context): Boolean = true + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + }) + + override def name: String = "test" + } + val transformed = transformer.transform(tree).toString + val classPattern = "TypeDef(Modifiers(,,List()),A," + val classPos = transformed.indexOf(classPattern) + val moduleClassPattern = "TypeDef(Modifiers(final module <synthetic>,,List()),A$" + val modulePos = transformed.indexOf(moduleClassPattern) + + Assert.assertTrue("should create non-existing objects in template", + classPos < modulePos + ) + } + + @Test + def shouldCreateOnlyIfAskedFor = checkCompile("frontend", "class DONT {class CREATE{}; } ") { + (tree, context) => + implicit val ctx = context + val transformer = new PostTyperTransformer { + override def transformations = Array(new CreateCompanionObjects { + override def name: String = "create all companion modules" + override def predicate(cts: TypeDef)(implicit ctx:Context): Boolean = cts.name.toString.contains("CREATE") + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + }) + + override def name: String = "test" + } + val transformed = transformer.transform(tree).toString + val classPattern = "TypeDef(Modifiers(,,List()),A," + val classPos = transformed.indexOf(classPattern) + val moduleClassPattern = "TypeDef(Modifiers(final module <synthetic>,,List()),CREATE$" + val modulePos = transformed.indexOf(moduleClassPattern) + + val notCreatedModulePattern = "TypeDef(Modifiers(final module <synthetic>,,List()),DONT" + val notCreatedPos = transformed.indexOf(notCreatedModulePattern) + + Assert.assertTrue("should create non-existing objects in template", + classPos < modulePos && (notCreatedPos < 0) + ) + } + */ +} diff --git a/compiler/test/dotty/tools/dotc/transform/LazyValsTest.scala b/compiler/test/dotty/tools/dotc/transform/LazyValsTest.scala new file mode 100644 index 000000000..96298c571 --- /dev/null +++ b/compiler/test/dotty/tools/dotc/transform/LazyValsTest.scala @@ -0,0 +1,361 @@ +package dotty.tools +package dotc +package transform + +import org.junit.Test +import org.junit.Assert + +class LazyValsTest extends DottyTest { + /* FIXME: re-enable after adapting to new scheme + @Test + def doNotRewriteObjects = { + checkCompile("LazyVals", "object O"){ (tree, ctx) => + Assert.assertTrue("local lazy shouldn't rewrite module instance definitions", tree.toString.contains( + "ValDef(Modifiers(final module <stable>,,List()),O," + )) + } + } + + @Test + def localInt = { + checkCompile("LazyVals", "class LocalLV { def m = { lazy val s = 1; s }}"){ (tree, ctx) => + Assert.assertTrue("local lazy int rewritten to class creation", tree.toString.contains( + "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class runtime),LazyInt)],Apply(Select(New(TypeTree[TypeRef(ThisType(module class runtime),LazyInt)]),<init>),List(Literal(Constant(1)))))" + )) + } + } + + @Test + def localLong = { + checkCompile("LazyVals", "class LocalLV { def m = { lazy val s = 1L; s }}"){ (tree, ctx) => + Assert.assertTrue("local lazy long rewritten to class creation", tree.toString.contains( + "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class runtime),LazyLong)],Apply(Select(New(TypeTree[TypeRef(ThisType(module class runtime),LazyLong)]),<init>),List(Literal(Constant(1)))))" + )) + } + } + + @Test + def localFloat = { + checkCompile("LazyVals", "class LocalLV { def m = { lazy val s = 1.0f; s }}"){ (tree, ctx) => + Assert.assertTrue("local lazy float rewritten to class creation", tree.toString.contains( + "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class runtime),LazyFloat)],Apply(Select(New(TypeTree[TypeRef(ThisType(module class runtime),LazyFloat)]),<init>),List(Literal(Constant(1.0)))))" + )) + } + } + + @Test + def localDouble = { + checkCompile("LazyVals", "class LocalLV { def m = { lazy val s = 1.0; s }}"){ (tree, ctx) => + Assert.assertTrue("local lazy double rewritten to class creation", tree.toString.contains( + "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class runtime),LazyDouble)],Apply(Select(New(TypeTree[TypeRef(ThisType(module class runtime),LazyDouble)]),<init>),List(Literal(Constant(1.0)))))" + )) + } + } + + @Test + def localBoolean = { + checkCompile("LazyVals", "class LocalLV { def m = { lazy val s = true; s }}"){ (tree, ctx) => + Assert.assertTrue("local lazy boolean rewritten to class creation", tree.toString.contains( + "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class runtime),LazyBoolean)],Apply(Select(New(TypeTree[TypeRef(ThisType(module class runtime),LazyBoolean)]),<init>),List(Literal(Constant(true)))))" + )) + } + } + + @Test + def localChar = { + checkCompile("LazyVals", "class LocalLV { def m = { lazy val s = 'a'; s }}"){ (tree, ctx) => + Assert.assertTrue("local lazy char rewritten to class creation", tree.toString.contains( + "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class runtime),LazyChar)],Apply(Select(New(TypeTree[TypeRef(ThisType(module class runtime),LazyChar)]),<init>),List(Literal(Constant(a)))))" + )) + } + } + + @Test + def localByte = { + checkCompile("LazyVals", "class LocalLV { def m = { lazy val s:Byte = 1; s }}"){ (tree, ctx) => + Assert.assertTrue("local lazy byte rewritten to class creation", tree.toString.contains( + "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class runtime),LazyByte)],Apply(Select(New(TypeTree[TypeRef(ThisType(module class runtime),LazyByte)]),<init>),List(Literal(Constant(1)))))" + )) + } + } + + @Test + def localShort = { + checkCompile("LazyVals", "class LocalLV { def m = { lazy val s:Short = 1; s }}"){ (tree, ctx) => + Assert.assertTrue("local lazy short rewritten to class creation", tree.toString.contains( + "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class runtime),LazyShort)],Apply(Select(New(TypeTree[TypeRef(ThisType(module class runtime),LazyShort)]),<init>),List(Literal(Constant(1)))))" + )) + } + } + + @Test + def localRef = { + checkCompile("LazyVals", "class LocalLV { def m = { lazy val s = \"string\"; s }}"){ (tree, ctx) => + Assert.assertTrue("local lazy ref rewritten to class creation", tree.toString.contains( + "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class runtime),LazyRef)],Apply(Select(New(TypeTree[TypeRef(ThisType(module class runtime),LazyRef)]),<init>),List(Literal(Constant(string)))))" + )) + } + } + + @Test + def fieldRef = { + checkCompile("LazyVals", "class LV { lazy val s = \"string\" }"){ (tree, ctx) => + Assert.assertTrue("field lazy int rewritten to class creation", tree.toString.contains( + "DefDef(Modifiers(,,List()),s,List(),List(),TypeTree[TypeRef(ThisType(module class lang),String)],If(Ident(sbitmap$1),Ident(s$lzy1),Block(List(Assign(Ident(sbitmap$1),Literal(Constant(true))), Assign(Ident(s$lzy1),Literal(Constant(string)))),Ident(s$lzy1))))" + )) + } + } + + @Test + def fieldInt = { + checkCompile("LazyVals", "class LV { lazy val s = 1 }"){ (tree, ctx) => + Assert.assertTrue("field lazy int rewritten", tree.toString.contains( + "DefDef(Modifiers(,,List()),s,List(),List(),TypeTree[TypeRef(ThisType(module class scala),Int)],If(Ident(sbitmap$1),Ident(s$lzy1),Block(List(Assign(Ident(sbitmap$1),Literal(Constant(true))), Assign(Ident(s$lzy1),Literal(Constant(1)))),Ident(s$lzy1))))" + )) + } + } + + @Test + def fieldLong = { + checkCompile("LazyVals", "class LV { lazy val s = 1L }"){ (tree, ctx) => + Assert.assertTrue("field lazy long rewritten", tree.toString.contains( + "DefDef(Modifiers(,,List()),s,List(),List(),TypeTree[TypeRef(ThisType(module class scala),Long)],If(Ident(sbitmap$1),Ident(s$lzy1),Block(List(Assign(Ident(sbitmap$1),Literal(Constant(true))), Assign(Ident(s$lzy1),Literal(Constant(1)))),Ident(s$lzy1))))" + )) + } + } + + @Test + def fieldShort = { + checkCompile("LazyVals", "class LV { lazy val s:Short = 1 }"){ (tree, ctx) => + Assert.assertTrue("field lazy short rewritten", tree.toString.contains( + "DefDef(Modifiers(,,List()),s,List(),List(),TypeTree[TypeRef(TermRef(ThisType(module class <root>),scala),Short)],If(Ident(sbitmap$1),Ident(s$lzy1),Block(List(Assign(Ident(sbitmap$1),Literal(Constant(true))), Assign(Ident(s$lzy1),Literal(Constant(1)))),Ident(s$lzy1))))" + )) + } + } + + @Test + def fieldByte = { + checkCompile("LazyVals", "class LV { lazy val s:Byte = 1 }"){ (tree, ctx) => + Assert.assertTrue("field lazy byte rewritten", tree.toString.contains( + "DefDef(Modifiers(,,List()),s,List(),List(),TypeTree[TypeRef(TermRef(ThisType(module class <root>),scala),Byte)],If(Ident(sbitmap$1),Ident(s$lzy1),Block(List(Assign(Ident(sbitmap$1),Literal(Constant(true))), Assign(Ident(s$lzy1),Literal(Constant(1)))),Ident(s$lzy1))))" + )) + } + } + + @Test + def fieldBoolean = { + checkCompile("LazyVals", "class LV { lazy val s = true }"){ (tree, ctx) => + Assert.assertTrue("field lazy boolean rewritten", tree.toString.contains( + "DefDef(Modifiers(,,List()),s,List(),List(),TypeTree[TypeRef(ThisType(module class scala),Boolean)],If(Ident(sbitmap$1),Ident(s$lzy1),Block(List(Assign(Ident(sbitmap$1),Literal(Constant(true))), Assign(Ident(s$lzy1),Literal(Constant(true)))),Ident(s$lzy1))))" + )) + } + } + + @Test + def fieldDouble = { + checkCompile("LazyVals", "class LV { lazy val s = 1.0 }"){ (tree, ctx) => + Assert.assertTrue("field lazy double rewritten", tree.toString.contains( + "DefDef(Modifiers(,,List()),s,List(),List(),TypeTree[TypeRef(ThisType(module class scala),Double)],If(Ident(sbitmap$1),Ident(s$lzy1),Block(List(Assign(Ident(sbitmap$1),Literal(Constant(true))), Assign(Ident(s$lzy1),Literal(Constant(1.0)))),Ident(s$lzy1))))" + )) + } + } + + @Test + def fieldFloat = { + checkCompile("LazyVals", "class LV { lazy val s = 1.0f }"){ (tree, ctx) => + Assert.assertTrue("field lazy float rewritten", tree.toString.contains( + "DefDef(Modifiers(,,List()),s,List(),List(),TypeTree[TypeRef(ThisType(module class scala),Float)],If(Ident(sbitmap$1),Ident(s$lzy1),Block(List(Assign(Ident(sbitmap$1),Literal(Constant(true))), Assign(Ident(s$lzy1),Literal(Constant(1.0)))),Ident(s$lzy1))))" + )) + } + } + + @Test + def fieldChar = { + checkCompile("LazyVals", "class LV { lazy val s = 'a' }"){ (tree, ctx) => + Assert.assertTrue("field lazy char rewritten", tree.toString.contains( + "DefDef(Modifiers(,,List()),s,List(),List(),TypeTree[TypeRef(ThisType(module class scala),Char)],If(Ident(sbitmap$1),Ident(s$lzy1),Block(List(Assign(Ident(sbitmap$1),Literal(Constant(true))), Assign(Ident(s$lzy1),Literal(Constant(a)))),Ident(s$lzy1))))" + )) + } + } + + @Test + def volatileFieldRef = { + checkCompile("LazyVals", "class LV { @volatile lazy val s = \"a\" }") { + (tree, ctx) => + val accessor = "DefDef(Modifiers(,,List(Apply(Select(New(Ident(volatile)),<init>),List()))),s,List(),List(),TypeTree[TypeRef(ThisType(module class lang),String)],Block(List(ValDef(Modifiers(,,List()),result,TypeTree[TypeRef(ThisType(module class lang),String)],Literal(Constant(null))), ValDef(Modifiers(,,List()),retry,TypeTree[TypeRef(ThisType(module class scala),Boolean)],Literal(Constant(true))), ValDef(Modifiers(,,List()),flag,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0))), WhileDo(Ident(retry),Block(List(Assign(Ident(flag),Apply(Select(Ident(LazyVals),get),List(This(LV), Select(Ident(LV),OFFSET$0))))),Match(Apply(Select(Ident(LazyVals),STATE),List(Ident(flag), Literal(Constant(0)))),List(CaseDef(Literal(Constant(0)),EmptyTree,If(Apply(Select(Ident(LazyVals),CAS),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(1)), Literal(Constant(0)))),Block(List(Try(Assign(Ident(result),Literal(Constant(a))),Block(List(DefDef(Modifiers(,,List()),$anonfun,List(),List(List(ValDef(Modifiers(,,List()),x$1,TypeTree[TypeRef(ThisType(module class lang),Throwable)],EmptyTree))),TypeTree[TypeRef(ThisType(module class scala),Int)],Block(List(Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(0)), Literal(Constant(0))))),Throw(Ident(x$1))))),Closure(List(),Ident($anonfun),EmptyTree)),EmptyTree), Assign(Ident(s$lzy1),Ident(result)), Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(3)), Literal(Constant(0)))), Assign(Ident(retry),Literal(Constant(false)))),Literal(Constant(()))),Literal(Constant(())))), CaseDef(Literal(Constant(1)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(2)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(3)),EmptyTree,Block(List(Assign(Ident(retry),Literal(Constant(false))), Assign(Ident(result),Ident(s$lzy1))),Literal(Constant(()))))))))),Ident(result)))" + val fields = "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class lang),String)],Literal(Constant(null))), ValDef(Modifiers(,,List()),bitmap$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0)))" + val moduleField = "TypeDef(Modifiers(final module <synthetic>,,List()),LV$,Template(DefDef(Modifiers(,,List()),<init>,List(),List(List()),TypeTree[TypeRef(ThisType(module class <empty>),LV$)],EmptyTree),List(Apply(Select(New(TypeTree[TypeRef(ThisType(module class lang),Object)]),<init>),List())),ValDef(Modifiers(,,List()),_,TypeTree[TermRef(ThisType(module class <empty>),LV)],EmptyTree),List(ValDef(Modifiers(,,List()),OFFSET$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Apply(Select(Ident(LazyVals),getOffset),List(This(LV), Literal(Constant(bitmap$0))))))))" + val treeS = tree.toString + //println(treeS) + Assert.assertTrue("volatile field lazy ref rewritten to class creation\n" + treeS, + treeS.contains(accessor) && treeS.contains(fields) && treeS.contains(moduleField)) + } + } + + @Test + def volatileFieldInt = { + checkCompile("LazyVals", "class LV { @volatile lazy val s = 1 }") { + (tree, ctx) => + val accessor = "DefDef(Modifiers(,,List(Apply(Select(New(Ident(volatile)),<init>),List()))),s,List(),List(),TypeTree[TypeRef(ThisType(module class scala),Int)],Block(List(ValDef(Modifiers(,,List()),result,TypeTree[TypeRef(ThisType(module class scala),Int)],Literal(Constant(0))), ValDef(Modifiers(,,List()),retry,TypeTree[TypeRef(ThisType(module class scala),Boolean)],Literal(Constant(true))), ValDef(Modifiers(,,List()),flag,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0))), WhileDo(Ident(retry),Block(List(Assign(Ident(flag),Apply(Select(Ident(LazyVals),get),List(This(LV), Select(Ident(LV),OFFSET$0))))),Match(Apply(Select(Ident(LazyVals),STATE),List(Ident(flag), Literal(Constant(0)))),List(CaseDef(Literal(Constant(0)),EmptyTree,If(Apply(Select(Ident(LazyVals),CAS),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(1)), Literal(Constant(0)))),Block(List(Try(Assign(Ident(result),Literal(Constant(1))),Block(List(DefDef(Modifiers(,,List()),$anonfun,List(),List(List(ValDef(Modifiers(,,List()),x$1,TypeTree[TypeRef(ThisType(module class lang),Throwable)],EmptyTree))),TypeTree[TypeRef(ThisType(module class scala),Int)],Block(List(Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(0)), Literal(Constant(0))))),Throw(Ident(x$1))))),Closure(List(),Ident($anonfun),EmptyTree)),EmptyTree), Assign(Ident(s$lzy1),Ident(result)), Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(3)), Literal(Constant(0)))), Assign(Ident(retry),Literal(Constant(false)))),Literal(Constant(()))),Literal(Constant(())))), CaseDef(Literal(Constant(1)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(2)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(3)),EmptyTree,Block(List(Assign(Ident(retry),Literal(Constant(false))), Assign(Ident(result),Ident(s$lzy1))),Literal(Constant(()))))))))),Ident(result)))" + val fields = "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class scala),Int)],Literal(Constant(0))), ValDef(Modifiers(,,List()),bitmap$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0)))" + val moduleField = "TypeDef(Modifiers(final module <synthetic>,,List()),LV$,Template(DefDef(Modifiers(,,List()),<init>,List(),List(List()),TypeTree[TypeRef(ThisType(module class <empty>),LV$)],EmptyTree),List(Apply(Select(New(TypeTree[TypeRef(ThisType(module class lang),Object)]),<init>),List())),ValDef(Modifiers(,,List()),_,TypeTree[TermRef(ThisType(module class <empty>),LV)],EmptyTree),List(ValDef(Modifiers(,,List()),OFFSET$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Apply(Select(Ident(LazyVals),getOffset),List(This(LV), Literal(Constant(bitmap$0))))))))" + val treeS = tree.toString + Assert.assertTrue("volatile field lazy ref rewritten to class creation\n" + treeS, + treeS.contains(accessor) && treeS.contains(fields) && treeS.contains(moduleField)) + } + } + + @Test + def volatileFieldLong = { + checkCompile("LazyVals", "class LV { @volatile lazy val s = 1L }") { + (tree, ctx) => + val accessor = "DefDef(Modifiers(,,List(Apply(Select(New(Ident(volatile)),<init>),List()))),s,List(),List(),TypeTree[TypeRef(ThisType(module class scala),Long)],Block(List(ValDef(Modifiers(,,List()),result,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0))), ValDef(Modifiers(,,List()),retry,TypeTree[TypeRef(ThisType(module class scala),Boolean)],Literal(Constant(true))), ValDef(Modifiers(,,List()),flag,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0))), WhileDo(Ident(retry),Block(List(Assign(Ident(flag),Apply(Select(Ident(LazyVals),get),List(This(LV), Select(Ident(LV),OFFSET$0))))),Match(Apply(Select(Ident(LazyVals),STATE),List(Ident(flag), Literal(Constant(0)))),List(CaseDef(Literal(Constant(0)),EmptyTree,If(Apply(Select(Ident(LazyVals),CAS),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(1)), Literal(Constant(0)))),Block(List(Try(Assign(Ident(result),Literal(Constant(1))),Block(List(DefDef(Modifiers(,,List()),$anonfun,List(),List(List(ValDef(Modifiers(,,List()),x$1,TypeTree[TypeRef(ThisType(module class lang),Throwable)],EmptyTree))),TypeTree[TypeRef(ThisType(module class scala),Int)],Block(List(Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(0)), Literal(Constant(0))))),Throw(Ident(x$1))))),Closure(List(),Ident($anonfun),EmptyTree)),EmptyTree), Assign(Ident(s$lzy1),Ident(result)), Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(3)), Literal(Constant(0)))), Assign(Ident(retry),Literal(Constant(false)))),Literal(Constant(()))),Literal(Constant(())))), CaseDef(Literal(Constant(1)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(2)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(3)),EmptyTree,Block(List(Assign(Ident(retry),Literal(Constant(false))), Assign(Ident(result),Ident(s$lzy1))),Literal(Constant(()))))))))),Ident(result)))" + val fields = "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0))), ValDef(Modifiers(,,List()),bitmap$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0)))" + val moduleField = "TypeDef(Modifiers(final module <synthetic>,,List()),LV$,Template(DefDef(Modifiers(,,List()),<init>,List(),List(List()),TypeTree[TypeRef(ThisType(module class <empty>),LV$)],EmptyTree),List(Apply(Select(New(TypeTree[TypeRef(ThisType(module class lang),Object)]),<init>),List())),ValDef(Modifiers(,,List()),_,TypeTree[TermRef(ThisType(module class <empty>),LV)],EmptyTree),List(ValDef(Modifiers(,,List()),OFFSET$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Apply(Select(Ident(LazyVals),getOffset),List(This(LV), Literal(Constant(bitmap$0))))))))" + val treeS = tree.toString + Assert.assertTrue("volatile field lazy ref rewritten to class creation\n" + treeS, + treeS.contains(accessor) && treeS.contains(fields) && treeS.contains(moduleField)) + } + } + + @Test + def volatileFieldFloat = { + checkCompile("LazyVals", "class LV { @volatile lazy val s = 1.0f }") { + (tree, ctx) => + val accessor = "DefDef(Modifiers(,,List(Apply(Select(New(Ident(volatile)),<init>),List()))),s,List(),List(),TypeTree[TypeRef(ThisType(module class scala),Float)],Block(List(ValDef(Modifiers(,,List()),result,TypeTree[TypeRef(ThisType(module class scala),Float)],Literal(Constant(0.0))), ValDef(Modifiers(,,List()),retry,TypeTree[TypeRef(ThisType(module class scala),Boolean)],Literal(Constant(true))), ValDef(Modifiers(,,List()),flag,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0))), WhileDo(Ident(retry),Block(List(Assign(Ident(flag),Apply(Select(Ident(LazyVals),get),List(This(LV), Select(Ident(LV),OFFSET$0))))),Match(Apply(Select(Ident(LazyVals),STATE),List(Ident(flag), Literal(Constant(0)))),List(CaseDef(Literal(Constant(0)),EmptyTree,If(Apply(Select(Ident(LazyVals),CAS),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(1)), Literal(Constant(0)))),Block(List(Try(Assign(Ident(result),Literal(Constant(1.0))),Block(List(DefDef(Modifiers(,,List()),$anonfun,List(),List(List(ValDef(Modifiers(,,List()),x$1,TypeTree[TypeRef(ThisType(module class lang),Throwable)],EmptyTree))),TypeTree[TypeRef(ThisType(module class scala),Int)],Block(List(Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(0)), Literal(Constant(0))))),Throw(Ident(x$1))))),Closure(List(),Ident($anonfun),EmptyTree)),EmptyTree), Assign(Ident(s$lzy1),Ident(result)), Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(3)), Literal(Constant(0)))), Assign(Ident(retry),Literal(Constant(false)))),Literal(Constant(()))),Literal(Constant(())))), CaseDef(Literal(Constant(1)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(2)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(3)),EmptyTree,Block(List(Assign(Ident(retry),Literal(Constant(false))), Assign(Ident(result),Ident(s$lzy1))),Literal(Constant(()))))))))),Ident(result)))" + val fields = "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class scala),Float)],Literal(Constant(0.0))), ValDef(Modifiers(,,List()),bitmap$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0)))" + val moduleField = "TypeDef(Modifiers(final module <synthetic>,,List()),LV$,Template(DefDef(Modifiers(,,List()),<init>,List(),List(List()),TypeTree[TypeRef(ThisType(module class <empty>),LV$)],EmptyTree),List(Apply(Select(New(TypeTree[TypeRef(ThisType(module class lang),Object)]),<init>),List())),ValDef(Modifiers(,,List()),_,TypeTree[TermRef(ThisType(module class <empty>),LV)],EmptyTree),List(ValDef(Modifiers(,,List()),OFFSET$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Apply(Select(Ident(LazyVals),getOffset),List(This(LV), Literal(Constant(bitmap$0))))))))" + val treeS = tree.toString + Assert.assertTrue("volatile field lazy ref rewritten to class creation\n" + treeS, + treeS.contains(accessor) && treeS.contains(fields) && treeS.contains(moduleField)) + } + } + + @Test + def volatileFieldDouble = { + checkCompile("LazyVals", "class LV { @volatile lazy val s = 1.0 }") { + (tree, ctx) => + val accessor = "DefDef(Modifiers(,,List(Apply(Select(New(Ident(volatile)),<init>),List()))),s,List(),List(),TypeTree[TypeRef(ThisType(module class scala),Double)],Block(List(ValDef(Modifiers(,,List()),result,TypeTree[TypeRef(ThisType(module class scala),Double)],Literal(Constant(0.0))), ValDef(Modifiers(,,List()),retry,TypeTree[TypeRef(ThisType(module class scala),Boolean)],Literal(Constant(true))), ValDef(Modifiers(,,List()),flag,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0))), WhileDo(Ident(retry),Block(List(Assign(Ident(flag),Apply(Select(Ident(LazyVals),get),List(This(LV), Select(Ident(LV),OFFSET$0))))),Match(Apply(Select(Ident(LazyVals),STATE),List(Ident(flag), Literal(Constant(0)))),List(CaseDef(Literal(Constant(0)),EmptyTree,If(Apply(Select(Ident(LazyVals),CAS),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(1)), Literal(Constant(0)))),Block(List(Try(Assign(Ident(result),Literal(Constant(1.0))),Block(List(DefDef(Modifiers(,,List()),$anonfun,List(),List(List(ValDef(Modifiers(,,List()),x$1,TypeTree[TypeRef(ThisType(module class lang),Throwable)],EmptyTree))),TypeTree[TypeRef(ThisType(module class scala),Int)],Block(List(Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(0)), Literal(Constant(0))))),Throw(Ident(x$1))))),Closure(List(),Ident($anonfun),EmptyTree)),EmptyTree), Assign(Ident(s$lzy1),Ident(result)), Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(3)), Literal(Constant(0)))), Assign(Ident(retry),Literal(Constant(false)))),Literal(Constant(()))),Literal(Constant(())))), CaseDef(Literal(Constant(1)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(2)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(3)),EmptyTree,Block(List(Assign(Ident(retry),Literal(Constant(false))), Assign(Ident(result),Ident(s$lzy1))),Literal(Constant(()))))))))),Ident(result)))" + val fields = "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class scala),Double)],Literal(Constant(0.0))), ValDef(Modifiers(,,List()),bitmap$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0)))" + val moduleField = "TypeDef(Modifiers(final module <synthetic>,,List()),LV$,Template(DefDef(Modifiers(,,List()),<init>,List(),List(List()),TypeTree[TypeRef(ThisType(module class <empty>),LV$)],EmptyTree),List(Apply(Select(New(TypeTree[TypeRef(ThisType(module class lang),Object)]),<init>),List())),ValDef(Modifiers(,,List()),_,TypeTree[TermRef(ThisType(module class <empty>),LV)],EmptyTree),List(ValDef(Modifiers(,,List()),OFFSET$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Apply(Select(Ident(LazyVals),getOffset),List(This(LV), Literal(Constant(bitmap$0))))))))" + val treeS = tree.toString + Assert.assertTrue("volatile field lazy ref rewritten to class creation\n" + treeS, + treeS.contains(accessor) && treeS.contains(fields) && treeS.contains(moduleField)) + } + } + + @Test + def volatileFieldBoolean = { + checkCompile("LazyVals", "class LV { @volatile lazy val s = true }") { + (tree, ctx) => + val accessor = "DefDef(Modifiers(,,List(Apply(Select(New(Ident(volatile)),<init>),List()))),s,List(),List(),TypeTree[TypeRef(ThisType(module class scala),Boolean)],Block(List(ValDef(Modifiers(,,List()),result,TypeTree[TypeRef(ThisType(module class scala),Boolean)],Literal(Constant(false))), ValDef(Modifiers(,,List()),retry,TypeTree[TypeRef(ThisType(module class scala),Boolean)],Literal(Constant(true))), ValDef(Modifiers(,,List()),flag,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0))), WhileDo(Ident(retry),Block(List(Assign(Ident(flag),Apply(Select(Ident(LazyVals),get),List(This(LV), Select(Ident(LV),OFFSET$0))))),Match(Apply(Select(Ident(LazyVals),STATE),List(Ident(flag), Literal(Constant(0)))),List(CaseDef(Literal(Constant(0)),EmptyTree,If(Apply(Select(Ident(LazyVals),CAS),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(1)), Literal(Constant(0)))),Block(List(Try(Assign(Ident(result),Literal(Constant(true))),Block(List(DefDef(Modifiers(,,List()),$anonfun,List(),List(List(ValDef(Modifiers(,,List()),x$1,TypeTree[TypeRef(ThisType(module class lang),Throwable)],EmptyTree))),TypeTree[TypeRef(ThisType(module class scala),Int)],Block(List(Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(0)), Literal(Constant(0))))),Throw(Ident(x$1))))),Closure(List(),Ident($anonfun),EmptyTree)),EmptyTree), Assign(Ident(s$lzy1),Ident(result)), Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(3)), Literal(Constant(0)))), Assign(Ident(retry),Literal(Constant(false)))),Literal(Constant(()))),Literal(Constant(())))), CaseDef(Literal(Constant(1)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(2)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(3)),EmptyTree,Block(List(Assign(Ident(retry),Literal(Constant(false))), Assign(Ident(result),Ident(s$lzy1))),Literal(Constant(()))))))))),Ident(result)))" + val fields = "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class scala),Boolean)],Literal(Constant(false))), ValDef(Modifiers(,,List()),bitmap$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0)))" + val moduleField = "TypeDef(Modifiers(final module <synthetic>,,List()),LV$,Template(DefDef(Modifiers(,,List()),<init>,List(),List(List()),TypeTree[TypeRef(ThisType(module class <empty>),LV$)],EmptyTree),List(Apply(Select(New(TypeTree[TypeRef(ThisType(module class lang),Object)]),<init>),List())),ValDef(Modifiers(,,List()),_,TypeTree[TermRef(ThisType(module class <empty>),LV)],EmptyTree),List(ValDef(Modifiers(,,List()),OFFSET$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Apply(Select(Ident(LazyVals),getOffset),List(This(LV), Literal(Constant(bitmap$0))))))))" + val treeS = tree.toString + Assert.assertTrue("volatile field lazy ref rewritten to class creation\n" + treeS, + treeS.contains(accessor) && treeS.contains(fields) && treeS.contains(moduleField)) + } + } + + @Test + def volatileFieldByte = { + checkCompile("LazyVals", "class LV { @volatile lazy val s:Byte = 1 }") { + (tree, ctx) => + val accessor = "DefDef(Modifiers(,,List(Apply(Select(New(Ident(volatile)),<init>),List()))),s,List(),List(),TypeTree[TypeRef(TermRef(ThisType(module class <root>),scala),Byte)],Block(List(ValDef(Modifiers(,,List()),result,TypeTree[TypeRef(TermRef(ThisType(module class <root>),scala),Byte)],Literal(Constant(0))), ValDef(Modifiers(,,List()),retry,TypeTree[TypeRef(ThisType(module class scala),Boolean)],Literal(Constant(true))), ValDef(Modifiers(,,List()),flag,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0))), WhileDo(Ident(retry),Block(List(Assign(Ident(flag),Apply(Select(Ident(LazyVals),get),List(This(LV), Select(Ident(LV),OFFSET$0))))),Match(Apply(Select(Ident(LazyVals),STATE),List(Ident(flag), Literal(Constant(0)))),List(CaseDef(Literal(Constant(0)),EmptyTree,If(Apply(Select(Ident(LazyVals),CAS),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(1)), Literal(Constant(0)))),Block(List(Try(Assign(Ident(result),Literal(Constant(1))),Block(List(DefDef(Modifiers(,,List()),$anonfun,List(),List(List(ValDef(Modifiers(,,List()),x$1,TypeTree[TypeRef(ThisType(module class lang),Throwable)],EmptyTree))),TypeTree[TypeRef(ThisType(module class scala),Int)],Block(List(Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(0)), Literal(Constant(0))))),Throw(Ident(x$1))))),Closure(List(),Ident($anonfun),EmptyTree)),EmptyTree), Assign(Ident(s$lzy1),Ident(result)), Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(3)), Literal(Constant(0)))), Assign(Ident(retry),Literal(Constant(false)))),Literal(Constant(()))),Literal(Constant(())))), CaseDef(Literal(Constant(1)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(2)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(3)),EmptyTree,Block(List(Assign(Ident(retry),Literal(Constant(false))), Assign(Ident(result),Ident(s$lzy1))),Literal(Constant(()))))))))),Ident(result)))" + val fields = "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(TermRef(ThisType(module class <root>),scala),Byte)],Literal(Constant(0))), ValDef(Modifiers(,,List()),bitmap$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0)))" + val moduleField = "TypeDef(Modifiers(final module <synthetic>,,List()),LV$,Template(DefDef(Modifiers(,,List()),<init>,List(),List(List()),TypeTree[TypeRef(ThisType(module class <empty>),LV$)],EmptyTree),List(Apply(Select(New(TypeTree[TypeRef(ThisType(module class lang),Object)]),<init>),List())),ValDef(Modifiers(,,List()),_,TypeTree[TermRef(ThisType(module class <empty>),LV)],EmptyTree),List(ValDef(Modifiers(,,List()),OFFSET$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Apply(Select(Ident(LazyVals),getOffset),List(This(LV), Literal(Constant(bitmap$0))))))))" + val treeS = tree.toString + Assert.assertTrue("volatile field lazy ref rewritten to class creation\n" + treeS, + treeS.contains(accessor) && treeS.contains(fields) && treeS.contains(moduleField)) + } + } + + @Test + def volatileFieldShort = { + checkCompile("LazyVals", "class LV { @volatile lazy val s:Short = 1 }") { + (tree, ctx) => + val accessor = "DefDef(Modifiers(,,List(Apply(Select(New(Ident(volatile)),<init>),List()))),s,List(),List(),TypeTree[TypeRef(TermRef(ThisType(module class <root>),scala),Short)],Block(List(ValDef(Modifiers(,,List()),result,TypeTree[TypeRef(TermRef(ThisType(module class <root>),scala),Short)],Literal(Constant(0))), ValDef(Modifiers(,,List()),retry,TypeTree[TypeRef(ThisType(module class scala),Boolean)],Literal(Constant(true))), ValDef(Modifiers(,,List()),flag,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0))), WhileDo(Ident(retry),Block(List(Assign(Ident(flag),Apply(Select(Ident(LazyVals),get),List(This(LV), Select(Ident(LV),OFFSET$0))))),Match(Apply(Select(Ident(LazyVals),STATE),List(Ident(flag), Literal(Constant(0)))),List(CaseDef(Literal(Constant(0)),EmptyTree,If(Apply(Select(Ident(LazyVals),CAS),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(1)), Literal(Constant(0)))),Block(List(Try(Assign(Ident(result),Literal(Constant(1))),Block(List(DefDef(Modifiers(,,List()),$anonfun,List(),List(List(ValDef(Modifiers(,,List()),x$1,TypeTree[TypeRef(ThisType(module class lang),Throwable)],EmptyTree))),TypeTree[TypeRef(ThisType(module class scala),Int)],Block(List(Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(0)), Literal(Constant(0))))),Throw(Ident(x$1))))),Closure(List(),Ident($anonfun),EmptyTree)),EmptyTree), Assign(Ident(s$lzy1),Ident(result)), Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(3)), Literal(Constant(0)))), Assign(Ident(retry),Literal(Constant(false)))),Literal(Constant(()))),Literal(Constant(())))), CaseDef(Literal(Constant(1)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(2)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(3)),EmptyTree,Block(List(Assign(Ident(retry),Literal(Constant(false))), Assign(Ident(result),Ident(s$lzy1))),Literal(Constant(()))))))))),Ident(result)))" + val fields = "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(TermRef(ThisType(module class <root>),scala),Short)],Literal(Constant(0))), ValDef(Modifiers(,,List()),bitmap$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0)))" + val moduleField = "TypeDef(Modifiers(final module <synthetic>,,List()),LV$,Template(DefDef(Modifiers(,,List()),<init>,List(),List(List()),TypeTree[TypeRef(ThisType(module class <empty>),LV$)],EmptyTree),List(Apply(Select(New(TypeTree[TypeRef(ThisType(module class lang),Object)]),<init>),List())),ValDef(Modifiers(,,List()),_,TypeTree[TermRef(ThisType(module class <empty>),LV)],EmptyTree),List(ValDef(Modifiers(,,List()),OFFSET$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Apply(Select(Ident(LazyVals),getOffset),List(This(LV), Literal(Constant(bitmap$0))))))))" + val treeS = tree.toString + Assert.assertTrue("volatile field lazy ref rewritten to class creation\n" + treeS, + treeS.contains(accessor) && treeS.contains(fields) && treeS.contains(moduleField)) + } + } + + @Test + def volatileFieldChar = { + checkCompile("LazyVals", "class LV { @volatile lazy val s = 'a' }") { + (tree, ctx) => + val accessor = "DefDef(Modifiers(,,List(Apply(Select(New(Ident(volatile)),<init>),List()))),s,List(),List(),TypeTree[TypeRef(ThisType(module class scala),Char)],Block(List(ValDef(Modifiers(,,List()),result,TypeTree[TypeRef(ThisType(module class scala),Char)],Literal(Constant(\u0000))), ValDef(Modifiers(,,List()),retry,TypeTree[TypeRef(ThisType(module class scala),Boolean)],Literal(Constant(true))), ValDef(Modifiers(,,List()),flag,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0))), WhileDo(Ident(retry),Block(List(Assign(Ident(flag),Apply(Select(Ident(LazyVals),get),List(This(LV), Select(Ident(LV),OFFSET$0))))),Match(Apply(Select(Ident(LazyVals),STATE),List(Ident(flag), Literal(Constant(0)))),List(CaseDef(Literal(Constant(0)),EmptyTree,If(Apply(Select(Ident(LazyVals),CAS),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(1)), Literal(Constant(0)))),Block(List(Try(Assign(Ident(result),Literal(Constant(a))),Block(List(DefDef(Modifiers(,,List()),$anonfun,List(),List(List(ValDef(Modifiers(,,List()),x$1,TypeTree[TypeRef(ThisType(module class lang),Throwable)],EmptyTree))),TypeTree[TypeRef(ThisType(module class scala),Int)],Block(List(Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(0)), Literal(Constant(0))))),Throw(Ident(x$1))))),Closure(List(),Ident($anonfun),EmptyTree)),EmptyTree), Assign(Ident(s$lzy1),Ident(result)), Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(3)), Literal(Constant(0)))), Assign(Ident(retry),Literal(Constant(false)))),Literal(Constant(()))),Literal(Constant(())))), CaseDef(Literal(Constant(1)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(2)),EmptyTree,Apply(Select(Ident(LazyVals),wait4Notification),List(This(LV), Select(Ident(LV),OFFSET$0), Ident(flag), Literal(Constant(0))))), CaseDef(Literal(Constant(3)),EmptyTree,Block(List(Assign(Ident(retry),Literal(Constant(false))), Assign(Ident(result),Ident(s$lzy1))),Literal(Constant(()))))))))),Ident(result)))" + val fields = "ValDef(Modifiers(,,List()),s$lzy1,TypeTree[TypeRef(ThisType(module class scala),Char)],Literal(Constant(\u0000))), ValDef(Modifiers(,,List()),bitmap$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Literal(Constant(0)))" + val moduleField = "TypeDef(Modifiers(final module <synthetic>,,List()),LV$,Template(DefDef(Modifiers(,,List()),<init>,List(),List(List()),TypeTree[TypeRef(ThisType(module class <empty>),LV$)],EmptyTree),List(Apply(Select(New(TypeTree[TypeRef(ThisType(module class lang),Object)]),<init>),List())),ValDef(Modifiers(,,List()),_,TypeTree[TermRef(ThisType(module class <empty>),LV)],EmptyTree),List(ValDef(Modifiers(,,List()),OFFSET$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Apply(Select(Ident(LazyVals),getOffset),List(This(LV), Literal(Constant(bitmap$0))))))))" + + val treeS = tree.toString + Assert.assertTrue("volatile field lazy ref rewritten to class creation\n" + treeS, + treeS.contains(accessor) && treeS.contains(fields) && treeS.contains(moduleField)) + } + } + + @Test + def volatilesReuseBitmaps = { + checkCompile("LazyVals", "class LV { @volatile lazy val a = 'a'; @volatile lazy val b = 'b'; }") { + (tree, ctx) => + val moduleField = "TypeDef(Modifiers(final module <synthetic>,,List()),LV$,Template(DefDef(Modifiers(,,List()),<init>,List(),List(List()),TypeTree[TypeRef(ThisType(module class <empty>),LV$)],EmptyTree),List(Apply(Select(New(TypeTree[TypeRef(ThisType(module class lang),Object)]),<init>),List())),ValDef(Modifiers(,,List()),_,TypeTree[TermRef(ThisType(module class <empty>),LV)],EmptyTree),List(ValDef(Modifiers(,,List()),OFFSET$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Apply(Select(Ident(LazyVals),getOffset),List(This(LV), Literal(Constant(bitmap$0))))))))" + val reuseFieldPattern = "Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$0), Literal(Constant(3)), Literal(Constant(1))))" + val treeS = tree.toString + Assert.assertTrue("volatile field lazy ref rewritten to class creation\n" + treeS, + treeS.contains(moduleField) && treeS.contains(reuseFieldPattern)) + } + } + + @Test + def volatilesCreateNewBitmaps = { + checkCompile("LazyVals", + """ + | class LV { + | @volatile lazy val a1 = '1'; + | @volatile lazy val a2 = '1'; + | @volatile lazy val a3 = '1'; + | @volatile lazy val a4 = '1'; + | @volatile lazy val a5 = '1'; + | @volatile lazy val a6 = '1'; + | @volatile lazy val a7 = '1'; + | @volatile lazy val a8 = '1'; + | @volatile lazy val a9 = '1'; + | @volatile lazy val a10 = '1'; + | @volatile lazy val a11 = '1'; + | @volatile lazy val a12 = '1'; + | @volatile lazy val a13 = '1'; + | @volatile lazy val a14 = '1'; + | @volatile lazy val a15 = '1'; + | @volatile lazy val a16 = '1'; + | @volatile lazy val a17 = '1'; + | @volatile lazy val a18 = '1'; + | @volatile lazy val a19 = '1'; + | @volatile lazy val a20 = '1'; + | @volatile lazy val a21 = '1'; + | @volatile lazy val a22 = '1'; + | @volatile lazy val a23 = '1'; + | @volatile lazy val a24 = '1'; + | @volatile lazy val a25 = '1'; + | @volatile lazy val a26 = '1'; + | @volatile lazy val a27 = '1'; + | @volatile lazy val a28 = '1'; + | @volatile lazy val a29 = '1'; + | @volatile lazy val a30 = '1'; + | @volatile lazy val a31 = '1'; + | @volatile lazy val a32 = '1'; + | @volatile lazy val a33 = '1'; + | @volatile lazy val a34 = '1'; + | } + """.stripMargin ){ + (tree, ctx) => + val moduleField = "TypeDef(Modifiers(final module <synthetic>,,List()),LV$,Template(DefDef(Modifiers(,,List()),<init>,List(),List(List()),TypeTree[TypeRef(ThisType(module class <empty>),LV$)],EmptyTree),List(Apply(Select(New(TypeTree[TypeRef(ThisType(module class lang),Object)]),<init>),List())),ValDef(Modifiers(,,List()),_,TypeTree[TermRef(ThisType(module class <empty>),LV)],EmptyTree),List(ValDef(Modifiers(,,List()),OFFSET$1,TypeTree[TypeRef(ThisType(module class scala),Long)],Apply(Select(Ident(LazyVals),getOffset),List(This(LV), Literal(Constant(bitmap$1))))), ValDef(Modifiers(,,List()),OFFSET$0,TypeTree[TypeRef(ThisType(module class scala),Long)],Apply(Select(Ident(LazyVals),getOffset),List(This(LV), Literal(Constant(bitmap$0))))))))" + val reuseFieldPattern = "Apply(Select(Ident(LazyVals),setFlag),List(This(LV), Select(Ident(LV),OFFSET$1), Literal(Constant(3)), Literal(Constant(1))))" + val treeS = tree.toString + Assert.assertTrue("volatile field lazy ref rewritten to class creation", + treeS.contains(moduleField) && treeS.contains(reuseFieldPattern)) + } + }*/ +} diff --git a/compiler/test/dotty/tools/dotc/transform/PostTyperTransformerTest.scala b/compiler/test/dotty/tools/dotc/transform/PostTyperTransformerTest.scala new file mode 100644 index 000000000..03d6d9b36 --- /dev/null +++ b/compiler/test/dotty/tools/dotc/transform/PostTyperTransformerTest.scala @@ -0,0 +1,132 @@ +package dotty.tools +package dotc +package transform + +import org.junit.{Assert, Test} +import core._ +import ast.Trees +import Contexts._ +import Flags._ +import Denotations._ +import NameOps._ +import Symbols._ +import Types._ +import Decorators._ +import Trees._ +import TreeTransforms.{TreeTransform, TreeTransformer} + +class PostTyperTransformerTest extends DottyTest { + /* FIXME: re-enable after adapting to new scheme + + @Test + def shouldStripImports = checkCompile("frontend", "class A{ import scala.collection.mutable._; val d = 1}") { + (tree, context) => + implicit val ctx = context + class EmptyTransform extends TreeTransform { + override def name: String = "empty" + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + } + val transformer = new PostTyperTransformer { + override def transformations = Array(new EmptyTransform) + + override def name: String = "test" + } + val transformed = transformer.transform(tree) + + Assert.assertTrue("should strip imports", + !transformed.toString.toLowerCase.contains("import") + ) + } + + @Test + def shouldStripNamedArgs = checkCompile("frontend", "class A{ def p(x:Int, y:Int= 2) = 1; p(1, y = 2)}") { + (tree, context) => + implicit val ctx = context + class EmptyTransform extends TreeTransform { + override def name: String = "empty" + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + } + val transformer = new PostTyperTransformer { + override def transformations = Array(new EmptyTransform) + + override def name: String = "test" + } + val transformed = transformer.transform(tree) + + Assert.assertTrue("should string named arguments", + !transformed.toString.contains("NamedArg") + ) + } + + @Test + def shouldReorderExistingObjectsInPackage = checkCompile("frontend", "object A{}; class A{} ") { + (tree, context) => + implicit val ctx = context + class EmptyTransform extends TreeTransform { + override def name: String = "empty" + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + } + val transformer = new PostTyperTransformer { + override def transformations = Array(new EmptyTransform) + + override def name: String = "test" + } + val transformed = transformer.transform(tree).toString + val classPattern = "TypeDef(Modifiers(,,List()),A," + val classPos = transformed.indexOf(classPattern) + val moduleClassPattern = "TypeDef(Modifiers(final module,,List()),A$," + val modulePos = transformed.indexOf(moduleClassPattern) + + Assert.assertTrue("should reorder existing objects in package", + classPos < modulePos + ) + } + + @Test + def shouldReorderExistingObjectsInBlock = checkCompile("frontend", "class D {def p = {object A{}; class A{}; 1}} ") { + (tree, context) => + implicit val ctx = context + class EmptyTransform extends TreeTransform { + override def name: String = "empty" + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + } + val transformer = new PostTyperTransformer { + override def transformations = Array(new EmptyTransform) + + override def name: String = "test" + } + val transformed = transformer.transform(tree).toString + val classPattern = "TypeDef(Modifiers(,,List()),A," + val classPos = transformed.indexOf(classPattern) + val moduleClassPattern = "TypeDef(Modifiers(final module,,List()),A$," + val modulePos = transformed.indexOf(moduleClassPattern) + + Assert.assertTrue("should reorder existing objects in block", + classPos < modulePos + ) + } + + @Test + def shouldReorderExistingObjectsInTemplate = checkCompile("frontend", "class D {object A{}; class A{}; } ") { + (tree, context) => + implicit val ctx = context + class EmptyTransform extends TreeTransform { + override def name: String = "empty" + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + } + val transformer = new PostTyperTransformer { + override def transformations = Array(new EmptyTransform) + + override def name: String = "test" + } + val transformed = transformer.transform(tree).toString + val classPattern = "TypeDef(Modifiers(,,List()),A," + val classPos = transformed.indexOf(classPattern) + val moduleClassPattern = "TypeDef(Modifiers(final module,,List()),A$," + val modulePos = transformed.indexOf(moduleClassPattern) + + Assert.assertTrue("should reorder existing objects in template", + classPos < modulePos + ) + }*/ +} diff --git a/compiler/test/dotty/tools/dotc/transform/TreeTransformerTest.scala b/compiler/test/dotty/tools/dotc/transform/TreeTransformerTest.scala new file mode 100644 index 000000000..d72980d80 --- /dev/null +++ b/compiler/test/dotty/tools/dotc/transform/TreeTransformerTest.scala @@ -0,0 +1,198 @@ +package dotty.tools +package dotc +package transform + +import org.junit.{Assert, Test} +import TreeTransforms.{TransformerInfo, TreeTransformer, MiniPhaseTransform} +import ast.tpd +import core.Constants.Constant +import core.Contexts.Context + +class TreeTransformerTest extends DottyTest { + + @Test + def shouldReturnSameTreeIfUnchanged = checkCompile("frontend", "class A{ val d = 1}") { + (tree, context) => + implicit val ctx = context + class EmptyTransform extends MiniPhaseTransform { + override def phaseName: String = "empty" + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + } + val transformer = new TreeTransformer { + override def miniPhases = Array(new EmptyTransform) + + override def phaseName: String = "test" + } + val transformed = transformer.macroTransform(tree) + + Assert.assertTrue("returns same tree if unmodified", + tree eq transformed + ) + } + + // Disabled, awaiting resolution. @Test + def canReplaceConstant = checkCompile("frontend", "class A{ val d = 1}") { + (tree, context) => + implicit val ctx = context + class ConstantTransform extends MiniPhaseTransform { + + override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = tpd.Literal(Constant(2)) + override def phaseName: String = "canReplaceConstant" + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + } + val transformer = new TreeTransformer { + override def miniPhases = Array(new ConstantTransform) + + override def phaseName: String = "test" + } + val transformed = transformer.macroTransform(tree) + + Assert.assertTrue("returns same tree if unmodified", + transformed.toString.contains("List(ValDef(Modifiers(,,List()),d,TypeTree[TypeRef(ThisType(module class scala),Int)],Literal(Constant(2)))") + ) + } + + @Test + def canOverwrite = checkCompile("frontend", "class A{ val d = 1}") { + (tree, context) => + implicit val ctx = context + class Transformation extends MiniPhaseTransform { + + override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = tpd.Literal(Constant(-1)) + override def phaseName: String = "canOverwrite" + + override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo): tpd.ValDef = { + Assert.assertTrue("transformation of children succeeded", + tree.rhs.toString == "Literal(Constant(-1))" + ) + tpd.cpy.ValDef(tree)(rhs = tpd.Literal(Constant(2))) + } + + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + } + val transformer = new TreeTransformer { + override def miniPhases = Array(new Transformation) + + override def phaseName: String = "test" + + } + val tr = transformer.macroTransform(tree).toString + + Assert.assertTrue("node can rewrite children", + tr.contains("Literal(Constant(2))") && !tr.contains("Literal(Constant(-1))") + ) + } + + @Test + def transformationOrder = checkCompile("frontend", "class A{ val d = 1}") { + (tree, context) => + implicit val ctx = context + class Transformation1 extends MiniPhaseTransform { + override def phaseName: String = "transformationOrder1" + + override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = { + Assert.assertTrue("correct constant", + tree.const.toString == "Constant(1)" + ) + tpd.cpy.Literal(tree)(Constant(-1)) + } + + override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo): tpd.ValDef = { + Assert.assertTrue("transformation of children succeeded", + tree.rhs.toString == "Literal(Constant(-1))" + ) + tpd.cpy.ValDef(tree)(rhs = tpd.Literal(Constant(2))) + } + + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + } + class Transformation2 extends MiniPhaseTransform { + override def phaseName: String = "transformationOrder2" + override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo): tpd.ValDef = { + Assert.assertTrue("transformation of children succeeded", + tree.rhs.toString == "Literal(Constant(2))" + ) + tpd.cpy.ValDef(tree)(rhs = tpd.Literal(Constant(3))) + } + + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + } + val transformer = new TreeTransformer { + override def miniPhases = Array(new Transformation1, new Transformation2) + + override def phaseName: String = "test" + } + val tr = transformer.macroTransform(tree).toString + + Assert.assertTrue("node can rewrite children", + tr.contains("Literal(Constant(3))") + ) + } + + @Test + def invocationCount = checkCompile("frontend", "class A{ val d = 1}") { + (tree, context) => + implicit val ctx = context + var transformed1 = 0 + class Transformation1 extends MiniPhaseTransform { + override def phaseName: String = "invocationCount1" + override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = { + transformed1 += 1 + Assert.assertTrue("correct constant", + tree.const.toString == "Constant(1)" + ) + tpd.cpy.Literal(tree)(Constant(-1)) + } + + override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo) = { + transformed1 += 1 + Assert.assertTrue("transformation of children succeeded", + tree.rhs.toString == "Literal(Constant(-3))" + ) + tpd.cpy.ValDef(tree)(rhs = transformFollowing(tpd.Literal(Constant(2)))) + } + + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + } + var transformed2 = 0 + class Transformation2 extends MiniPhaseTransform { + var constantsSeen = 0 + override def phaseName: String = "invocationCount2" + override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = { + transformed2 += 1 + constantsSeen match { + case 0 => + Assert.assertTrue("correct constant", + tree.const.toString == "Constant(-1)" + ) + case 1 => + Assert.assertTrue("correct constant", + tree.const.toString == "Constant(2)" + ) + case _ => Assert.fail("to many constants seen") + } + constantsSeen += 1 + tpd.cpy.Literal(tree)(Constant(-3)) + } + + override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo) = { + transformed2 += 1 + Assert.assertTrue("transformation of children succeeded", + tree.rhs.toString == "Literal(Constant(-3))" + ) + transformFollowing(tpd.cpy.ValDef(tree)(rhs = tpd.Literal(Constant(3)))) + } + + init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId) + } + val transformer = new TreeTransformer { + override def miniPhases = Array(new Transformation1, new Transformation2) + + override def phaseName: String = "test" + } + val tr = transformer.macroTransform(tree).toString + Assert.assertTrue("transformations aren't invoked multiple times", + transformed1 == 2 && transformed2 == 3 + ) + } +} |