1 /*
  2  * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package jdk.internal.jextract.impl;
 27 
 28 import jdk.incubator.jextract.Declaration;
 29 import jdk.incubator.jextract.Type;
 30 import jdk.incubator.foreign.FunctionDescriptor;
 31 
 32 import java.util.Optional;
 33 import java.util.Set;
 34 
 35 class FunctionalInterfaceScanner implements Declaration.Visitor<Void, Set<FunctionDescriptor>> {
 36 
 37     private final Set<FunctionDescriptor> descriptors;
 38 
 39     FunctionalInterfaceScanner(Set<FunctionDescriptor> descriptors) {
 40         this.descriptors = descriptors;
 41     }
 42 
 43     Declaration.Scoped scan(Declaration.Scoped decl) {
 44         decl.accept(this, descriptors);
 45         return decl;
 46     }
 47 
 48     void scanType(Type t, Set<FunctionDescriptor> functionDescriptors) {
 49         t.accept(new TypeScanner(), functionDescriptors);
 50     }
 51 
 52     @Override
 53     public Void visitScoped(Declaration.Scoped d, Set<FunctionDescriptor> functionDescriptors) {
 54         d.members().forEach(m -> m.accept(this, functionDescriptors));
 55         return null;
 56     }
 57 
 58     @Override
 59     public Void visitFunction(Declaration.Function d, Set<FunctionDescriptor> functionDescriptors) {
 60         scanType(d.type().returnType(), functionDescriptors);
 61         d.parameters().forEach(p -> p.accept(this, functionDescriptors));
 62         return null;
 63     }
 64 
 65     @Override
 66     public Void visitVariable(Declaration.Variable d, Set<FunctionDescriptor> functionDescriptors) {
 67         scanType(d.type(), functionDescriptors);
 68         return null;
 69     }
 70 
 71     @Override
 72     public Void visitConstant(Declaration.Constant d, Set<FunctionDescriptor> functionDescriptors) {
 73         scanType(d.type(), functionDescriptors);
 74         return null;
 75     }
 76 
 77     static class TypeScanner implements Type.Visitor<Void, Set<FunctionDescriptor>> {
 78 
 79         @Override
 80         public Void visitPrimitive(Type.Primitive t, Set<FunctionDescriptor> functionDescriptors) {
 81             return null;
 82         }
 83 
 84         @Override
 85         public Void visitDelegated(Type.Delegated t, Set<FunctionDescriptor> functionDescriptors) {
 86             return t.type().accept(this, functionDescriptors);
 87         }
 88 
 89         @Override
 90         public Void visitFunction(Type.Function t, Set<FunctionDescriptor> functionDescriptors) {
 91             t.returnType().accept(this, functionDescriptors);
 92             t.argumentTypes().forEach(a -> a.accept(this, functionDescriptors));
 93             Optional<FunctionDescriptor> descriptor = Type.descriptorFor(t);
 94             if (descriptor.isPresent()) {
 95                 functionDescriptors.add(descriptor.get());
 96             }
 97             return null;
 98         }
 99 
100         @Override
101         public Void visitDeclared(Type.Declared t, Set<FunctionDescriptor> functionDescriptors) {
102             return null;
103         }
104 
105         @Override
106         public Void visitArray(Type.Array t, Set<FunctionDescriptor> functionDescriptors) {
107             return t.elementType().accept(this, functionDescriptors);
108         }
109 
110         @Override
111         public Void visitType(Type t, Set<FunctionDescriptor> functionDescriptors) {
112             throw new UnsupportedOperationException();
113         }
114     }
115 }