1 /* 2 * Copyright 2017 Google Inc. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.turbine.binder.lookup; 18 19 import com.google.turbine.binder.sym.ClassSymbol; 20 import com.google.turbine.tree.Tree; 21 22 /** 23 * A scope for imports. Non-canonical imports depend on hierarchy analysis, so to break the cycle we 24 * defer non-canonical resolution to a {@link ResolveFunction} that is provided once hierarchy 25 * analysis is underway. 26 */ 27 public interface ImportScope { 28 29 /** 30 * A function that performs non-canonical resolution, see {@link 31 * com.google.turbine.binder.Resolve#resolve}. 32 */ 33 @FunctionalInterface 34 interface ResolveFunction { resolveOne(ClassSymbol base, Tree.Ident name)35 ClassSymbol resolveOne(ClassSymbol base, Tree.Ident name); 36 } 37 38 /** See {@link Scope#lookup(LookupKey)}. */ lookup(LookupKey lookupKey, ResolveFunction resolve)39 LookupResult lookup(LookupKey lookupKey, ResolveFunction resolve); 40 41 /** Adds a scope to the chain, in the manner of {@link CompoundScope#append(Scope)}. */ append(ImportScope next)42 default ImportScope append(ImportScope next) { 43 return new ImportScope() { 44 @Override 45 public LookupResult lookup(LookupKey lookupKey, ResolveFunction resolve) { 46 LookupResult result = next.lookup(lookupKey, resolve); 47 if (result != null) { 48 return result; 49 } 50 return ImportScope.this.lookup(lookupKey, resolve); 51 } 52 }; 53 } 54 55 /** 56 * Creates a trivial {@link ImportScope} from a {@link Scope}, which ignores the provided {@link 57 * ResolveFunction} and calls the underlying scope's lookup method. Used to chain {@link Scope}s 58 * and {@link ImportScope}s together. 59 */ 60 static ImportScope fromScope(Scope scope) { 61 return new ImportScope() { 62 @Override 63 public LookupResult lookup(LookupKey lookupKey, ResolveFunction resolve) { 64 return scope.lookup(lookupKey); 65 } 66 }; 67 } 68 69 /** Partially applies the given {@link ResolveFunction} to this {@link ImportScope}. */ 70 default CompoundScope toScope(ResolveFunction resolve) { 71 return CompoundScope.base( 72 new Scope() { 73 @Override 74 public LookupResult lookup(LookupKey lookupKey) { 75 return ImportScope.this.lookup(lookupKey, resolve); 76 } 77 }); 78 } 79 } 80