863531d2eab18b5c0c4cc7267c37adeabab73b24
[WebKit-https.git] / Tools / WebGPUShadingLanguageRI / 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._signatures = [];
32         this._signatureMap = new Map();
33         this._typeVariable = new TypeVariable(origin, name, null);
34         this.isPrimitive = false;
35     }
36     
37     add(signature)
38     {
39         if (!(signature instanceof ProtocolFuncDecl))
40             throw new Error("Signature isn't a ProtocolFuncDecl but a " + signature.constructor.name);
41         
42         signature.protocolDecl = this;
43         this._signatures.push(signature);
44         let overloads = this._signatureMap.get(signature.name);
45         if (!overloads)
46             this._signatureMap.set(signature.name, overloads = []);
47         overloads.push(signature);
48     }
49     
50     get signatures() { return this._signatures; }
51     signaturesByName(name) { return this._signatureMap.get(name); }
52     get typeVariable() { return this._typeVariable; }
53     
54     signaturesByNameWithTypeVariable(name, typeVariable)
55     {
56         let substitution = new Substitution([this.typeVariable], [typeVariable]);
57         let result = this.signaturesByName(name);
58         if (!result)
59             return null;
60         return result.map(signature => signature.visit(substitution));
61     }
62     
63     inherits(otherProtocol)
64     {
65         if (!otherProtocol)
66             return true;
67         
68         if (otherProtocol instanceof ProtocolRef)
69             otherProtocol = otherProtocol.protocolDecl;
70         
71         for (let otherSignature of otherProtocol.signatures) {
72             let signatures = this.signaturesByName(otherSignature.name);
73             if (!signatures)
74                 return false;
75             let overload = resolveOverloadImpl(signatures, [], otherSignature.parameterTypes, otherSignature.returnTypeForOverloadResolution);
76             if (!overload.func)
77                 return false;
78             let substitutedReturnType =
79                 overload.func.returnType.substituteToUnification(
80                     overload.func.typeParameters, overload.unificationContext);
81             if (!substitutedReturnType.equals(otherSignature.returnType))
82                 return false;
83         }
84         return true;
85     }
86     
87     hasHeir(type)
88     {
89         let substitution = new Substitution([this._typeVariable], [type]);
90         let signatures = this.signatures;
91         for (let signature of signatures) {
92             signature = signature.visit(substitution);
93             let overload = resolveOverloadImpl(signature.possibleOverloads, signature.typeParameters, signature.parameterTypes, signature.returnTyupeForOverloadResolution);
94             if (!overload.func)
95                 return false;
96             
97             let substitutedReturnType = overload.func.returnType.substituteToUnification(
98                 overload.func.typeParameters, overload.unificationContext);
99             if (!substitutedReturnType.equals(signature.returnType))
100                 return false;
101         }
102         return true;
103     }
104     
105     toString()
106     {
107         return "protocol " + this.name + " { " + this.signatures.join("; ") + "; }";
108     }
109 }
110
111