Skip to content

Commit a9f95dc

Browse files
committed
Merge pull request scala#1340 from gkossakowski/revert-static-annotation
Revert `@static` annotation
2 parents 61480eb + fbed813 commit a9f95dc

27 files changed

+36
-722
lines changed
+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
acfbbb4117b222b488226b4a89d5e732eb59f19c ?scala-compiler-src.jar
1+
2698ecddfcde060a5db2a37e4aa448f4ad5c5891 ?scala-compiler-src.jar

lib/scala-compiler.jar.desired.sha1

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
e0c0f2326622f535aa86978dee74dc7ac86e401b ?scala-compiler.jar
1+
d9ce03a6d3d33234d94577b0cc0093f7a1739d95 ?scala-compiler.jar
+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
52b0ea12b0fe6c2150434fdda3909c2aa927a325 ?scala-library-src.jar
1+
a06b6e42d646e7077325fe1147f1fc9fa22aad7b ?scala-library-src.jar

lib/scala-library.jar.desired.sha1

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7a35fcd17b39ea1e13cc8c919e1e556eed81e799 ?scala-library.jar
1+
4b0516ead118899611bbf6b1b21bf7a32e1f1f40 ?scala-library.jar
+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
fc25fdfd30959e77b85c0c7917005a83890f94a2 ?scala-reflect-src.jar
1+
4f474a08df49c89a04031096093a0eda7875c8b7 ?scala-reflect-src.jar

lib/scala-reflect.jar.desired.sha1

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5aca838ee9d82be45fb476c1722f71842d5d528e ?scala-reflect.jar
1+
2a2172b2a97a0458ccce846b3a779e7728a7f034 ?scala-reflect.jar

src/compiler/scala/tools/nsc/backend/icode/GenICode.scala

