diff options
author | Paul Phillips <paulp@improving.org> | 2013-08-17 07:56:01 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-08-17 10:58:12 -0700 |
commit | dc872cd1fda84d04dc4de7789a21517902322d68 (patch) | |
tree | 7695580e4563ecfa7c25e5986e42b19628ce14ef | |
parent | b084cab0aa474e9f650c391fa64464734c276597 (diff) | |
download | scala-dc872cd1fda84d04dc4de7789a21517902322d68.tar.gz scala-dc872cd1fda84d04dc4de7789a21517902322d68.tar.bz2 scala-dc872cd1fda84d04dc4de7789a21517902322d68.zip |
Broke up typed1's giant pattern match.
Another level of dispatch based on what trees on can expect
to see during what mode. This should be beneficial for both
performance (smaller methods, fewer type tests) and correctness
(prevent trees from reaching inappropriate typing methods by
construction rather than via ad hoc checks.)
This work also revealed that UnApply trees never reach here,
so I removed typedUnApply as dead code.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 111 |
1 files changed, 66 insertions, 45 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index d2ff47626d..dd92657de8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -4993,13 +4993,6 @@ trait Typers extends Adaptations with Tags with TypersTracking { treeCopy.Star(tree, typed(tree.elem, mode, pt)) setType makeFullyDefined(pt) } - def typedUnApply(tree: UnApply) = { - val fun1 = typed(tree.fun) - val tpes = formalTypes(unapplyTypeList(tree.fun.pos, tree.fun.symbol, fun1.tpe, tree.args), tree.args.length) - val args1 = map2(tree.args, tpes)(typedPattern) - treeCopy.UnApply(tree, fun1, args1) setType pt - } - def issueTryWarnings(tree: Try): Try = { def checkForCatchAll(cdef: CaseDef) { def unbound(t: Tree) = t.symbol == null || t.symbol == NoSymbol @@ -5254,52 +5247,80 @@ trait Typers extends Adaptations with Tags with TypersTracking { typerWithLocalContext(context.makeNewScope(fun, fun.symbol))(_.typedFunction(fun, mode, pt)) } - // begin typed1 - //if (settings.debug.value && tree.isDef) log("typing definition of "+sym);//DEBUG - tree match { - case tree: Ident => typedIdentOrWildcard(tree) - case tree: Select => typedSelectOrSuperCall(tree) - case tree: Apply => typedApply(tree) + // Trees only allowed during pattern mode. + def typedInPatternMode(tree: Tree): Tree = tree match { + case tree: Alternative => typedAlternative(tree) + case tree: Star => typedStar(tree) + case _ => abort(s"unexpected tree in pattern mode: ${tree.getClass}\n$tree") + } + + def typedTypTree(tree: TypTree): Tree = tree match { case tree: TypeTree => typedTypeTree(tree) - case tree: Literal => typedLiteral(tree) - case tree: This => typedThis(tree) - case tree: ValDef => typedValDef(tree) - case tree: DefDef => defDefTyper(tree).typedDefDef(tree) - case tree: Block => typerWithLocalContext(context.makeNewScope(tree, context.owner))(_.typedBlock(tree, mode, pt)) - case tree: If => typedIf(tree) - case tree: TypeApply => typedTypeApply(tree) case tree: AppliedTypeTree => typedAppliedTypeTree(tree) - case tree: Bind => typedBind(tree) - case tree: Function => typedFunction(tree) - case tree: Match => typedVirtualizedMatch(tree) - case tree: New => typedNew(tree) - case tree: Assign => typedAssign(tree.lhs, tree.rhs) - case tree: AssignOrNamedArg => typedAssign(tree.lhs, tree.rhs) // called by NamesDefaults in silent typecheck - case tree: Super => typedSuper(tree) case tree: TypeBoundsTree => typedTypeBoundsTree(tree) - case tree: Typed => typedTyped(tree) - case tree: ClassDef => newTyper(context.makeNewScope(tree, sym)).typedClassDef(tree) - case tree: ModuleDef => newTyper(context.makeNewScope(tree, sym.moduleClass)).typedModuleDef(tree) - case tree: TypeDef => typedTypeDef(tree) - case tree: LabelDef => labelTyper(tree).typedLabelDef(tree) - case tree: PackageDef => typedPackageDef(tree) - case tree: DocDef => typedDocDef(tree, mode, pt) - case tree: Annotated => typedAnnotated(tree) case tree: SingletonTypeTree => typedSingletonTypeTree(tree) case tree: SelectFromTypeTree => typedSelectFromTypeTree(tree) case tree: CompoundTypeTree => typedCompoundTypeTree(tree) case tree: ExistentialTypeTree => typedExistentialTypeTree(tree) - case tree: Return => typedReturn(tree) - case tree: Try => typedTry(tree) - case tree: Throw => typedThrow(tree) - case tree: Alternative => typedAlternative(tree) - case tree: Star => typedStar(tree) - case tree: UnApply => typedUnApply(tree) - case tree: ArrayValue => typedArrayValue(tree) - case tree: ApplyDynamic => typedApplyDynamic(tree) - case tree: ReferenceToBoxed => typedReferenceToBoxed(tree) case tree: TypeTreeWithDeferredRefCheck => tree // TODO: retype the wrapped tree? TTWDRC would have to change to hold the wrapped tree (not a closure) - case _ => abort(s"unexpected tree: ${tree.getClass}\n$tree") + case _ => abort(s"unexpected type-representing tree: ${tree.getClass}\n$tree") + } + + def typedMemberDef(tree: MemberDef): Tree = tree match { + case tree: ValDef => typedValDef(tree) + case tree: DefDef => defDefTyper(tree).typedDefDef(tree) + case tree: ClassDef => newTyper(context.makeNewScope(tree, sym)).typedClassDef(tree) + case tree: ModuleDef => newTyper(context.makeNewScope(tree, sym.moduleClass)).typedModuleDef(tree) + case tree: TypeDef => typedTypeDef(tree) + case tree: PackageDef => typedPackageDef(tree) + case _ => abort(s"unexpected member def: ${tree.getClass}\n$tree") + } + + // Trees not allowed during pattern mode. + def typedOutsidePatternMode(tree: Tree): Tree = tree match { + case tree: Block => typerWithLocalContext(context.makeNewScope(tree, context.owner))(_.typedBlock(tree, mode, pt)) + case tree: If => typedIf(tree) + case tree: TypeApply => typedTypeApply(tree) + case tree: Function => typedFunction(tree) + case tree: Match => typedVirtualizedMatch(tree) + case tree: New => typedNew(tree) + case tree: Assign => typedAssign(tree.lhs, tree.rhs) + case tree: AssignOrNamedArg => typedAssign(tree.lhs, tree.rhs) // called by NamesDefaults in silent typecheck + case tree: Super => typedSuper(tree) + case tree: Annotated => typedAnnotated(tree) + case tree: Return => typedReturn(tree) + case tree: Try => typedTry(tree) + case tree: Throw => typedThrow(tree) + case tree: ArrayValue => typedArrayValue(tree) + case tree: ApplyDynamic => typedApplyDynamic(tree) + case tree: ReferenceToBoxed => typedReferenceToBoxed(tree) + case tree: LabelDef => labelTyper(tree).typedLabelDef(tree) + case tree: DocDef => typedDocDef(tree, mode, pt) + case _ => abort(s"unexpected tree: ${tree.getClass}\n$tree") + } + + // Trees allowed in or out of pattern mode. + def typedInAnyMode(tree: Tree): Tree = tree match { + case tree: Ident => typedIdentOrWildcard(tree) + case tree: Bind => typedBind(tree) + case tree: Apply => typedApply(tree) + case tree: Select => typedSelectOrSuperCall(tree) + case tree: Literal => typedLiteral(tree) + case tree: Typed => typedTyped(tree) + case tree: This => typedThis(tree) // SI-6104 + case tree: UnApply => abort(s"unexpected UnApply $tree") // turns out UnApply never reaches here + case _ => + if (mode.inPatternMode) + typedInPatternMode(tree) + else + typedOutsidePatternMode(tree) + } + + // begin typed1 + tree match { + case tree: TypTree => typedTypTree(tree) + case tree: MemberDef => typedMemberDef(tree) + case _ => typedInAnyMode(tree) } } |