Make JetStream 2
[WebKit-https.git] / PerformanceTests / JetStream2 / WSL / TypeVariable.js
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25 "use strict";
26
27 class TypeVariable extends Type {
28     constructor(origin, name, protocol)
29     {
30         super();
31         this._origin = origin;
32         this._name = name;
33         this._protocol = protocol;
34     }
35     
36     get origin() { return this._origin; }
37     get name() { return this._name; }
38     get protocol() { return this._protocol; }
39     
40     get isPrimitive()
41     {
42         return this._protocol && this._protocol.isPrimitive;
43     }
44     
45     get isUnifiable() { return true; }
46     
47     inherits(protocol)
48     {
49         if (!protocol)
50             return {result: true};
51         if (!this.protocol)
52             return {result: false, reason: "Type variable " + this + " does not have a protocol"};
53         return this.protocol.inherits(protocol);
54     }
55     
56     typeVariableUnify(unificationContext, other)
57     {
58         if (!(other instanceof Type))
59             return false;
60         
61         return this._typeVariableUnifyImpl(unificationContext, other);
62     }
63     
64     unifyImpl(unificationContext, other)
65     {
66         return this.typeVariableUnify(unificationContext, other);
67     }
68     
69     verifyAsArgument(unificationContext)
70     {
71         let realThis = unificationContext.find(this);
72         
73         // The thing we get unified with must be a type variable that accepts a broader set of
74         // things than we do.
75         if (!(realThis instanceof TypeVariable))
76             return {result: false, reason: "Type variable argument " + this + " cannot be passed to non-type-variable parameter type " + realThis};
77         
78         if (!this.protocol) {
79             if (realThis.protocol)
80                 return {result: false, reason: "Type variable without protocol " + this + " cannot be passed to parameter type variable with protocol " + realThis.protocol};
81             return {result: true};
82         }
83         
84         let result = this.protocol.inherits(realThis.protocol);
85         if (!result.result)
86             return {result: false, reason: "Protocol " + this.protocol + " does not subsume protocol " + realThis.protocol + " (passing type " + this + " to type " + realThis + "): " + result.reason};
87         return {result: true};
88     }
89     
90     verifyAsParameter(unificationContext)
91     {
92         if (!this.protocol)
93             return {result: true};
94         let realThis = unificationContext.find(this);
95         let result = realThis.inherits(this.protocol);
96         if (!result.result)
97             return {result: false, reason: "Type " + realThis + " does not inherit protocol " + this.protocol + " (passing type " + realThis + " to type " + this + "): " + result.reason};
98         return {result: true};
99     }
100     
101     toString()
102     {
103         return this.name + (this.protocol ? ":" + this.protocol.name : "");
104     }
105 }
106