*** empty log message ***
git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@3534 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
parent
63bc3b4bdf
commit
eb93dbc9c3
|
@ -4385,11 +4385,8 @@ following definitions.
|
||||||
package scala;
|
package scala;
|
||||||
abstract class Any {
|
abstract class Any {
|
||||||
|
|
||||||
/** Reference equality */
|
/** Defined equality; abstract here */
|
||||||
final def eq(that: Any): boolean = $\ldots$
|
def equals(that: Any): boolean;
|
||||||
|
|
||||||
/** Defined equality */
|
|
||||||
def equals(that: Any): boolean = this eq that;
|
|
||||||
|
|
||||||
/** Semantic equality between values of same type */
|
/** Semantic equality between values of same type */
|
||||||
final def == (that: Any): boolean = this equals that
|
final def == (that: Any): boolean = this equals that
|
||||||
|
@ -4420,7 +4417,10 @@ abstract class Any {
|
||||||
def match[a, b](cases: a => b): b = cases(this);
|
def match[a, b](cases: a => b): b = cases(this);
|
||||||
}
|
}
|
||||||
final class AnyVal extends Any;
|
final class AnyVal extends Any;
|
||||||
class AnyRef extends Any;
|
class AnyRef extends Any {
|
||||||
|
def equals(that: Any): boolean = this eq that;
|
||||||
|
final def eq(that: Any): boolean = $\ldots$; // reference equality
|
||||||
|
}
|
||||||
trait ScalaObject extends AnyRef;
|
trait ScalaObject extends AnyRef;
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ object List {
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Parses a string which contains substrings separated by a
|
/** Parses a string which contains substrings separated by a
|
||||||
*
|
*
|
||||||
* separator character and returns a list of all substrings.
|
* separator character and returns a list of all substrings.
|
||||||
|
@ -180,6 +180,49 @@ object List {
|
||||||
sb.toString()
|
sb.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the list resulting from applying the given function <code>f</code> to
|
||||||
|
* corresponding elements of the argument lists.
|
||||||
|
*
|
||||||
|
* @param f function to apply to each pair of elements.
|
||||||
|
* @return <code>[f(a0,b0), ..., f(an,bn)]</code> if the lists are
|
||||||
|
* <code>[a0, ..., ak]</code>, <code>[b0, ..., bl]</code> and
|
||||||
|
* <code>m = min(k,l)</code>
|
||||||
|
*/
|
||||||
|
def map2[a,b,c](xs: List[a], ys: List[b], f: (a, b) => c): List[c] =
|
||||||
|
if (xs.isEmpty || ys.isEmpty) Nil
|
||||||
|
else f(xs.head, ys.head) :: map2(xs.tail, ys.tail, f);
|
||||||
|
|
||||||
|
/** Tests whether the given predicate <code>p</code> holds
|
||||||
|
* for all corresponding elements of the argument lists.
|
||||||
|
*
|
||||||
|
* @param p function to apply to each pair of elements.
|
||||||
|
* @return <code>n == 0 || (p(a0,b0) && ... && p(an,bn))]</code> if the lists are
|
||||||
|
* <code>[a0, ..., ak]</code>, <code>[b0, ..., bl]</code> and
|
||||||
|
* <code>m = min(k,l)</code>
|
||||||
|
*/
|
||||||
|
def forall2[a,b](xs: List[a], ys: List[b], f: (a, b) => boolean): boolean =
|
||||||
|
if (xs.isEmpty || ys.isEmpty) true
|
||||||
|
else f(xs.head, ys.head) && forall2(xs.tail, ys.tail, f);
|
||||||
|
|
||||||
|
/** Tests whether the given predicate <code>p</code> holds
|
||||||
|
* for some corresponding elements of the argument lists.
|
||||||
|
*
|
||||||
|
* @param p function to apply to each pair of elements.
|
||||||
|
* @return <code>n != 0 && (p(a0,b0) || ... || p(an,bn))]</code> if the lists are
|
||||||
|
* <code>[a0, ..., ak]</code>, <code>[b0, ..., bl]</code> and
|
||||||
|
* <code>m = min(k,l)</code>
|
||||||
|
*/
|
||||||
|
def exists2[a,b](xs: List[a], ys: List[b], f: (a, b) => boolean): boolean =
|
||||||
|
if (xs.isEmpty || ys.isEmpty) false
|
||||||
|
else f(xs.head, ys.head) || exists2(xs.tail, ys.tail, f);
|
||||||
|
|
||||||
|
/** Transposes a list of lists.
|
||||||
|
* pre: All element lists have the same length.
|
||||||
|
*/
|
||||||
|
def transpose[a](xss: List[List[a]]): List[List[a]] =
|
||||||
|
if (xss.head.isEmpty) List()
|
||||||
|
else (xss map (xs => xs.head)) :: transpose(xss map (xs => xs.tail));
|
||||||
|
|
||||||
/** Lists with ordered elements are ordered
|
/** Lists with ordered elements are ordered
|
||||||
*/
|
*/
|
||||||
def view[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = new Ordered[List[a]] {
|
def view[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = new Ordered[List[a]] {
|
||||||
|
@ -445,7 +488,7 @@ sealed trait List[+a] extends Seq[a] {
|
||||||
def map[b](f: a => b): List[b] = match {
|
def map[b](f: a => b): List[b] = match {
|
||||||
case Nil => Nil
|
case Nil => Nil
|
||||||
case head :: tail => f(head) :: (tail map f)
|
case head :: tail => f(head) :: (tail map f)
|
||||||
};
|
}
|
||||||
|
|
||||||
/** Apply a function to all the elements of the list, and return the
|
/** Apply a function to all the elements of the list, and return the
|
||||||
* reversed list of results. This is equivalent to a call to <code>map</code>
|
* reversed list of results. This is equivalent to a call to <code>map</code>
|
||||||
|
|
|
@ -239,6 +239,7 @@ class Parser(unit: CompilationUnit) {
|
||||||
NewArray.Tree(left, right));
|
NewArray.Tree(left, right));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def scalaDot(pos: int, name: Name): Tree =
|
def scalaDot(pos: int, name: Name): Tree =
|
||||||
make.Select(pos, make.Ident(pos, Names.scala), name);
|
make.Select(pos, make.Ident(pos, Names.scala), name);
|
||||||
|
|
||||||
|
@ -433,6 +434,29 @@ class Parser(unit: CompilationUnit) {
|
||||||
make.Apply(t.pos, t, Tree.EMPTY_ARRAY)
|
make.Apply(t.pos, t, Tree.EMPTY_ARRAY)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** make closure from tree */
|
||||||
|
def makeClosure(pos: int, tree: Tree): Tree = {
|
||||||
|
val pname = fresh();
|
||||||
|
def insertParam(tree: Tree): Tree = tree match {
|
||||||
|
case Tree$Ident(name) =>
|
||||||
|
make.Select(tree.pos, make.Ident(pos, pname), name)
|
||||||
|
case Tree$Select(qual, name) =>
|
||||||
|
make.Select(tree.pos, insertParam(qual), name)
|
||||||
|
case Tree$Apply(fn, args) =>
|
||||||
|
make.Apply(tree.pos, insertParam(fn), args)
|
||||||
|
case Tree$TypeApply(fn, args) =>
|
||||||
|
make.TypeApply(tree.pos, insertParam(fn), args)
|
||||||
|
case _ =>
|
||||||
|
syntaxError(pos, "cannot concert to closure", false);
|
||||||
|
gen.mkZeroLit(s.pos)
|
||||||
|
}
|
||||||
|
make.Function(
|
||||||
|
pos,
|
||||||
|
NewArray.ValDef(
|
||||||
|
make.ValDef(pos, Modifiers.PARAM, pname, Tree.Empty, Tree.Empty)),
|
||||||
|
insertParam(tree))
|
||||||
|
}
|
||||||
|
|
||||||
/////// OPERAND/OPERATOR STACK /////////////////////////////////////////////////
|
/////// OPERAND/OPERATOR STACK /////////////////////////////////////////////////
|
||||||
|
|
||||||
var operands = new Array[Tree](8);
|
var operands = new Array[Tree](8);
|
||||||
|
@ -818,7 +842,8 @@ class Parser(unit: CompilationUnit) {
|
||||||
* | return [Expr]
|
* | return [Expr]
|
||||||
* | [SimpleExpr `.'] Id `=' Expr
|
* | [SimpleExpr `.'] Id `=' Expr
|
||||||
* | SimpleExpr ArgumentExprs `=' Expr
|
* | SimpleExpr ArgumentExprs `=' Expr
|
||||||
* | PostfixExpr [`:' Type1]
|
* | `.' SimpleExpr
|
||||||
|
* | PostfixExpr [`:' Type1]
|
||||||
* Bindings ::= Id [`:' Type1]
|
* Bindings ::= Id [`:' Type1]
|
||||||
* | `(' [Binding {`,' Binding}] `)'
|
* | `(' [Binding {`,' Binding}] `)'
|
||||||
* Binding ::= Id [`:' Type]
|
* Binding ::= Id [`:' Type]
|
||||||
|
@ -890,7 +915,15 @@ class Parser(unit: CompilationUnit) {
|
||||||
} else if (s.token == THROW) {
|
} else if (s.token == THROW) {
|
||||||
val pos = s.skipToken();
|
val pos = s.skipToken();
|
||||||
make.Throw(pos, expr())
|
make.Throw(pos, expr())
|
||||||
} else {
|
} else if (s.token == DOT) {
|
||||||
|
val pos = s.skipToken();
|
||||||
|
if (s.token == IDENTIFIER)
|
||||||
|
makeClosure(pos, simpleExpr())
|
||||||
|
else {
|
||||||
|
syntaxError("identifier expected", true);
|
||||||
|
gen.mkZeroLit(pos);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
var t = postfixExpr();
|
var t = postfixExpr();
|
||||||
if (s.token == EQUALS) {
|
if (s.token == EQUALS) {
|
||||||
t match {
|
t match {
|
||||||
|
@ -927,7 +960,7 @@ class Parser(unit: CompilationUnit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** PostfixExpr ::= InfixExpr [Id]
|
/** PostfixExpr ::= [`.'] InfixExpr [Id]
|
||||||
* InfixExpr ::= PrefixExpr
|
* InfixExpr ::= PrefixExpr
|
||||||
* | InfixExpr Id InfixExpr
|
* | InfixExpr Id InfixExpr
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1330,6 +1330,8 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
|
||||||
clazz.getType()
|
clazz.getType()
|
||||||
else if (selftype.isSubType(clazz.getType()))
|
else if (selftype.isSubType(clazz.getType()))
|
||||||
selftype
|
selftype
|
||||||
|
else if (selftype.isSingletonType() && selftype.singleDeref().symbol().isSubClass(clazz))
|
||||||
|
selftype
|
||||||
else
|
else
|
||||||
selftype match {
|
selftype match {
|
||||||
case Type$CompoundType(parts, members) =>
|
case Type$CompoundType(parts, members) =>
|
||||||
|
@ -1342,6 +1344,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
|
||||||
Type.compoundTypeWithOwner(
|
Type.compoundTypeWithOwner(
|
||||||
clazz.owner().enclClass(), NewArray.Type(selftype, clazz.getType()), Scope.EMPTY);
|
clazz.owner().enclClass(), NewArray.Type(selftype, clazz.getType()), Scope.EMPTY);
|
||||||
}
|
}
|
||||||
|
if (global.debug) global.log("assigning self type " + selftype1);
|
||||||
sym.setInfo(selftype1);
|
sym.setInfo(selftype1);
|
||||||
|
|
||||||
this.unit = savedUnit;
|
this.unit = savedUnit;
|
||||||
|
@ -1367,7 +1370,9 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
|
||||||
}
|
}
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
if ((pt != null && pt.isStable() || (mode & QUALmode) != 0) &&
|
if ((pt != null && pt.isStable() ||
|
||||||
|
(mode & QUALmode) != 0 ||
|
||||||
|
tree.getType().symbol().isModuleClass()) &&
|
||||||
(pre != null) && pre.isStable()) {
|
(pre != null) && pre.isStable()) {
|
||||||
var sym: Symbol = tree.symbol();
|
var sym: Symbol = tree.symbol();
|
||||||
tree.getType() match {
|
tree.getType() match {
|
||||||
|
@ -1566,7 +1571,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
|
||||||
}
|
}
|
||||||
|
|
||||||
var owntype: Type = tree.getType();
|
var owntype: Type = tree.getType();
|
||||||
if ((mode & (CONSTRmode | FUNmode)) == (CONSTRmode)) {
|
if ((mode & (CONSTRmode | FUNmode)) == (CONSTRmode) && pt != Type.AnyType) {
|
||||||
owntype = owntype.instanceType();
|
owntype = owntype.instanceType();
|
||||||
// this works as for superclass constructor calls the expected
|
// this works as for superclass constructor calls the expected
|
||||||
// type `pt' is always AnyType (see transformConstrInvocations).
|
// type `pt' is always AnyType (see transformConstrInvocations).
|
||||||
|
@ -1917,7 +1922,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
|
||||||
transformConstrInvocationArgs(parents);
|
transformConstrInvocationArgs(parents);
|
||||||
if (!owner.isError()) {
|
if (!owner.isError()) {
|
||||||
validateParentClasses(
|
validateParentClasses(
|
||||||
parents, owner.info().parents(), owner.typeOfThis());
|
parents, owner.info().parents(), owner.thisType());
|
||||||
}
|
}
|
||||||
val prevContext = pushContext(templ, owner, owner.members());
|
val prevContext = pushContext(templ, owner, owner.members());
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -591,7 +591,7 @@ class DeSugarize(make: TreeFactory, copy: TreeCopier, gen: TreeGen, infer: scala
|
||||||
* It is assumed that all symbols are term symbols ==> make.Ident().
|
* It is assumed that all symbols are term symbols ==> make.Ident().
|
||||||
*/
|
*/
|
||||||
def toIdents(symbols: Array[Symbol]): Array[Tree] = {
|
def toIdents(symbols: Array[Symbol]): Array[Tree] = {
|
||||||
val idents = new Array[Tree$Ident](symbols.length);
|
val idents = new Array[Tree](symbols.length);
|
||||||
for (val i <- Iterator.range(0, symbols.length)) {
|
for (val i <- Iterator.range(0, symbols.length)) {
|
||||||
idents(i) = make.Ident(symbols(i).pos, symbols(i).name);
|
idents(i) = make.Ident(symbols(i).pos, symbols(i).name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,10 @@ public class ClosureHistory extends History {
|
||||||
for (int i = 0; i < parents.length; i++)
|
for (int i = 0; i < parents.length; i++)
|
||||||
addParents(table, parents[i]);
|
addParents(table, parents[i]);
|
||||||
return;
|
return;
|
||||||
|
case SingleType(_, _):
|
||||||
|
case ThisType(_):
|
||||||
|
addParents(table, type.singleDeref());
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
throw Debug.abort("illegal case", type);
|
throw Debug.abort("illegal case", type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -698,6 +698,15 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Is this type a s thistype or singletype?
|
||||||
|
*/
|
||||||
|
public boolean isSingletonType() {
|
||||||
|
switch (this) {
|
||||||
|
case ThisType(_): case SingleType(_, _): return true;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Is this type a reference to an object type?
|
/** Is this type a reference to an object type?
|
||||||
* todo: replace by this.isSubType(global.definitions.ANY_TYPE())?
|
* todo: replace by this.isSubType(global.definitions.ANY_TYPE())?
|
||||||
*/
|
*/
|
||||||
|
@ -708,7 +717,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
|
||||||
case ConstantType(_, _):
|
case ConstantType(_, _):
|
||||||
case CompoundType(_, _):
|
case CompoundType(_, _):
|
||||||
case TypeRef(_, _, _):
|
case TypeRef(_, _, _):
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2155,6 +2164,12 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
|
||||||
&& sym == sym1.moduleClass()
|
&& sym == sym1.moduleClass()
|
||||||
&& sym.owner().thisType().isSameAs(pre1)
|
&& sym.owner().thisType().isSameAs(pre1)
|
||||||
||
|
||
|
||||||
|
this.singleDeref().isSingletonType() &&
|
||||||
|
this.singleDeref().isSameAs(that)
|
||||||
|
||
|
||||||
|
that.singleDeref().isSingletonType() &&
|
||||||
|
this.isSameAs(that.singleDeref())
|
||||||
|
||
|
||||||
deAlias(that) != that &&
|
deAlias(that) != that &&
|
||||||
this.isSameAs(deAlias(that));
|
this.isSameAs(deAlias(that));
|
||||||
}
|
}
|
||||||
|
@ -2164,6 +2179,12 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
|
||||||
switch (that) {
|
switch (that) {
|
||||||
case SingleType(Type pre1, Symbol sym1):
|
case SingleType(Type pre1, Symbol sym1):
|
||||||
return sym == sym1 && pre.isSameAs(pre1)
|
return sym == sym1 && pre.isSameAs(pre1)
|
||||||
|
||
|
||||||
|
this.singleDeref().isSingletonType() &&
|
||||||
|
this.singleDeref().isSameAs(that)
|
||||||
|
||
|
||||||
|
that.singleDeref().isSingletonType() &&
|
||||||
|
this.isSameAs(that.singleDeref())
|
||||||
||
|
||
|
||||||
(deAlias(this) != this || deAlias(that) != that) &&
|
(deAlias(this) != this || deAlias(that) != that) &&
|
||||||
deAlias(this).isSameAs(deAlias(that));
|
deAlias(this).isSameAs(deAlias(that));
|
||||||
|
@ -2172,6 +2193,12 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
|
||||||
&& sym.moduleClass() == sym1
|
&& sym.moduleClass() == sym1
|
||||||
&& pre.isSameAs(sym1.owner().thisType())
|
&& pre.isSameAs(sym1.owner().thisType())
|
||||||
||
|
||
|
||||||
|
this.singleDeref().isSingletonType() &&
|
||||||
|
this.singleDeref().isSameAs(that)
|
||||||
|
||
|
||||||
|
that.singleDeref().isSingletonType() &&
|
||||||
|
this.isSameAs(that.singleDeref())
|
||||||
|
||
|
||||||
deAlias(this) != this &&
|
deAlias(this) != this &&
|
||||||
deAlias(this).isSameAs(that);
|
deAlias(this).isSameAs(that);
|
||||||
default:
|
default:
|
||||||
|
@ -2280,6 +2307,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//where
|
//where
|
||||||
|
|
||||||
Type deAlias(Type tp) {
|
Type deAlias(Type tp) {
|
||||||
switch (tp) {
|
switch (tp) {
|
||||||
case SingleType(_, _):
|
case SingleType(_, _):
|
||||||
|
|
|
@ -60,5 +60,9 @@ object List extends scala.AnyRef with scala.ScalaObject {
|
||||||
final def fromString(java.lang.String, scala.Char): scala.List[java.lang.String];
|
final def fromString(java.lang.String, scala.Char): scala.List[java.lang.String];
|
||||||
final def fromString(java.lang.String): scala.List[scala.Char];
|
final def fromString(java.lang.String): scala.List[scala.Char];
|
||||||
final def toString(scala.List[scala.Char]): java.lang.String;
|
final def toString(scala.List[scala.Char]): java.lang.String;
|
||||||
|
final def map2[a, b, c](scala.List[a], scala.List[b], (a, b) => c): scala.List[c];
|
||||||
|
final def forall2[a, b](scala.List[a], scala.List[b], (a, b) => scala.Boolean): scala.Boolean;
|
||||||
|
final def exists2[a, b](scala.List[a], scala.List[b], (a, b) => scala.Boolean): scala.Boolean;
|
||||||
|
final def transpose[a](scala.List[scala.List[a]]): scala.List[scala.List[a]];
|
||||||
final def view[a <% scala.Ordered[a]](a => scala.Ordered[a])(scala.List[a]): scala.Ordered[scala.List[a]]
|
final def view[a <% scala.Ordered[a]](a => scala.Ordered[a])(scala.List[a]): scala.Ordered[scala.List[a]]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
bug72.scala:5: object Set of type scala.collection.mutable.Set cannot be applied to (java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) with expected result type scala.collection.mutable.Set[java.lang.String]
|
bug72.scala:5: object Set of type scala.collection.mutable.Set.type cannot be applied to (java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) with expected result type scala.collection.mutable.Set[java.lang.String]
|
||||||
val weekDays : Set[String] = Set("Mon", "Tue", "Wed", "Thu", "Fri");
|
val weekDays : Set[String] = Set("Mon", "Tue", "Wed", "Thu", "Fri");
|
||||||
^
|
^
|
||||||
one error found
|
one error found
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
class Context {
|
||||||
|
object symswrap extends SymsWrapper {
|
||||||
|
val context: Context.this.type = Context.this
|
||||||
|
}
|
||||||
|
object typswrap extends TypsWrapper {
|
||||||
|
val context: Context.this.type = Context.this
|
||||||
|
}
|
||||||
|
object syms extends symswrap.Syms;
|
||||||
|
object typs extends typswrap.Typs;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class SymsWrapper {
|
||||||
|
val context: Context;
|
||||||
|
import context._;
|
||||||
|
|
||||||
|
class Syms: context.syms.type {
|
||||||
|
abstract class Sym: context.syms.Sym {
|
||||||
|
def typ: typs.Typ;
|
||||||
|
def sym: Sym = typ.sym;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class TypsWrapper {
|
||||||
|
val context: Context;
|
||||||
|
import context._;
|
||||||
|
|
||||||
|
class Typs: context.typs.type {
|
||||||
|
abstract class Typ {
|
||||||
|
def sym: syms.Sym;
|
||||||
|
def typ: Typ = sym.typ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
|
||||||
|
class Context {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue