Make JetStream 2
[WebKit-https.git] / PerformanceTests / JetStream2 / WSL / ProtocolDecl.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 ProtocolDecl extends Protocol {
28     constructor(origin, name)
29     {
30         super(origin, name);
31         this.extends = [];
32         this._signatures = [];
33         this._signatureMap = new Map();
34         this._typeVariable = new TypeVariable(origin, name, null);
35     }
36     
37     addExtends(protocol)
38     {
39         this.extends.push(protocol);
40     }
41     
42     add(signature)
43     {
44         if (!(signature instanceof ProtocolFuncDecl))
45             throw new Error("Signature isn't a ProtocolFuncDecl but a " + signature.constructor.name);
46         
47         signature.protocolDecl = this;
48         this._signatures.push(signature);
49         let overloads = this._signatureMap.get(signature.name);
50         if (!overloads)
51             this._signatureMap.set(signature.name, overloads = []);
52         overloads.push(signature);
53     }
54     
55     get signatures() { return this._signatures; }
56     signaturesByName(name) { return this._signatureMap.get(name); }
57     get typeVariable() { return this._typeVariable; }
58     
59     signaturesByNameWithTypeVariable(name, typeVariable)
60     {
61         let substitution = new Substitution([this.typeVariable], [typeVariable]);
62         let result = this.signaturesByName(name);
63         if (!result)
64             return null;
65         return result.map(signature => signature.visit(substitution));
66     }
67     
68     inherits(otherProtocol)
69     {
70         if (!otherProtocol)
71             return {result: true};
72         
73         if (otherProtocol instanceof ProtocolRef)
74             otherProtocol = otherProtocol.protocolDecl;
75         
76         for (let otherSignature of otherProtocol.signatures) {
77             let signatures = this.signaturesByName(otherSignature.name);
78             if (!signatures)
79                 return {result: false, reason: "Protocol " + this.name + " does not have a function named " + otherSignature.name + " (looking at signature " + otherSignature + ")"};
80             let overload = resolveOverloadImpl(
81                 signatures, [],
82                 otherSignature.parameterTypes,
83                 otherSignature.returnTypeForOverloadResolution);
84             if (!overload.func)
85                 return {result: false, reason: "Did not find matching signature for " + otherSignature + " in " + this.name + (overload.failures.length ? " (tried: " + overload.failures.join("; ") + ")" : "")};
86             let substitutedReturnType =
87                 overload.func.returnType.substituteToUnification(
88                     overload.func.typeParameters, overload.unificationContext);
89             if (!substitutedReturnType.equals(otherSignature.returnType))
90                 return {result: false, reason: "Return type mismatch between " + otherSignature.returnType + " and " + substitutedReturnType};
91         }
92         return {result: true};
93     }
94     
95     hasHeir(type)
96     {
97         let substitution = new Substitution([this._typeVariable], [type]);
98         let signatures = this.signatures;
99         for (let originalSignature of signatures) {
100             let signature = originalSignature.visit(substitution);
101             let overload = resolveOverloadImpl(signature.possibleOverloads, signature.typeParameters, signature.parameterTypes, signature.returnTypeForOverloadResolution);
102             if (!overload.func)
103                 return {result: false, reason: "Did not find matching signature for " + originalSignature + " (at " + originalSignature.origin.originString + ") with type " + type + (overload.failures.length ? " (tried: " + overload.failures.join("; ") + ")" : "")};
104             
105             let substitutedReturnType = overload.func.returnType.substituteToUnification(
106                 overload.func.typeParameters, overload.unificationContext);
107             if (!substitutedReturnType.equals(signature.returnType))
108                 return {result: false, reason: "At signature " + originalSignature + " (at " + originalSignature.origin.originString + "): return type mismatch between " + signature.returnType + " and " + substitutedReturnType + " in found function " + overload.func.toDeclString()};
109         }
110         return {result: true};
111     }
112     
113     toString()
114     {
115         return "protocol " + this.name + " { " + this.signatures.join("; ") + "; }";
116     }
117 }
118
119