diff options
Diffstat (limited to 'java/com/google/turbine/binder/lookup')
12 files changed, 93 insertions, 58 deletions
diff --git a/java/com/google/turbine/binder/lookup/CanonicalSymbolResolver.java b/java/com/google/turbine/binder/lookup/CanonicalSymbolResolver.java index 1e33d5f..d44f4e4 100644 --- a/java/com/google/turbine/binder/lookup/CanonicalSymbolResolver.java +++ b/java/com/google/turbine/binder/lookup/CanonicalSymbolResolver.java @@ -18,11 +18,13 @@ package com.google.turbine.binder.lookup; import com.google.turbine.binder.sym.ClassSymbol; import com.google.turbine.tree.Tree; +import org.jspecify.nullness.Nullable; /** Canonical type resolution. Breaks a circular dependency between binding and import handling. */ public interface CanonicalSymbolResolver extends ImportScope.ResolveFunction { /** Resolves a single member type of the given symbol by canonical name. */ @Override + @Nullable ClassSymbol resolveOne(ClassSymbol sym, Tree.Ident bit); /** Returns true if the given symbol is visible from the current package. */ diff --git a/java/com/google/turbine/binder/lookup/CompoundScope.java b/java/com/google/turbine/binder/lookup/CompoundScope.java index 11309bf..bedf775 100644 --- a/java/com/google/turbine/binder/lookup/CompoundScope.java +++ b/java/com/google/turbine/binder/lookup/CompoundScope.java @@ -18,21 +18,21 @@ package com.google.turbine.binder.lookup; import static com.google.common.base.Preconditions.checkNotNull; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.nullness.Nullable; /** A {@link Scope} that chains other scopes together. */ public class CompoundScope implements Scope { private final Scope scope; - @Nullable private final Scope base; + private final @Nullable Scope base; - private CompoundScope(Scope scope, Scope base) { + private CompoundScope(Scope scope, @Nullable Scope base) { this.scope = checkNotNull(scope); this.base = base; } @Override - public LookupResult lookup(LookupKey key) { + public @Nullable LookupResult lookup(LookupKey key) { LookupResult result = scope.lookup(key); if (result != null) { return result; diff --git a/java/com/google/turbine/binder/lookup/CompoundTopLevelIndex.java b/java/com/google/turbine/binder/lookup/CompoundTopLevelIndex.java index b41edb0..e7fa45f 100644 --- a/java/com/google/turbine/binder/lookup/CompoundTopLevelIndex.java +++ b/java/com/google/turbine/binder/lookup/CompoundTopLevelIndex.java @@ -19,7 +19,7 @@ package com.google.turbine.binder.lookup; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.ImmutableList; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.nullness.Nullable; /** A {@link TopLevelIndex} that aggregates multiple indices into one. */ // Note: this implementation doesn't detect if the indices contain incompatible information, @@ -42,9 +42,8 @@ public class CompoundTopLevelIndex implements TopLevelIndex { private final Scope scope = new Scope() { - @Nullable @Override - public LookupResult lookup(LookupKey lookupKey) { + public @Nullable LookupResult lookup(LookupKey lookupKey) { // Return the first matching symbol. for (TopLevelIndex index : indexes) { LookupResult result = index.scope().lookup(lookupKey); @@ -62,14 +61,19 @@ public class CompoundTopLevelIndex implements TopLevelIndex { } @Override - public PackageScope lookupPackage(Iterable<String> packagename) { + public @Nullable PackageScope lookupPackage(Iterable<String> packagename) { // When returning package scopes, build up a compound scope containing entries from all // indices with matching packages. PackageScope result = null; for (TopLevelIndex index : indexes) { PackageScope packageScope = index.lookupPackage(packagename); - if (packageScope != null) { - result = result == null ? packageScope : result.append(packageScope); + if (packageScope == null) { + continue; + } + if (result == null) { + result = packageScope; + } else { + result = result.append(packageScope); } } return result; diff --git a/java/com/google/turbine/binder/lookup/ImportIndex.java b/java/com/google/turbine/binder/lookup/ImportIndex.java index fd57223..bcd9366 100644 --- a/java/com/google/turbine/binder/lookup/ImportIndex.java +++ b/java/com/google/turbine/binder/lookup/ImportIndex.java @@ -31,6 +31,7 @@ import com.google.turbine.tree.Tree.Ident; import com.google.turbine.tree.Tree.ImportDecl; import java.util.HashMap; import java.util.Map; +import org.jspecify.nullness.Nullable; /** * A scope that provides entries for the single-type imports in a compilation unit. @@ -59,7 +60,7 @@ public class ImportIndex implements ImportScope { CanonicalSymbolResolver resolve, final TopLevelIndex cpi, ImmutableList<ImportDecl> imports) { - Map<String, Supplier<ImportScope>> thunks = new HashMap<>(); + Map<String, Supplier<@Nullable ImportScope>> thunks = new HashMap<>(); for (final Tree.ImportDecl i : imports) { if (i.stat() || i.wild()) { continue; @@ -67,9 +68,9 @@ public class ImportIndex implements ImportScope { thunks.put( getLast(i.type()).value(), Suppliers.memoize( - new Supplier<ImportScope>() { + new Supplier<@Nullable ImportScope>() { @Override - public ImportScope get() { + public @Nullable ImportScope get() { return namedImport(log, cpi, i, resolve); } })); @@ -84,9 +85,9 @@ public class ImportIndex implements ImportScope { thunks.putIfAbsent( last, Suppliers.memoize( - new Supplier<ImportScope>() { + new Supplier<@Nullable ImportScope>() { @Override - public ImportScope get() { + public @Nullable ImportScope get() { return staticNamedImport(log, cpi, i); } })); @@ -95,7 +96,7 @@ public class ImportIndex implements ImportScope { } /** Fully resolve the canonical name of a non-static named import. */ - private static ImportScope namedImport( + private static @Nullable ImportScope namedImport( TurbineLogWithSource log, TopLevelIndex cpi, ImportDecl i, CanonicalSymbolResolver resolve) { LookupResult result = cpi.scope().lookup(new LookupKey(i.type())); if (result == null) { @@ -119,7 +120,7 @@ public class ImportIndex implements ImportScope { }; } - private static ClassSymbol resolveNext( + private static @Nullable ClassSymbol resolveNext( TurbineLogWithSource log, CanonicalSymbolResolver resolve, ClassSymbol sym, Ident bit) { ClassSymbol next = resolve.resolveOne(sym, bit); if (next == null) { @@ -138,7 +139,7 @@ public class ImportIndex implements ImportScope { * hierarchy analysis is complete, so for now we resolve the base {@code java.util.HashMap} and * defer the rest. */ - private static ImportScope staticNamedImport( + private static @Nullable ImportScope staticNamedImport( TurbineLogWithSource log, TopLevelIndex cpi, ImportDecl i) { LookupResult base = cpi.scope().lookup(new LookupKey(i.type())); if (base == null) { @@ -148,7 +149,7 @@ public class ImportIndex implements ImportScope { } return new ImportScope() { @Override - public LookupResult lookup(LookupKey lookupKey, ResolveFunction resolve) { + public @Nullable LookupResult lookup(LookupKey lookupKey, ResolveFunction resolve) { ClassSymbol sym = (ClassSymbol) base.sym(); for (Tree.Ident bit : base.remaining()) { sym = resolve.resolveOne(sym, bit); @@ -164,7 +165,7 @@ public class ImportIndex implements ImportScope { } @Override - public LookupResult lookup(LookupKey lookup, ResolveFunction resolve) { + public @Nullable LookupResult lookup(LookupKey lookup, ResolveFunction resolve) { Supplier<ImportScope> thunk = thunks.get(lookup.first().value()); if (thunk == null) { return null; diff --git a/java/com/google/turbine/binder/lookup/ImportScope.java b/java/com/google/turbine/binder/lookup/ImportScope.java index 2e6917e..a33a8e2 100644 --- a/java/com/google/turbine/binder/lookup/ImportScope.java +++ b/java/com/google/turbine/binder/lookup/ImportScope.java @@ -18,6 +18,7 @@ package com.google.turbine.binder.lookup; import com.google.turbine.binder.sym.ClassSymbol; import com.google.turbine.tree.Tree; +import org.jspecify.nullness.Nullable; /** * A scope for imports. Non-canonical imports depend on hierarchy analysis, so to break the cycle we @@ -32,17 +33,19 @@ public interface ImportScope { */ @FunctionalInterface interface ResolveFunction { + @Nullable ClassSymbol resolveOne(ClassSymbol base, Tree.Ident name); } /** See {@link Scope#lookup(LookupKey)}. */ + @Nullable LookupResult lookup(LookupKey lookupKey, ResolveFunction resolve); /** Adds a scope to the chain, in the manner of {@link CompoundScope#append(Scope)}. */ default ImportScope append(ImportScope next) { return new ImportScope() { @Override - public LookupResult lookup(LookupKey lookupKey, ResolveFunction resolve) { + public @Nullable LookupResult lookup(LookupKey lookupKey, ResolveFunction resolve) { LookupResult result = next.lookup(lookupKey, resolve); if (result != null) { return result; @@ -60,7 +63,7 @@ public interface ImportScope { static ImportScope fromScope(Scope scope) { return new ImportScope() { @Override - public LookupResult lookup(LookupKey lookupKey, ResolveFunction resolve) { + public @Nullable LookupResult lookup(LookupKey lookupKey, ResolveFunction resolve) { return scope.lookup(lookupKey); } }; @@ -71,7 +74,7 @@ public interface ImportScope { return CompoundScope.base( new Scope() { @Override - public LookupResult lookup(LookupKey lookupKey) { + public @Nullable LookupResult lookup(LookupKey lookupKey) { return ImportScope.this.lookup(lookupKey, resolve); } }); diff --git a/java/com/google/turbine/binder/lookup/MemberImportIndex.java b/java/com/google/turbine/binder/lookup/MemberImportIndex.java index a8ecc7a..d825396 100644 --- a/java/com/google/turbine/binder/lookup/MemberImportIndex.java +++ b/java/com/google/turbine/binder/lookup/MemberImportIndex.java @@ -30,21 +30,22 @@ import com.google.turbine.tree.Tree.ImportDecl; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; +import org.jspecify.nullness.Nullable; /** An index for statically imported members, in particular constant variables. */ public class MemberImportIndex { /** A cache of resolved static imports, keyed by the simple name of the member. */ - private final Map<String, Supplier<ClassSymbol>> cache = new LinkedHashMap<>(); + private final Map<String, Supplier<@Nullable ClassSymbol>> cache = new LinkedHashMap<>(); - private final ImmutableList<Supplier<ClassSymbol>> classes; + private final ImmutableList<Supplier<@Nullable ClassSymbol>> classes; public MemberImportIndex( SourceFile source, CanonicalSymbolResolver resolve, TopLevelIndex tli, ImmutableList<ImportDecl> imports) { - ImmutableList.Builder<Supplier<ClassSymbol>> packageScopes = ImmutableList.builder(); + ImmutableList.Builder<Supplier<@Nullable ClassSymbol>> packageScopes = ImmutableList.builder(); for (ImportDecl i : imports) { if (!i.stat()) { continue; @@ -52,9 +53,9 @@ public class MemberImportIndex { if (i.wild()) { packageScopes.add( Suppliers.memoize( - new Supplier<ClassSymbol>() { + new Supplier<@Nullable ClassSymbol>() { @Override - public ClassSymbol get() { + public @Nullable ClassSymbol get() { LookupResult result = tli.scope().lookup(new LookupKey(i.type())); if (result == null) { return null; @@ -70,15 +71,18 @@ public class MemberImportIndex { cache.put( getLast(i.type()).value(), Suppliers.memoize( - new Supplier<ClassSymbol>() { + new Supplier<@Nullable ClassSymbol>() { @Override - public ClassSymbol get() { + public @Nullable ClassSymbol get() { LookupResult result = tli.scope().lookup(new LookupKey(i.type())); if (result == null) { return null; } ClassSymbol sym = (ClassSymbol) result.sym(); for (int i = 0; i < result.remaining().size() - 1; i++) { + if (sym == null) { + return null; + } sym = resolve.resolveOne(sym, result.remaining().get(i)); } return sym; @@ -107,8 +111,8 @@ public class MemberImportIndex { } /** Resolves the owner of a single-member static import of the given simple name. */ - public ClassSymbol singleMemberImport(String simpleName) { - Supplier<ClassSymbol> cachedResult = cache.get(simpleName); + public @Nullable ClassSymbol singleMemberImport(String simpleName) { + Supplier<@Nullable ClassSymbol> cachedResult = cache.get(simpleName); return cachedResult != null ? cachedResult.get() : null; } diff --git a/java/com/google/turbine/binder/lookup/PackageScope.java b/java/com/google/turbine/binder/lookup/PackageScope.java index 695e802..94e950f 100644 --- a/java/com/google/turbine/binder/lookup/PackageScope.java +++ b/java/com/google/turbine/binder/lookup/PackageScope.java @@ -18,7 +18,7 @@ package com.google.turbine.binder.lookup; import com.google.common.collect.Iterables; import com.google.turbine.binder.sym.ClassSymbol; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.nullness.Nullable; /** * A scope that corresponds to a particular package, which supports iteration over its enclosed diff --git a/java/com/google/turbine/binder/lookup/Scope.java b/java/com/google/turbine/binder/lookup/Scope.java index 12466f4..eb9f5cb 100644 --- a/java/com/google/turbine/binder/lookup/Scope.java +++ b/java/com/google/turbine/binder/lookup/Scope.java @@ -16,7 +16,7 @@ package com.google.turbine.binder.lookup; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.nullness.Nullable; /** A scope that defines types, and supports qualified name resolution. */ public interface Scope { diff --git a/java/com/google/turbine/binder/lookup/SimpleTopLevelIndex.java b/java/com/google/turbine/binder/lookup/SimpleTopLevelIndex.java index 4ec05bc..179f603 100644 --- a/java/com/google/turbine/binder/lookup/SimpleTopLevelIndex.java +++ b/java/com/google/turbine/binder/lookup/SimpleTopLevelIndex.java @@ -23,7 +23,7 @@ import com.google.turbine.binder.sym.ClassSymbol; import java.util.HashMap; import java.util.Map; import java.util.Objects; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.nullness.Nullable; /** * An index of canonical type names where all members are known statically. @@ -36,17 +36,17 @@ public class SimpleTopLevelIndex implements TopLevelIndex { /** A class symbol or package. */ public static class Node { - public Node lookup(String bit) { + public @Nullable Node lookup(String bit) { return children.get(bit); } - @Nullable private final ClassSymbol sym; + private final @Nullable ClassSymbol sym; // TODO(cushon): the set of children is typically going to be small, consider optimizing this // to use a denser representation where appropriate. private final Map<String, Node> children = new HashMap<>(); - Node(ClassSymbol sym) { + Node(@Nullable ClassSymbol sym) { this.sym = sym; } @@ -56,7 +56,7 @@ public class SimpleTopLevelIndex implements TopLevelIndex { * * @return {@code null} if an existing symbol with the same name has already been inserted. */ - private Node insert(String name, ClassSymbol sym) { + private @Nullable Node insert(String name, @Nullable ClassSymbol sym) { Node child = children.get(name); if (child != null) { if (child.sym != null) { @@ -83,7 +83,7 @@ public class SimpleTopLevelIndex implements TopLevelIndex { final Node root = new Node(null); /** Inserts a {@link ClassSymbol} into the index, creating any needed packages. */ - public boolean insert(ClassSymbol sym) { + public void insert(ClassSymbol sym) { String binaryName = sym.binaryName(); int start = 0; int end = binaryName.indexOf('/'); @@ -95,7 +95,7 @@ public class SimpleTopLevelIndex implements TopLevelIndex { // symbol), bail out. When inserting elements from the classpath, this results in the // expected first-match-wins semantics. if (curr == null) { - return false; + return; } start = end + 1; end = binaryName.indexOf('/', start); @@ -103,9 +103,9 @@ public class SimpleTopLevelIndex implements TopLevelIndex { String simpleName = binaryName.substring(start); curr = curr.insert(simpleName, sym); if (curr == null || !Objects.equals(curr.sym, sym)) { - return false; + return; } - return true; + return; } } @@ -133,8 +133,7 @@ public class SimpleTopLevelIndex implements TopLevelIndex { final Scope scope = new Scope() { @Override - @Nullable - public LookupResult lookup(LookupKey lookupKey) { + public @Nullable LookupResult lookup(LookupKey lookupKey) { Node curr = root; while (true) { curr = curr.lookup(lookupKey.first().value()); @@ -159,7 +158,7 @@ public class SimpleTopLevelIndex implements TopLevelIndex { /** Returns a {@link Scope} that performs lookups in the given qualified package name. */ @Override - public PackageScope lookupPackage(Iterable<String> packagename) { + public @Nullable PackageScope lookupPackage(Iterable<String> packagename) { Node curr = root; for (String bit : packagename) { curr = curr.lookup(bit); @@ -179,7 +178,7 @@ public class SimpleTopLevelIndex implements TopLevelIndex { } @Override - public LookupResult lookup(LookupKey lookupKey) { + public @Nullable LookupResult lookup(LookupKey lookupKey) { Node result = node.lookup(lookupKey.first().value()); if (result != null && result.sym != null) { return new LookupResult(result.sym, lookupKey); diff --git a/java/com/google/turbine/binder/lookup/TopLevelIndex.java b/java/com/google/turbine/binder/lookup/TopLevelIndex.java index a364119..049ac5c 100644 --- a/java/com/google/turbine/binder/lookup/TopLevelIndex.java +++ b/java/com/google/turbine/binder/lookup/TopLevelIndex.java @@ -16,6 +16,7 @@ package com.google.turbine.binder.lookup; +import org.jspecify.nullness.Nullable; /** * An index of canonical type names. @@ -35,5 +36,6 @@ public interface TopLevelIndex { Scope scope(); /** Returns a scope to look up members of the given package. */ + @Nullable PackageScope lookupPackage(Iterable<String> packagename); } diff --git a/java/com/google/turbine/binder/lookup/WildImportIndex.java b/java/com/google/turbine/binder/lookup/WildImportIndex.java index cfe58c7..8b4bab1 100644 --- a/java/com/google/turbine/binder/lookup/WildImportIndex.java +++ b/java/com/google/turbine/binder/lookup/WildImportIndex.java @@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableList; import com.google.turbine.binder.sym.ClassSymbol; import com.google.turbine.tree.Tree; import com.google.turbine.tree.Tree.ImportDecl; +import org.jspecify.nullness.Nullable; /** * A scope that provides best-effort lookup for on-demand imported types in a compilation unit. @@ -45,14 +46,14 @@ public class WildImportIndex implements ImportScope { CanonicalSymbolResolver importResolver, final TopLevelIndex cpi, ImmutableList<ImportDecl> imports) { - ImmutableList.Builder<Supplier<ImportScope>> packageScopes = ImmutableList.builder(); + ImmutableList.Builder<Supplier<@Nullable ImportScope>> packageScopes = ImmutableList.builder(); for (final ImportDecl i : imports) { if (i.wild()) { packageScopes.add( Suppliers.memoize( - new Supplier<ImportScope>() { + new Supplier<@Nullable ImportScope>() { @Override - public ImportScope get() { + public @Nullable ImportScope get() { if (i.stat()) { return staticOnDemandImport(cpi, i, importResolver); } else { @@ -66,7 +67,7 @@ public class WildImportIndex implements ImportScope { } /** Full resolve the type for a non-static on-demand import. */ - private static ImportScope onDemandImport( + private static @Nullable ImportScope onDemandImport( TopLevelIndex cpi, ImportDecl i, final CanonicalSymbolResolver importResolver) { ImmutableList.Builder<String> flatNames = ImmutableList.builder(); for (Tree.Ident ident : i.type()) { @@ -77,7 +78,7 @@ public class WildImportIndex implements ImportScope { // a wildcard import of a package return new ImportScope() { @Override - public LookupResult lookup(LookupKey lookupKey, ResolveFunction resolve) { + public @Nullable LookupResult lookup(LookupKey lookupKey, ResolveFunction resolve) { return packageIndex.lookup(lookupKey); } }; @@ -92,7 +93,7 @@ public class WildImportIndex implements ImportScope { } return new ImportScope() { @Override - public LookupResult lookup(LookupKey lookupKey, ResolveFunction unused) { + public @Nullable LookupResult lookup(LookupKey lookupKey, ResolveFunction unused) { return resolveMember(member, importResolver, importResolver, lookupKey); } }; @@ -103,7 +104,7 @@ public class WildImportIndex implements ImportScope { * ImportScope#staticNamedImport} for an explanation of why the possibly non-canonical part is * deferred). */ - private static ImportScope staticOnDemandImport( + private static @Nullable ImportScope staticOnDemandImport( TopLevelIndex cpi, ImportDecl i, final CanonicalSymbolResolver importResolver) { LookupResult result = cpi.scope().lookup(new LookupKey(i.type())); if (result == null) { @@ -111,7 +112,7 @@ public class WildImportIndex implements ImportScope { } return new ImportScope() { @Override - public LookupResult lookup(LookupKey lookupKey, ResolveFunction resolve) { + public @Nullable LookupResult lookup(LookupKey lookupKey, ResolveFunction resolve) { ClassSymbol member = resolveImportBase(result, resolve, importResolver); if (member == null) { return null; @@ -121,7 +122,7 @@ public class WildImportIndex implements ImportScope { }; } - private static LookupResult resolveMember( + private static @Nullable LookupResult resolveMember( ClassSymbol base, ResolveFunction resolve, CanonicalSymbolResolver importResolver, @@ -136,7 +137,7 @@ public class WildImportIndex implements ImportScope { return new LookupResult(member, lookupKey); } - static ClassSymbol resolveImportBase( + static @Nullable ClassSymbol resolveImportBase( LookupResult result, ResolveFunction resolve, CanonicalSymbolResolver importResolver) { ClassSymbol member = (ClassSymbol) result.sym(); for (Tree.Ident bit : result.remaining()) { @@ -152,7 +153,7 @@ public class WildImportIndex implements ImportScope { } @Override - public LookupResult lookup(LookupKey lookup, ResolveFunction resolve) { + public @Nullable LookupResult lookup(LookupKey lookup, ResolveFunction resolve) { for (Supplier<ImportScope> packageScope : packages) { ImportScope scope = packageScope.get(); if (scope == null) { diff --git a/java/com/google/turbine/binder/lookup/package-info.java b/java/com/google/turbine/binder/lookup/package-info.java new file mode 100644 index 0000000..7784138 --- /dev/null +++ b/java/com/google/turbine/binder/lookup/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2021 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@com.google.errorprone.annotations.CheckReturnValue +@org.jspecify.nullness.NullMarked +package com.google.turbine.binder.lookup; |