+19-82
Original file line numberDiff line numberDiff line change
@@ -121,44 +121,26 @@ abstract class GenICode extends SubComponent {
121121
m.native = m.symbol.hasAnnotation(definitions.NativeAttr)
122122

123123
if (!m.isAbstractMethod && !m.native) {
124-
val staticfield = if (m.symbol.isAccessor && m.symbol.accessed.hasStaticAnnotation) {
125-
val compClass = m.symbol.owner.companionClass
126-
compClass.info.findMember(m.symbol.accessed.name, NoFlags, NoFlags, false)
127-
} else NoSymbol
128-
if (staticfield != NoSymbol) {
129-
// in companion object accessors to @static fields, we access the static field directly
130-
val hostClass = m.symbol.owner.companionClass
131-
if (m.symbol.isGetter) {
132-
ctx1.bb.emit(LOAD_FIELD(staticfield, true) setHostClass hostClass, tree.pos)
133-
ctx1.bb.closeWith(RETURN(m.returnType))
134-
} else if (m.symbol.isSetter) {
135-
ctx1.bb.emit(LOAD_LOCAL(m.locals.head), tree.pos)
136-
ctx1.bb.emit(STORE_FIELD(staticfield, true), tree.pos)
124+
ctx1 = genLoad(rhs, ctx1, m.returnType);
125+
126+
// reverse the order of the local variables, to match the source-order
127+
m.locals = m.locals.reverse
128+
129+
rhs match {
130+
case Block(_, Return(_)) => ()
131+
case Return(_) => ()
132+
case EmptyTree =>
133+
globalError("Concrete method has no definition: " + tree + (
134+
if (settings.debug.value) "(found: " + m.symbol.owner.info.decls.toList.mkString(", ") + ")"
135+
else "")
136+
)
137+
case _ => if (ctx1.bb.isEmpty)
138+
ctx1.bb.closeWith(RETURN(m.returnType), rhs.pos)
139+
else
137140
ctx1.bb.closeWith(RETURN(m.returnType))
138-
} else assert(false, "unreachable")
139-
} else {
140-
ctx1 = genLoad(rhs, ctx1, m.returnType);
141-
142-
// reverse the order of the local variables, to match the source-order
143-
m.locals = m.locals.reverse
144-
145-
rhs match {
146-
case Block(_, Return(_)) => ()
147-
case Return(_) => ()
148-
case EmptyTree =>
149-
globalError("Concrete method has no definition: " + tree + (
150-
if (settings.debug.value) "(found: " + m.symbol.owner.info.decls.toList.mkString(", ") + ")"
151-
else "")
152-
)
153-
case _ =>
154-
if (ctx1.bb.isEmpty)
155-
ctx1.bb.closeWith(RETURN(m.returnType), rhs.pos)
156-
else
157-
ctx1.bb.closeWith(RETURN(m.returnType))
158-
}
159-
if (!ctx1.bb.closed) ctx1.bb.close
160-
prune(ctx1.method)
161141
}
142+
if (!ctx1.bb.closed) ctx1.bb.close
143+
prune(ctx1.method)
162144
} else
163145
ctx1.method.setCode(NoCode)
164146
ctx1
@@ -900,47 +882,6 @@ abstract class GenICode extends SubComponent {
900882
generatedType = toTypeKind(fun.symbol.tpe.resultType)
901883
ctx1
902884

903-
case app @ Apply(fun @ Select(qual, _), args)
904-
if !ctx.method.symbol.isStaticConstructor
905-
&& fun.symbol.isAccessor && fun.symbol.accessed.hasStaticAnnotation
906-
&& qual.tpe.typeSymbol.orElse(fun.symbol.owner).companionClass != NoSymbol =>
907-
// bypass the accessor to the companion object and load the static field directly
908-
// this bypass is not done:
909-
// - if the static intializer for the static field itself
910-
// - if there is no companion class of the object owner - this happens in the REPL
911-
def genLoadApply5 = {
912-
val sym = fun.symbol
913-
generatedType = toTypeKind(sym.accessed.info)
914-
val hostOwner = qual.tpe.typeSymbol.orElse(sym.owner)
915-
val hostClass = hostOwner.companionClass
916-
val staticfield = hostClass.info.findMember(sym.accessed.name, NoFlags, NoFlags, false) orElse {
917-
if (!currentRun.compiles(hostOwner)) {
918-
// hostOwner was separately compiled -- the static field symbol needs to be recreated in hostClass
919-
import Flags._
920-
debuglog("recreating sym.accessed.name: " + sym.accessed.name)
921-
val objectfield = hostOwner.info.findMember(sym.accessed.name, NoFlags, NoFlags, false)
922-
val staticfield = hostClass.newVariable(newTermName(sym.accessed.name.toString), tree.pos, STATIC | SYNTHETIC | FINAL) setInfo objectfield.tpe
923-
staticfield.addAnnotation(definitions.StaticClass)
924-
hostClass.info.decls enter staticfield
925-
staticfield
926-
} else NoSymbol
927-
}
928-
929-
if (sym.isGetter) {
930-
ctx.bb.emit(LOAD_FIELD(staticfield, true) setHostClass hostClass, tree.pos)
931-
ctx
932-
} else if (sym.isSetter) {
933-
val ctx1 = genLoadArguments(args, sym.info.paramTypes, ctx)
934-
ctx1.bb.emit(STORE_FIELD(staticfield, true), tree.pos)
935-
ctx1.bb.emit(CONSTANT(Constant(false)), tree.pos)
936-
ctx1
937-
} else {
938-
assert(false, "supposedly unreachable")
939-
ctx
940-
}
941-
}
942-
genLoadApply5
943-
944885
case app @ Apply(fun, args) =>
945886
def genLoadApply6 = {
946887
val sym = fun.symbol
@@ -1732,12 +1673,8 @@ abstract class GenICode extends SubComponent {
17321673
* backend emits them as static).
17331674
* No code is needed for this module symbol.
17341675
*/
1735-
for (
1736-
f <- cls.info.decls;
1737-
if !f.isMethod && f.isTerm && !f.isModule && !(f.owner.isModuleClass && f.hasStaticAnnotation)
1738-
) {
1676+
for (f <- cls.info.decls ; if !f.isMethod && f.isTerm && !f.isModule)
17391677
ctx.clazz addField new IField(f)
1740-
}
17411678
}
17421679

17431680
/**

src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala

+1-4
Original file line numberDiff line numberDiff line change
@@ -1190,9 +1190,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
11901190
log(s"No forwarder for non-public member $m")
11911191
else {
11921192
log("Adding static forwarder for '%s' from %s to '%s'".format(m, jclassName, moduleClass))
1193-
if (m.isAccessor && m.accessed.hasStaticAnnotation) {
1194-
log("@static: accessor " + m + ", accessed: " + m.accessed)
1195-
} else addForwarder(isRemoteClass, jclass, moduleClass, m)
1193+
addForwarder(isRemoteClass, jclass, moduleClass, m)
11961194
}
11971195
}
11981196
}
@@ -1697,7 +1695,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
16971695
jmethod = clinitMethod
16981696
jMethodName = CLASS_CONSTRUCTOR_NAME
16991697
jmethod.visitCode()
1700-
computeLocalVarsIndex(m)
17011698
genCode(m, false, true)
17021699
jmethod.visitMaxs(0, 0) // just to follow protocol, dummy arguments
17031700
jmethod.visitEnd()

src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala

+1-5
Original file line numberDiff line numberDiff line change
@@ -1023,8 +1023,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
10231023

10241024
method = m
10251025
jmethod = clinitMethod
1026-
1027-
computeLocalVarsIndex(m)
10281026
genCode(m)
10291027
case None =>
10301028
legacyStaticInitializer(cls, clinit)
@@ -1126,9 +1124,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
11261124
log("No forwarder for " + m + " due to conflict with " + linkedClass.info.member(m.name))
11271125
else {
11281126
log("Adding static forwarder for '%s' from %s to '%s'".format(m, className, moduleClass))
1129-
if (m.isAccessor && m.accessed.hasStaticAnnotation) {
1130-
log("@static: accessor " + m + ", accessed: " + m.accessed)
1131-
} else addForwarder(jclass, moduleClass, m)
1127+
addForwarder(jclass, moduleClass, m)
11321128
}
11331129
}
11341130
}

src/compiler/scala/tools/nsc/transform/CleanUp.scala

+7-146
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,9 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
2323
new CleanUpTransformer(unit)
2424

2525
class CleanUpTransformer(unit: CompilationUnit) extends Transformer {
26-
private val newStaticMembers = mutable.Buffer.empty[Tree]
27-
private val newStaticInits = mutable.Buffer.empty[Tree]
28-
private val symbolsStoredAsStatic = mutable.Map.empty[String, Symbol]
29-
private val staticBodies = mutable.Map.empty[(Symbol, Symbol), Tree]
30-
private val syntheticClasses = mutable.Map.empty[Symbol, mutable.Set[Tree]] // package and trees
31-
private val classNames = mutable.Map.empty[Symbol, Set[Name]]
26+
private val newStaticMembers = mutable.Buffer.empty[Tree]
27+
private val newStaticInits = mutable.Buffer.empty[Tree]
28+
private val symbolsStoredAsStatic = mutable.Map.empty[String, Symbol]
3229
private def clearStatics() {
3330
newStaticMembers.clear()
3431
newStaticInits.clear()
@@ -48,9 +45,8 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
4845
result
4946
}
5047
private def transformTemplate(tree: Tree) = {
51-
val t @ Template(parents, self, body) = tree
48+
val Template(parents, self, body) = tree
5249
clearStatics()
53-
5450
val newBody = transformTrees(body)
5551
val templ = deriveTemplate(tree)(_ => transformTrees(newStaticMembers.toList) ::: newBody)
5652
try addStaticInits(templ) // postprocess to include static ctors
@@ -550,80 +546,6 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
550546
else tree
551547
}
552548

553-
case DefDef(mods, name, tps, vps, tp, rhs) if tree.symbol.hasStaticAnnotation =>
554-
reporter.error(tree.pos, "The @static annotation is not allowed on method definitions.")
555-
super.transform(tree)
556-
557-
case ValDef(mods, name, tpt, rhs) if tree.symbol.hasStaticAnnotation =>
558-
def transformStaticValDef = {
559-
log("moving @static valdef field: " + name + ", in: " + tree.symbol.owner)
560-
val sym = tree.symbol
561-
val owner = sym.owner
562-
563-
val staticBeforeLifting = atPhase(currentRun.erasurePhase) { owner.isStatic }
564-
val isPrivate = atPhase(currentRun.typerPhase) { sym.getter(owner).hasFlag(PRIVATE) }
565-
val isProtected = atPhase(currentRun.typerPhase) { sym.getter(owner).hasFlag(PROTECTED) }
566-
val isLazy = atPhase(currentRun.typerPhase) { sym.getter(owner).hasFlag(LAZY) }
567-
if (!owner.isModuleClass || !staticBeforeLifting) {
568-
if (!sym.isSynthetic) {
569-
reporter.error(tree.pos, "Only members of top-level objects and their nested objects can be annotated with @static.")
570-
tree.symbol.removeAnnotation(StaticClass)
571-
}
572-
super.transform(tree)
573-
} else if (isPrivate || isProtected) {
574-
reporter.error(tree.pos, "The @static annotation is only allowed on public members.")
575-
tree.symbol.removeAnnotation(StaticClass)
576-
super.transform(tree)
577-
} else if (isLazy) {
578-
reporter.error(tree.pos, "The @static annotation is not allowed on lazy members.")
579-
tree.symbol.removeAnnotation(StaticClass)
580-
super.transform(tree)
581-
} else if (owner.isModuleClass) {
582-
val linkedClass = owner.companionClass match {
583-
case NoSymbol =>
584-
// create the companion class if it does not exist
585-
val enclosing = owner.owner
586-
val compclass = enclosing.newClass(newTypeName(owner.name.toString))
587-
compclass setInfo ClassInfoType(List(ObjectClass.tpe), newScope, compclass)
588-
enclosing.info.decls enter compclass
589-
590-
val compclstree = ClassDef(compclass, NoMods, ListOfNil, ListOfNil, List(), tree.pos)
591-
592-
syntheticClasses.getOrElseUpdate(enclosing, mutable.Set()) += compclstree
593-
594-
compclass
595-
case comp => comp
596-
}
597-
598-
// create a static field in the companion class for this @static field
599-
val stfieldSym = linkedClass.newValue(newTermName(name), tree.pos, STATIC | SYNTHETIC | FINAL) setInfo sym.tpe
600-
if (sym.isMutable) stfieldSym.setFlag(MUTABLE)
601-
stfieldSym.addAnnotation(StaticClass)
602-
603-
val names = classNames.getOrElseUpdate(linkedClass, linkedClass.info.decls.collect {
604-
case sym if sym.name.isTermName => sym.name
605-
} toSet)
606-
if (names(stfieldSym.name)) {
607-
reporter.error(
608-
tree.pos,
609-
"@static annotated field " + tree.symbol.name + " has the same name as a member of class " + linkedClass.name
610-
)
611-
} else {
612-
linkedClass.info.decls enter stfieldSym
613-
614-
val initializerBody = rhs
615-
616-
// static field was previously initialized in the companion object itself, like this:
617-
// staticBodies((linkedClass, stfieldSym)) = Select(This(owner), sym.getter(owner))
618-
// instead, we move the initializer to the static ctor of the companion class
619-
// we save the entire ValDef/DefDef to extract the rhs later
620-
staticBodies((linkedClass, stfieldSym)) = tree
621-
}
622-
}
623-
super.transform(tree)
624-
}
625-
transformStaticValDef
626-
627549
/* MSIL requires that the stack is empty at the end of a try-block.
628550
* Hence, we here rewrite all try blocks with a result != {Unit, All} such that they
629551
* store their result in a local variable. The catch blocks are adjusted as well.
@@ -738,11 +660,6 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
738660
if (newStaticInits.isEmpty)
739661
template
740662
else {
741-
val ctorBody = newStaticInits.toList flatMap {
742-
case Block(stats, expr) => stats :+ expr
743-
case t => List(t)
744-
}
745-
746663
val newCtor = findStaticCtor(template) match {
747664
// in case there already were static ctors - augment existing ones
748665
// currently, however, static ctors aren't being generated anywhere else
@@ -751,78 +668,22 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
751668
deriveDefDef(ctor) {
752669
case block @ Block(stats, expr) =>
753670
// need to add inits to existing block
754-
treeCopy.Block(block, ctorBody ::: stats, expr)
671+
treeCopy.Block(block, newStaticInits.toList ::: stats, expr)
755672
case term: TermTree =>
756673
// need to create a new block with inits and the old term
757-
treeCopy.Block(term, ctorBody, term)
674+
treeCopy.Block(term, newStaticInits.toList, term)
758675
}
759676
case _ =>
760677
// create new static ctor
761678
val staticCtorSym = currentClass.newStaticConstructor(template.pos)
762-
val rhs = Block(ctorBody, Literal(Constant(())))
679+
val rhs = Block(newStaticInits.toList, Literal(Constant(())))
763680

764681
localTyper.typedPos(template.pos)(DefDef(staticCtorSym, rhs))
765682
}
766683
deriveTemplate(template)(newCtor :: _)
767684
}
768685
}
769686

770-
private def addStaticDeclarations(tree: Template, clazz: Symbol) {
771-
// add static field initializer statements for each static field in clazz
772-
if (!clazz.isModuleClass) for {
773-
staticSym <- clazz.info.decls
774-
if staticSym.hasStaticAnnotation
775-
} staticSym match {
776-
case stfieldSym if (stfieldSym.isValue && !stfieldSym.isMethod) || stfieldSym.isVariable =>
777-
log(stfieldSym + " is value: " + stfieldSym.isValue)
778-
val valdef = staticBodies((clazz, stfieldSym))
779-
val ValDef(_, _, _, rhs) = valdef
780-
val fixedrhs = rhs.changeOwner((valdef.symbol, clazz.info.decl(nme.CONSTRUCTOR)))
781-
782-
val stfieldDef = localTyper.typedPos(tree.pos)(VAL(stfieldSym) === EmptyTree)
783-
val flattenedInit = fixedrhs match {
784-
case Block(stats, expr) => Block(stats, REF(stfieldSym) === expr)
785-
case rhs => REF(stfieldSym) === rhs
786-
}
787-
val stfieldInit = localTyper.typedPos(tree.pos)(flattenedInit)
788-
789-
// add field definition to new defs
790-
newStaticMembers append stfieldDef
791-
newStaticInits append stfieldInit
792-
case _ => // ignore @static on other members
793-
}
794-
}
795-
796-
797-
798-
override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = {
799-
super.transformStats(stats, exprOwner) ++ {
800-
// flush pending synthetic classes created in this owner
801-
val synthclassdefs = syntheticClasses.get(exprOwner).toList.flatten
802-
syntheticClasses -= exprOwner
803-
synthclassdefs map {
804-
cdef => localTyper.typedPos(cdef.pos)(cdef)
805-
}
806-
} map {
807-
case clsdef @ ClassDef(mods, name, tparams, t @ Template(parent, self, body)) =>
808-
// process all classes in the package again to add static initializers
809-
clearStatics()
810-
811-
addStaticDeclarations(t, clsdef.symbol)
812-
813-
val templ = deriveTemplate(t)(_ => transformTrees(newStaticMembers.toList) ::: body)
814-
val ntempl =
815-
try addStaticInits(templ)
816-
finally clearStatics()
817-
818-
val derived = deriveClassDef(clsdef)(_ => ntempl)
819-
classNames.remove(clsdef.symbol)
820-
derived
821-
822-
case stat => stat
823-
}
824-
}
825-
826687
} // CleanUpTransformer
827688

828689
}

0 commit comments

Comments
 (0)