summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/models/Models.scala.xxx
blob: e95976ed19c6e48373dc7276bb797976026ecd84 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/* NSC -- new scala compiler
 * Copyright 2005 LAMP/EPFL
 * @author  Martin Odersky
 */
// $Id: Trees.scala,v 1.35 2005/11/14 16:58:21 mcdirmid Exp $
package scala.tools.nsc.models;

import scala.tools.nsc.Global;
import scala.tools.nsc.ast.Trees;
import scala.tools.nsc.symtab.Flags;
import scala.tools.nsc.symtab.Names;

[_trait_] abstract class Models {
  val global : Global;

  import global._;

  abstract class Model {
  }
  abstract class HasTree extends Model {
    var tree : Tree = _;
    def update(tree0 : Tree): Boolean = {
      tree = tree0;
      false;
    }
    def replacedBy(tree0 : Tree) : Boolean = true;
  }
  class ImportMod extends HasTree { 
    def treex = tree.asInstanceOf[Import];

    override def replacedBy(tree0 : Tree) : Boolean = if (super.replacedBy(tree0) && tree0.isInstanceOf[Import]) {
      val tree1 = tree0.asInstanceOf[Import];
      tree1.tpe == treex.tpe;
    } else false;
  }

  abstract class Composite extends Model {
    import scala.collection.mutable._;
    class Members extends HashSet[HasTree] with ObservableSet[HasTree, Members] {
      override def +=(elem: HasTree): Unit = super.+=(elem);
      override def -=(elem: HasTree): Unit = super.-=(elem);
      override def clear: Unit = super.clear;
    }
    object members extends Members;

    def isMember(tree : Tree) : Boolean = false;

    def update0(members1 : List[Tree]) : Boolean = {
      val marked = new HashSet[HasTree];
      var updated = false;
      for (val mmbr1 <- members1) {
	var found = false;
	for (val mmbr <- members) if (!found && mmbr.replacedBy(mmbr1)) {
	  found = true;
	  updated = mmbr.update(mmbr1) || updated;
	  marked += mmbr;
	}
	if (!found) {
	  updated = true;
	  val add = modelFor(mmbr1);
	  add.update(mmbr1);
	  members += (add);
	  marked += add;
	}
      }
      val sz = members.size;
      members.intersect(marked);
      updated = updated || sz < members.size;
      // check if anything was removed!
      updated;
    }
  }
  abstract class MemberMod extends HasTree {
    def treex = tree.asInstanceOf[MemberDef];
    def flags = new Flags.Flag(treex.mods0);
    def name : Name = { treex.name0; }

    override def replacedBy(tree0 : Tree) : Boolean = if (super.replacedBy(tree0) && tree0.isInstanceOf[MemberDef]) {
      val tree1 = tree0.asInstanceOf[MemberDef];
      treex.name0 == tree1.name0;
    } else false;

    override def update(tree0 : Tree): Boolean = {
      val updated = tree == null || (treex.mods0 != tree0.asInstanceOf[MemberDef].mods0);
      super.update(tree0) || updated;
    }
  }
  abstract class MemberComposite extends MemberMod with Composite;

  abstract class HasClassObjects extends Composite {
    override def isMember(tree : Tree) : Boolean = super.isMember(tree) || tree.isInstanceOf[ImplDef];
  }
  abstract class ValOrDefMod extends MemberComposite with HasClassObjects {
    def treey = tree.asInstanceOf[ValOrDefDef];
    override def replacedBy(tree0 : Tree) : Boolean = (super.replacedBy(tree0) && tree0.isInstanceOf[ValOrDefDef]);

    override def update(tree0 : Tree): Boolean = {
      val tree1 = tree0.asInstanceOf[ValOrDefDef];
      val updated = tree == null || treex.tpe != tree1.tpe;
      update0(flatten(tree1.rhs0, (tree2 : Tree) => isMember(tree2)));
      super.update(tree0) || updated;
    }
  }
  class ValMod extends ValOrDefMod { 
    def treez = tree.asInstanceOf[ValDef];
    override def replacedBy(tree0 : Tree) : Boolean = (super.replacedBy(tree0) && tree0.isInstanceOf[ValDef]);
  }
  class DefMod extends ValOrDefMod { 
    def treez = tree.asInstanceOf[DefDef];

    override def replacedBy(tree0 : Tree) : Boolean = if (super.replacedBy(tree0) && tree0.isInstanceOf[DefDef]) {
      val tree1 = tree0.asInstanceOf[DefDef];
      if (tree1.vparamss.length == treez.vparamss.length) {
	val tpz = for (val vd <- treez.vparamss) yield for (val xd <- vd) yield xd.tpe;
	val tp1 = for (val vd <- tree1.vparamss) yield for (val xd <- vd) yield xd.tpe;
	tpz == tp1;
      } else false; 
    } else false;
  }
  abstract class ImplMod extends MemberComposite with HasClassObjects {
    def treey = tree.asInstanceOf[ImplDef];
    override def replacedBy(tree0 : Tree) : Boolean = (super.replacedBy(tree0) && tree0.isInstanceOf[ImplDef]);
    override def isMember(tree : Tree) : Boolean = super.isMember(tree) || tree.isInstanceOf[ValOrDefDef] || tree.isInstanceOf[AliasTypeDef];

    override def update(tree0 : Tree): Boolean = {
      val tree1 = tree0.asInstanceOf[ImplDef];
      
      var updated = update0(tree1.impl0.body);

      // XXX: ignore parents for now!

      (super.update(tree0) || updated) && !flags.isPrivate;
    }


  }
  class  ClassMod extends ImplMod { 
    def treez = tree.asInstanceOf[ClassDef];
    override def replacedBy(tree0 : Tree) : Boolean = (super.replacedBy(tree0) && tree0.isInstanceOf[ClassDef]);

    override def update(tree0 : Tree): Boolean = {
      // XXX: type parameters and this type!


      super.update(tree0);
    }
  }
  class ObjectMod extends ImplMod { 
    def treez = tree.asInstanceOf[ModuleDef];
    override def replacedBy(tree0 : Tree) : Boolean = (super.replacedBy(tree0) && tree0.isInstanceOf[ModuleDef]);
  }
  class AliasTypeMod extends MemberMod { 
    def treey = tree.asInstanceOf[AliasTypeDef];
    override def replacedBy(tree0 : Tree) : Boolean = (super.replacedBy(tree0) && tree0.isInstanceOf[AliasTypeDef]);
  }
  class SourceMod(val unit : CompilationUnit) extends Composite with HasClassObjects {
    override def isMember(tree : Tree) : Boolean = super.isMember(tree) || tree.isInstanceOf[Import];
  }


  def flatten0(exprs : List[Tree], filter: (Tree) => Boolean) : List[Tree] = 
    for (val expr <- exprs; val t : Tree <- flatten(expr,filter)) yield t;

  def flatten(expr : Tree, filter: (Tree) => Boolean) : List[Tree] = 
    if (filter(expr)) expr :: Nil; else expr match {
      case Block(stats,last) => flatten0(stats, filter) ::: flatten(last, filter);
      case If(cond,thenp,elsep) => flatten(cond,filter) ::: flatten(thenp,filter) ::: flatten(elsep,filter);
      case Assign(lhs,rhs) => flatten(rhs,filter);
      case CaseDef(pat,guard,body) => flatten(body,filter);
      case Return(expr0) => flatten(expr0,filter);
      case  Throw(expr0) => flatten(expr0,filter);
      case Try(block,catches,finalizer) => flatten(block,filter) ::: flatten(finalizer,filter) ::: flatten0(catches, filter);
      case Match(selector,cases) => flatten(selector,filter) ::: flatten0(cases, filter);
      case Apply(fun,args) => flatten(fun,filter) ::: flatten0(args,filter); 
      case TypeApply(fun,args) => flatten(fun,filter) ::: flatten0(args,filter); 
      case _ => Nil;
    }


  def modelFor(tree: Tree): HasTree = tree match {
    case _:    ValDef => new    ValMod();
    case _:    DefDef => new    DefMod();
    case _:  ClassDef => new  ClassMod();
    case _: ModuleDef => new ObjectMod();
    case _: AliasTypeDef => new AliasTypeMod();
    case _: Import => new ImportMod();
  }

}