aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2019-01-29 11:42:19 -0800
committerColin Cross <ccross@android.com>2019-01-29 11:42:35 -0800
commita8a207a9f1578d8aaf5360ad99b910bcab097b86 (patch)
tree1341c1adbe2adae484c8f3018179457ca5a39a6c
parentbcab8b65c6fa5de2d7376acb73c619942a70b624 (diff)
parent86a7c8a2f17d1ac976d94880c3123e6820f7d5cc (diff)
downloadturbine-a8a207a9f1578d8aaf5360ad99b910bcab097b86.tar.gz
Merge remote-tracking branch 'aosp/upstream-master' into master
* aosp/upstream-master: Perform best-effort unescaping of command line options Fix error reporting for resolution failures on nested annotations Don't crash on type variables used as qualifiers in const exprs Use a newer version of guava Fix an NPE in constant expression binding of malformed annotations Reformat with google-java-format Miscellaneous cleanups Report diagnostics for unterminated expressions at the beginning of the expression instead of at the end of the file, which is probably farther from the problem. Fix error reporting for import resolution errors on nested types Add flag control for the reduced classpath optimization Bug: 122929601 Test: m checkbuild Change-Id: I30c0efadd5379f668772bc047d54ccfbbce118f8
-rw-r--r--java/com/google/turbine/binder/ConstBinder.java4
-rw-r--r--java/com/google/turbine/binder/ConstEvaluator.java19
-rw-r--r--java/com/google/turbine/binder/CtSymClassBinder.java4
-rw-r--r--java/com/google/turbine/binder/JimageClassBinder.java4
-rw-r--r--java/com/google/turbine/binder/bound/TurbineClassValue.java (renamed from java/com/google/turbine/binder/bound/ClassValue.java)8
-rw-r--r--java/com/google/turbine/binder/bytecode/BytecodeBinder.java8
-rw-r--r--java/com/google/turbine/binder/bytecode/BytecodeBoundClass.java4
-rw-r--r--java/com/google/turbine/binder/lookup/ImportIndex.java15
-rw-r--r--java/com/google/turbine/binder/lookup/LookupResult.java4
-rw-r--r--java/com/google/turbine/binder/lookup/WildImportIndex.java12
-rw-r--r--java/com/google/turbine/bytecode/AnnotationWriter.java6
-rw-r--r--java/com/google/turbine/bytecode/ClassFile.java4
-rw-r--r--java/com/google/turbine/bytecode/ClassReader.java7
-rw-r--r--java/com/google/turbine/diag/TurbineError.java1
-rw-r--r--java/com/google/turbine/lower/Lower.java10
-rw-r--r--java/com/google/turbine/main/Main.java6
-rw-r--r--java/com/google/turbine/options/TurbineOptionsParser.java14
-rw-r--r--java/com/google/turbine/parse/Parser.java9
-rw-r--r--java/com/google/turbine/type/Type.java3
-rw-r--r--java/com/google/turbine/types/Canonicalize.java2
-rw-r--r--javatests/com/google/turbine/binder/BinderErrorTest.java89
-rw-r--r--javatests/com/google/turbine/binder/BinderTest.java17
-rw-r--r--javatests/com/google/turbine/binder/ClassPathBinderTest.java11
-rw-r--r--javatests/com/google/turbine/binder/JimageClassBinderTest.java3
-rw-r--r--javatests/com/google/turbine/binder/bytecode/BytecodeBoundClassTest.java6
-rw-r--r--javatests/com/google/turbine/deps/AbstractTransitiveTest.java21
-rw-r--r--javatests/com/google/turbine/deps/DependenciesTest.java34
-rw-r--r--javatests/com/google/turbine/lower/IntegrationTestSupport.java26
-rw-r--r--javatests/com/google/turbine/lower/LowerTest.java6
-rw-r--r--javatests/com/google/turbine/lower/ModuleIntegrationTest.java8
-rw-r--r--javatests/com/google/turbine/main/MainTest.java18
-rw-r--r--javatests/com/google/turbine/model/ConstTest.java14
-rw-r--r--javatests/com/google/turbine/options/TurbineOptionsTest.java38
-rw-r--r--javatests/com/google/turbine/parse/ParseErrorTest.java48
-rw-r--r--pom.xml2
35 files changed, 332 insertions, 153 deletions
diff --git a/java/com/google/turbine/binder/ConstBinder.java b/java/com/google/turbine/binder/ConstBinder.java
index e5717b2..0f989dd 100644
--- a/java/com/google/turbine/binder/ConstBinder.java
+++ b/java/com/google/turbine/binder/ConstBinder.java
@@ -20,9 +20,9 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.turbine.binder.bound.AnnotationMetadata;
-import com.google.turbine.binder.bound.ClassValue;
import com.google.turbine.binder.bound.EnumConstantValue;
import com.google.turbine.binder.bound.SourceTypeBoundClass;
+import com.google.turbine.binder.bound.TurbineClassValue;
import com.google.turbine.binder.bound.TypeBoundClass;
import com.google.turbine.binder.bound.TypeBoundClass.FieldInfo;
import com.google.turbine.binder.bound.TypeBoundClass.MethodInfo;
@@ -215,7 +215,7 @@ public class ConstBinder {
if (value.kind() != Kind.CLASS_LITERAL) {
return null;
}
- Type type = ((ClassValue) value).type();
+ Type type = ((TurbineClassValue) value).type();
if (type.tyKind() != TyKind.CLASS_TY) {
return null;
}
diff --git a/java/com/google/turbine/binder/ConstEvaluator.java b/java/com/google/turbine/binder/ConstEvaluator.java
index 2d8ce2d..0e837a4 100644
--- a/java/com/google/turbine/binder/ConstEvaluator.java
+++ b/java/com/google/turbine/binder/ConstEvaluator.java
@@ -18,12 +18,13 @@ package com.google.turbine.binder;
import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.turbine.binder.bound.AnnotationValue;
-import com.google.turbine.binder.bound.ClassValue;
import com.google.turbine.binder.bound.EnumConstantValue;
+import com.google.turbine.binder.bound.TurbineClassValue;
import com.google.turbine.binder.bound.TypeBoundClass;
import com.google.turbine.binder.bound.TypeBoundClass.FieldInfo;
import com.google.turbine.binder.bound.TypeBoundClass.MethodInfo;
@@ -35,6 +36,7 @@ import com.google.turbine.binder.lookup.MemberImportIndex;
import com.google.turbine.binder.lookup.Scope;
import com.google.turbine.binder.sym.ClassSymbol;
import com.google.turbine.binder.sym.FieldSymbol;
+import com.google.turbine.binder.sym.Symbol;
import com.google.turbine.diag.SourceFile;
import com.google.turbine.diag.TurbineError;
import com.google.turbine.diag.TurbineError.ErrorKind;
@@ -166,7 +168,7 @@ public strictfp class ConstEvaluator {
/** Evaluates a class literal. */
Const evalClassLiteral(ClassLiteral t) {
- return new ClassValue(evalClassLiteralType(t.type()));
+ return new TurbineClassValue(evalClassLiteralType(t.type()));
}
private Type evalClassLiteralType(Tree.Type type) {
@@ -203,6 +205,9 @@ public strictfp class ConstEvaluator {
if (result == null) {
throw error(classTy.position(), ErrorKind.CANNOT_RESOLVE, flat.peekFirst());
}
+ if (result.sym().symKind() != Symbol.Kind.CLASS) {
+ throw error(classTy.position(), ErrorKind.UNEXPECTED_TYPE_PARAMETER, flat.peekFirst());
+ }
ClassSymbol classSym = (ClassSymbol) result.sym();
for (Ident bit : result.remaining()) {
classSym = resolveNext(classTy.position(), classSym, bit);
@@ -949,9 +954,19 @@ public strictfp class ConstEvaluator {
private AnnotationValue evalAnno(Tree.Anno t) {
LookupResult result = scope.lookup(new LookupKey(t.name()));
+ if (result == null) {
+ throw error(
+ t.name().get(0).position(), ErrorKind.CANNOT_RESOLVE, Joiner.on(".").join(t.name()));
+ }
ClassSymbol sym = (ClassSymbol) result.sym();
for (Ident name : result.remaining()) {
sym = Resolve.resolve(env, sym, sym, name);
+ if (sym == null) {
+ throw error(name.position(), ErrorKind.CANNOT_RESOLVE, name.value());
+ }
+ }
+ if (sym == null) {
+ return null;
}
AnnoInfo annoInfo = evaluateAnnotation(new AnnoInfo(source, sym, t, null));
return new AnnotationValue(annoInfo.sym(), annoInfo.values());
diff --git a/java/com/google/turbine/binder/CtSymClassBinder.java b/java/com/google/turbine/binder/CtSymClassBinder.java
index fd2e544..d9d74ab 100644
--- a/java/com/google/turbine/binder/CtSymClassBinder.java
+++ b/java/com/google/turbine/binder/CtSymClassBinder.java
@@ -16,6 +16,8 @@
package com.google.turbine.binder;
+import static com.google.common.base.StandardSystemProperty.JAVA_HOME;
+
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
@@ -42,7 +44,7 @@ public class CtSymClassBinder {
@Nullable
public static ClassPath bind(String version) throws IOException {
- Path javaHome = Paths.get(System.getProperty("java.home"));
+ Path javaHome = Paths.get(JAVA_HOME.value());
Path ctSym = javaHome.resolve("lib/ct.sym");
if (!Files.exists(ctSym)) {
throw new IllegalStateException("lib/ct.sym does not exist in " + javaHome);
diff --git a/java/com/google/turbine/binder/JimageClassBinder.java b/java/com/google/turbine/binder/JimageClassBinder.java
index 72bcb2f..b32b8ea 100644
--- a/java/com/google/turbine/binder/JimageClassBinder.java
+++ b/java/com/google/turbine/binder/JimageClassBinder.java
@@ -16,6 +16,8 @@
package com.google.turbine.binder;
+import static com.google.common.base.StandardSystemProperty.JAVA_HOME;
+
import com.google.common.base.Joiner;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
@@ -79,7 +81,7 @@ public class JimageClassBinder {
/** Returns a platform classpath for the given JDK's jimage file. */
public static ClassPath bind(String javaHome) throws IOException {
- if (javaHome.equals(System.getProperty("java.home"))) {
+ if (javaHome.equals(JAVA_HOME.value())) {
return bindDefault();
}
FileSystem fileSystem =
diff --git a/java/com/google/turbine/binder/bound/ClassValue.java b/java/com/google/turbine/binder/bound/TurbineClassValue.java
index a75db42..df55501 100644
--- a/java/com/google/turbine/binder/bound/ClassValue.java
+++ b/java/com/google/turbine/binder/bound/TurbineClassValue.java
@@ -21,11 +21,11 @@ import com.google.turbine.type.Type;
import java.util.Objects;
/** A class literal constant. */
-public class ClassValue extends Const {
+public class TurbineClassValue extends Const {
private final Type type;
- public ClassValue(Type type) {
+ public TurbineClassValue(Type type) {
this.type = type;
}
@@ -46,11 +46,11 @@ public class ClassValue extends Const {
@Override
public int hashCode() {
- return Objects.hash(type);
+ return Objects.hashCode(type);
}
@Override
public boolean equals(Object obj) {
- return obj instanceof ClassValue && type().equals(((ClassValue) obj).type());
+ return obj instanceof TurbineClassValue && type().equals(((TurbineClassValue) obj).type());
}
}
diff --git a/java/com/google/turbine/binder/bytecode/BytecodeBinder.java b/java/com/google/turbine/binder/bytecode/BytecodeBinder.java
index e5ba343..1d2eecb 100644
--- a/java/com/google/turbine/binder/bytecode/BytecodeBinder.java
+++ b/java/com/google/turbine/binder/bytecode/BytecodeBinder.java
@@ -19,9 +19,9 @@ package com.google.turbine.binder.bytecode;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.turbine.binder.bound.AnnotationValue;
-import com.google.turbine.binder.bound.ClassValue;
import com.google.turbine.binder.bound.EnumConstantValue;
import com.google.turbine.binder.bound.ModuleInfo;
+import com.google.turbine.binder.bound.TurbineClassValue;
import com.google.turbine.binder.sym.ClassSymbol;
import com.google.turbine.binder.sym.FieldSymbol;
import com.google.turbine.binder.sym.TyVarSymbol;
@@ -29,7 +29,7 @@ import com.google.turbine.bytecode.ClassFile;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.ArrayValue;
-import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.ConstClassValue;
+import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.ConstTurbineClassValue;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.ConstValue;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.EnumConstValue;
import com.google.turbine.bytecode.ClassReader;
@@ -118,9 +118,9 @@ public class BytecodeBinder {
case ARRAY:
return bindArrayValue(type, (ArrayValue) value);
case CLASS:
- return new ClassValue(
+ return new TurbineClassValue(
bindTy(
- new SigParser(((ConstClassValue) value).className()).parseType(),
+ new SigParser(((ConstTurbineClassValue) value).className()).parseType(),
x -> {
throw new IllegalStateException(x);
}));
diff --git a/java/com/google/turbine/binder/bytecode/BytecodeBoundClass.java b/java/com/google/turbine/binder/bytecode/BytecodeBoundClass.java
index f21760b..6e882e6 100644
--- a/java/com/google/turbine/binder/bytecode/BytecodeBoundClass.java
+++ b/java/com/google/turbine/binder/bytecode/BytecodeBoundClass.java
@@ -37,7 +37,7 @@ import com.google.turbine.bytecode.ClassFile;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.ArrayValue;
-import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.ConstClassValue;
+import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.ConstTurbineClassValue;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.EnumConstValue;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.Kind;
import com.google.turbine.bytecode.ClassFile.MethodInfo.ParameterInfo;
@@ -530,7 +530,7 @@ public class BytecodeBoundClass implements BoundClass, HeaderBoundClass, TypeBou
ElementValue val = annotation.elementValuePairs().get("value");
switch (val.kind()) {
case CLASS:
- String className = ((ConstClassValue) val).className();
+ String className = ((ConstTurbineClassValue) val).className();
return new ClassSymbol(className.substring(1, className.length() - 1));
default:
break;
diff --git a/java/com/google/turbine/binder/lookup/ImportIndex.java b/java/com/google/turbine/binder/lookup/ImportIndex.java
index f28d905..afa985a 100644
--- a/java/com/google/turbine/binder/lookup/ImportIndex.java
+++ b/java/com/google/turbine/binder/lookup/ImportIndex.java
@@ -105,7 +105,10 @@ public class ImportIndex implements ImportScope {
}
ClassSymbol sym = (ClassSymbol) result.sym();
for (Tree.Ident bit : result.remaining()) {
- sym = resolveNext(log, i.position(), resolve, sym, bit);
+ sym = resolveNext(log, resolve, sym, bit);
+ if (sym == null) {
+ return null;
+ }
}
ClassSymbol resolved = sym;
return new ImportScope() {
@@ -117,15 +120,13 @@ public class ImportIndex implements ImportScope {
}
private static ClassSymbol resolveNext(
- TurbineLogWithSource log,
- int position,
- CanonicalSymbolResolver resolve,
- ClassSymbol sym,
- Ident bit) {
+ TurbineLogWithSource log, CanonicalSymbolResolver resolve, ClassSymbol sym, Ident bit) {
ClassSymbol next = resolve.resolveOne(sym, bit);
if (next == null) {
log.error(
- position, ErrorKind.SYMBOL_NOT_FOUND, new ClassSymbol(sym.binaryName() + '$' + bit));
+ bit.position(),
+ ErrorKind.SYMBOL_NOT_FOUND,
+ new ClassSymbol(sym.binaryName() + '$' + bit));
}
return next;
}
diff --git a/java/com/google/turbine/binder/lookup/LookupResult.java b/java/com/google/turbine/binder/lookup/LookupResult.java
index 7e0f737..8340386 100644
--- a/java/com/google/turbine/binder/lookup/LookupResult.java
+++ b/java/com/google/turbine/binder/lookup/LookupResult.java
@@ -16,6 +16,8 @@
package com.google.turbine.binder.lookup;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.Immutable;
import com.google.turbine.binder.sym.ClassSymbol;
@@ -45,7 +47,7 @@ public class LookupResult {
private final ImmutableList<Tree.Ident> remaining;
public LookupResult(Symbol sym, LookupKey remaining) {
- this.sym = sym;
+ this.sym = requireNonNull(sym);
this.remaining = remaining.hasNext() ? remaining.rest().simpleNames() : ImmutableList.of();
}
}
diff --git a/java/com/google/turbine/binder/lookup/WildImportIndex.java b/java/com/google/turbine/binder/lookup/WildImportIndex.java
index 043ccc5..cfe58c7 100644
--- a/java/com/google/turbine/binder/lookup/WildImportIndex.java
+++ b/java/com/google/turbine/binder/lookup/WildImportIndex.java
@@ -67,9 +67,7 @@ public class WildImportIndex implements ImportScope {
/** Full resolve the type for a non-static on-demand import. */
private static ImportScope onDemandImport(
- TopLevelIndex cpi,
- ImportDecl i,
- final CanonicalSymbolResolver importResolver) {
+ TopLevelIndex cpi, ImportDecl i, final CanonicalSymbolResolver importResolver) {
ImmutableList.Builder<String> flatNames = ImmutableList.builder();
for (Tree.Ident ident : i.type()) {
flatNames.add(ident.value());
@@ -106,9 +104,7 @@ public class WildImportIndex implements ImportScope {
* deferred).
*/
private static ImportScope staticOnDemandImport(
- TopLevelIndex cpi,
- ImportDecl i,
- final CanonicalSymbolResolver importResolver) {
+ TopLevelIndex cpi, ImportDecl i, final CanonicalSymbolResolver importResolver) {
LookupResult result = cpi.scope().lookup(new LookupKey(i.type()));
if (result == null) {
return null;
@@ -141,9 +137,7 @@ public class WildImportIndex implements ImportScope {
}
static ClassSymbol resolveImportBase(
- LookupResult result,
- ResolveFunction resolve,
- CanonicalSymbolResolver importResolver) {
+ LookupResult result, ResolveFunction resolve, CanonicalSymbolResolver importResolver) {
ClassSymbol member = (ClassSymbol) result.sym();
for (Tree.Ident bit : result.remaining()) {
member = resolve.resolveOne(member, bit);
diff --git a/java/com/google/turbine/bytecode/AnnotationWriter.java b/java/com/google/turbine/bytecode/AnnotationWriter.java
index b52cc5e..868b548 100644
--- a/java/com/google/turbine/bytecode/AnnotationWriter.java
+++ b/java/com/google/turbine/bytecode/AnnotationWriter.java
@@ -22,7 +22,7 @@ import com.google.turbine.bytecode.ClassFile.AnnotationInfo;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.AnnotationValue;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.ArrayValue;
-import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.ConstClassValue;
+import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.ConstTurbineClassValue;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.ConstValue;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.EnumConstValue;
import com.google.turbine.bytecode.ClassFile.TypeAnnotationInfo;
@@ -65,7 +65,7 @@ public class AnnotationWriter {
writeEnumElementValue((EnumConstValue) value);
break;
case CLASS:
- writeClassElementValue((ConstClassValue) value);
+ writeClassElementValue((ConstTurbineClassValue) value);
break;
case ARRAY:
writeArrayElementValue((ArrayValue) value);
@@ -123,7 +123,7 @@ public class AnnotationWriter {
output.writeShort(pool.utf8(value.constName()));
}
- private void writeClassElementValue(ConstClassValue value) {
+ private void writeClassElementValue(ConstTurbineClassValue value) {
output.writeByte('c');
output.writeShort(pool.utf8(value.className()));
}
diff --git a/java/com/google/turbine/bytecode/ClassFile.java b/java/com/google/turbine/bytecode/ClassFile.java
index 502e295..422f8c6 100644
--- a/java/com/google/turbine/bytecode/ClassFile.java
+++ b/java/com/google/turbine/bytecode/ClassFile.java
@@ -450,11 +450,11 @@ public class ClassFile {
}
/** A constant class literal value. */
- class ConstClassValue implements ElementValue {
+ class ConstTurbineClassValue implements ElementValue {
private final String className;
- public ConstClassValue(String className) {
+ public ConstTurbineClassValue(String className) {
this.className = className;
}
diff --git a/java/com/google/turbine/bytecode/ClassReader.java b/java/com/google/turbine/bytecode/ClassReader.java
index 0070527..dc5e050 100644
--- a/java/com/google/turbine/bytecode/ClassReader.java
+++ b/java/com/google/turbine/bytecode/ClassReader.java
@@ -22,7 +22,7 @@ import com.google.errorprone.annotations.CheckReturnValue;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.AnnotationValue;
-import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.ConstClassValue;
+import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.ConstTurbineClassValue;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.ConstValue;
import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue.EnumConstValue;
import com.google.turbine.bytecode.ClassFile.MethodInfo.ParameterInfo;
@@ -34,7 +34,6 @@ import com.google.turbine.bytecode.ClassFile.ModuleInfo.RequireInfo;
import com.google.turbine.bytecode.ClassFile.ModuleInfo.UseInfo;
import com.google.turbine.model.Const;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
@@ -101,7 +100,7 @@ public class ClassReader {
List<ClassFile.MethodInfo> methodinfos = readMethods(constantPool);
String signature = null;
- List<ClassFile.InnerClass> innerclasses = Collections.emptyList();
+ List<ClassFile.InnerClass> innerclasses = ImmutableList.of();
ImmutableList.Builder<ClassFile.AnnotationInfo> annotations = ImmutableList.builder();
ClassFile.ModuleInfo module = null;
int attributesCount = reader.u2();
@@ -346,7 +345,7 @@ public class ClassReader {
{
int classInfoIndex = reader.u2();
String className = constantPool.utf8(classInfoIndex);
- return new ConstClassValue(className);
+ return new ConstTurbineClassValue(className);
}
case '@':
return new AnnotationValue(readAnnotation(constantPool));
diff --git a/java/com/google/turbine/diag/TurbineError.java b/java/com/google/turbine/diag/TurbineError.java
index e13eb44..b8b2a54 100644
--- a/java/com/google/turbine/diag/TurbineError.java
+++ b/java/com/google/turbine/diag/TurbineError.java
@@ -30,6 +30,7 @@ public class TurbineError extends Error {
UNEXPECTED_EOF("unexpected end of input"),
UNTERMINATED_STRING("unterminated string literal"),
UNTERMINATED_CHARACTER_LITERAL("unterminated char literal"),
+ UNTERMINATED_EXPRESSION("unterminated expression, expected ';' not found"),
EMPTY_CHARACTER_LITERAL("empty char literal"),
EXPECTED_TOKEN("expected token %s"),
INVALID_LITERAL("invalid literal: %s"),
diff --git a/java/com/google/turbine/lower/Lower.java b/java/com/google/turbine/lower/Lower.java
index 99b5627..97fbd6e 100644
--- a/java/com/google/turbine/lower/Lower.java
+++ b/java/com/google/turbine/lower/Lower.java
@@ -25,7 +25,6 @@ import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.turbine.binder.bound.AnnotationValue;
-import com.google.turbine.binder.bound.ClassValue;
import com.google.turbine.binder.bound.EnumConstantValue;
import com.google.turbine.binder.bound.ModuleInfo.ExportInfo;
import com.google.turbine.binder.bound.ModuleInfo.OpenInfo;
@@ -34,6 +33,7 @@ import com.google.turbine.binder.bound.ModuleInfo.RequireInfo;
import com.google.turbine.binder.bound.ModuleInfo.UseInfo;
import com.google.turbine.binder.bound.SourceModuleInfo;
import com.google.turbine.binder.bound.SourceTypeBoundClass;
+import com.google.turbine.binder.bound.TurbineClassValue;
import com.google.turbine.binder.bound.TypeBoundClass;
import com.google.turbine.binder.bound.TypeBoundClass.FieldInfo;
import com.google.turbine.binder.bound.TypeBoundClass.MethodInfo;
@@ -79,7 +79,6 @@ import com.google.turbine.types.Erasure;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Deque;
import java.util.LinkedHashSet;
import java.util.List;
@@ -373,7 +372,7 @@ public class Lower {
private ClassFile.FieldInfo lowerField(FieldInfo f) {
final String name = f.name();
- Function<TyVarSymbol, TyVarInfo> tenv = new TyVarEnv(Collections.emptyMap());
+ Function<TyVarSymbol, TyVarInfo> tenv = new TyVarEnv(ImmutableMap.of());
String desc = SigWriter.type(sig.signature(Erasure.erase(f.type(), tenv)));
String signature = sig.fieldSignature(f.type());
@@ -543,8 +542,9 @@ public class Lower {
switch (value.kind()) {
case CLASS_LITERAL:
{
- ClassValue classValue = (ClassValue) value;
- return new ElementValue.ConstClassValue(SigWriter.type(sig.signature(classValue.type())));
+ TurbineClassValue classValue = (TurbineClassValue) value;
+ return new ElementValue.ConstTurbineClassValue(
+ SigWriter.type(sig.signature(classValue.type())));
}
case ENUM_CONSTANT:
{
diff --git a/java/com/google/turbine/main/Main.java b/java/com/google/turbine/main/Main.java
index 03a68ce..34421e1 100644
--- a/java/com/google/turbine/main/Main.java
+++ b/java/com/google/turbine/main/Main.java
@@ -16,10 +16,12 @@
package com.google.turbine.main;
+import static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableList;
import com.google.common.hash.Hashing;
+import com.google.common.io.MoreFiles;
import com.google.turbine.binder.Binder;
import com.google.turbine.binder.Binder.BindingResult;
import com.google.turbine.binder.ClassPath;
@@ -145,7 +147,7 @@ public class Main {
if (options.release().isPresent()) {
String release = options.release().get();
- if (release.equals(System.getProperty("java.specification.version"))) {
+ if (release.equals(JAVA_SPECIFICATION_VERSION.value())) {
// if --release matches the host JDK, use its jimage instead of ct.sym
return JimageClassBinder.bindDefault();
}
@@ -172,7 +174,7 @@ public class Main {
ImmutableList.Builder<CompUnit> units = ImmutableList.builder();
for (String source : options.sources()) {
Path path = Paths.get(source);
- units.add(Parser.parse(new SourceFile(source, new String(Files.readAllBytes(path), UTF_8))));
+ units.add(Parser.parse(new SourceFile(source, MoreFiles.asCharSource(path, UTF_8).read())));
}
for (String sourceJar : options.sourceJars()) {
for (Zip.Entry ze : new Zip.ZipIterable(Paths.get(sourceJar))) {
diff --git a/java/com/google/turbine/options/TurbineOptionsParser.java b/java/com/google/turbine/options/TurbineOptionsParser.java
index 2976285..5b1f326 100644
--- a/java/com/google/turbine/options/TurbineOptionsParser.java
+++ b/java/com/google/turbine/options/TurbineOptionsParser.java
@@ -16,6 +16,7 @@
package com.google.turbine.options;
+import static com.google.common.base.Preconditions.checkArgument;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.base.CharMatcher;
@@ -116,6 +117,12 @@ public class TurbineOptionsParser {
case "--nojavac_fallback":
builder.setJavacFallback(false);
break;
+ case "--reduce_classpath":
+ builder.setShouldReduceClassPath(true);
+ break;
+ case "--noreduce_classpath":
+ builder.setShouldReduceClassPath(false);
+ break;
case "--help":
builder.setHelp(true);
break;
@@ -138,6 +145,13 @@ public class TurbineOptionsParser {
if (arg.isEmpty()) {
continue;
}
+ if (arg.charAt(0) == '\'') {
+ // perform best-effort unescaping as a concession to ninja, see:
+ // https://android.googlesource.com/platform/external/ninja/+/6f903faaf5488dc052ffc4e3e0b12757b426e088/src/util.cc#274
+ checkArgument(arg.charAt(arg.length() - 1) == '\'', arg);
+ arg = arg.substring(1, arg.length() - 1);
+ checkArgument(!arg.contains("'"), arg);
+ }
if (arg.startsWith("@@")) {
argumentDeque.addLast(arg.substring(1));
} else if (arg.startsWith("@")) {
diff --git a/java/com/google/turbine/parse/Parser.java b/java/com/google/turbine/parse/Parser.java
index ba76659..dd45b0d 100644
--- a/java/com/google/turbine/parse/Parser.java
+++ b/java/com/google/turbine/parse/Parser.java
@@ -20,6 +20,7 @@ import static com.google.turbine.parse.Token.COMMA;
import static com.google.turbine.parse.Token.INTERFACE;
import static com.google.turbine.parse.Token.LPAREN;
import static com.google.turbine.parse.Token.RPAREN;
+import static com.google.turbine.parse.Token.SEMI;
import static com.google.turbine.tree.TurbineModifier.PROTECTED;
import static com.google.turbine.tree.TurbineModifier.PUBLIC;
@@ -812,6 +813,7 @@ public class Parser {
token = initializerParser.token;
boolean first = true;
+ int expressionStart = pos;
for (List<SavedToken> bit : bits) {
IteratorLexer lexer = new IteratorLexer(this.lexer.source(), bit.iterator());
Parser parser = new Parser(lexer);
@@ -823,12 +825,17 @@ public class Parser {
Type ty = baseTy;
ty = parser.extraDims(ty);
// TODO(cushon): skip more fields that are definitely non-const
- Expression init = new ConstExpressionParser(lexer, lexer.next()).expression();
+ ConstExpressionParser constExpressionParser = new ConstExpressionParser(lexer, lexer.next());
+ expressionStart = lexer.position();
+ Expression init = constExpressionParser.expression();
if (init != null && init.kind() == Tree.Kind.ARRAY_INIT) {
init = null;
}
result.add(new VarDecl(pos, access, annos, ty, name, Optional.ofNullable(init)));
}
+ if (token != SEMI) {
+ throw TurbineError.format(lexer.source(), expressionStart, ErrorKind.UNTERMINATED_EXPRESSION);
+ }
eat(Token.SEMI);
return result.build();
}
diff --git a/java/com/google/turbine/type/Type.java b/java/com/google/turbine/type/Type.java
index 3bf47d6..8950ec0 100644
--- a/java/com/google/turbine/type/Type.java
+++ b/java/com/google/turbine/type/Type.java
@@ -19,6 +19,7 @@ package com.google.turbine.type;
import com.google.auto.value.AutoValue;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
import com.google.turbine.binder.sym.ClassSymbol;
import com.google.turbine.binder.sym.TyVarSymbol;
import com.google.turbine.model.TurbineConstantTypeKind;
@@ -100,7 +101,7 @@ public interface Type {
/** The class symbol. */
public ClassSymbol sym() {
- return classes().get(classes().size() - 1).sym();
+ return Iterables.getLast(classes()).sym();
}
@Override
diff --git a/java/com/google/turbine/types/Canonicalize.java b/java/com/google/turbine/types/Canonicalize.java
index d3328b7..a8861da 100644
--- a/java/com/google/turbine/types/Canonicalize.java
+++ b/java/com/google/turbine/types/Canonicalize.java
@@ -157,7 +157,7 @@ public class Canonicalize {
private Collection<ClassTy.SimpleClassTy> lexicalBase(ClassSymbol first, ClassSymbol owner) {
if ((getInfo(first).access() & TurbineFlag.ACC_STATIC) == TurbineFlag.ACC_STATIC) {
- return Collections.emptyList();
+ return ImmutableList.of();
}
ClassSymbol canonOwner = getInfo(first).owner();
Deque<ClassTy.SimpleClassTy> result = new ArrayDeque<>();
diff --git a/javatests/com/google/turbine/binder/BinderErrorTest.java b/javatests/com/google/turbine/binder/BinderErrorTest.java
index f6fb317..5a4d97e 100644
--- a/javatests/com/google/turbine/binder/BinderErrorTest.java
+++ b/javatests/com/google/turbine/binder/BinderErrorTest.java
@@ -26,7 +26,6 @@ import com.google.turbine.diag.TurbineError;
import com.google.turbine.parse.Parser;
import com.google.turbine.tree.Tree.CompUnit;
import java.util.Arrays;
-import java.util.Collections;
import java.util.Optional;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -180,7 +179,7 @@ public class BinderErrorTest {
{
"<>:2: error: symbol not found java.util.List$NoSuch", //
"import java.util.List.NoSuch;",
- " ^",
+ " ^",
"<>:3: error: could not resolve NoSuch",
"public class Test extends NoSuch {",
" ^",
@@ -488,6 +487,88 @@ public class BinderErrorTest {
" ^",
},
},
+ {
+ {
+ "package p;", //
+ "import java.util.List.NoSuchAnno;",
+ "@NoSuchAnno",
+ "public class Test {",
+ "}",
+ },
+ {
+ "<>:2: error: symbol not found java.util.List$NoSuchAnno",
+ "import java.util.List.NoSuchAnno;",
+ " ^",
+ "<>:3: error: could not resolve NoSuchAnno",
+ "@NoSuchAnno",
+ " ^",
+ },
+ },
+ {
+ {
+ "package p;", //
+ "import java.lang.annotation.Retention;",
+ "import java.lang.annotation.RetentionPolicy;",
+ "@Retention(@RetentionPolicy.RUNTIME)",
+ "public @interface A {",
+ "}",
+ },
+ {
+ "<>:4: error: could not resolve RUNTIME",
+ "@Retention(@RetentionPolicy.RUNTIME)",
+ " ^",
+ },
+ },
+ {
+ {
+ "@interface Param {",
+ " Class<?> type();",
+ "}",
+ "class Foo<T> {",
+ " @Param(type = T.class)",
+ " public void bar() {}",
+ "}",
+ },
+ {
+ "<>:5: error: unexpected type parameter T",
+ " @Param(type = T.class)",
+ " ^",
+ },
+ },
+ {
+ {
+ "class One {",
+ " @interface A {", //
+ " B[] b();",
+ " }",
+ " @interface B {}",
+ "}",
+ "@One.A(b = {@B})",
+ "class T {}",
+ },
+ {
+ "<>:7: error: could not resolve B", //
+ "@One.A(b = {@B})",
+ " ^",
+ },
+ },
+ {
+ {
+ "class One {",
+ " @interface A {", //
+ " B[] b();",
+ " }",
+ " @interface B {}",
+ "}",
+ "@One.A(b = {@One.NoSuch})",
+ "class T {}",
+ },
+ {
+ "<>:7: error: could not resolve NoSuch", //
+ "@One.A(b = {@One.NoSuch})",
+ " ^",
+ },
+ }
};
return Arrays.asList((Object[][]) testCases);
}
@@ -505,13 +586,13 @@ public class BinderErrorTest {
try {
Binder.bind(
ImmutableList.of(parseLines(source)),
- ClassPathBinder.bindClasspath(Collections.emptyList()),
+ ClassPathBinder.bindClasspath(ImmutableList.of()),
TURBINE_BOOTCLASSPATH,
/* moduleVersion=*/ Optional.empty())
.units();
fail(Joiner.on('\n').join(source));
} catch (TurbineError e) {
- assertThat(e.getMessage()).isEqualTo(lines(expected));
+ assertThat(e).hasMessageThat().isEqualTo(lines(expected));
}
}
diff --git a/javatests/com/google/turbine/binder/BinderTest.java b/javatests/com/google/turbine/binder/BinderTest.java
index 8bf4cd3..4b1e890 100644
--- a/javatests/com/google/turbine/binder/BinderTest.java
+++ b/javatests/com/google/turbine/binder/BinderTest.java
@@ -37,7 +37,6 @@ import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -76,7 +75,7 @@ public class BinderTest {
ImmutableMap<ClassSymbol, SourceTypeBoundClass> bound =
Binder.bind(
units,
- ClassPathBinder.bindClasspath(Collections.emptyList()),
+ ClassPathBinder.bindClasspath(ImmutableList.of()),
TURBINE_BOOTCLASSPATH,
/* moduleVersion=*/ Optional.empty())
.units();
@@ -122,7 +121,7 @@ public class BinderTest {
ImmutableMap<ClassSymbol, SourceTypeBoundClass> bound =
Binder.bind(
units,
- ClassPathBinder.bindClasspath(Collections.emptyList()),
+ ClassPathBinder.bindClasspath(ImmutableList.of()),
TURBINE_BOOTCLASSPATH,
/* moduleVersion=*/ Optional.empty())
.units();
@@ -162,7 +161,7 @@ public class BinderTest {
ImmutableMap<ClassSymbol, SourceTypeBoundClass> bound =
Binder.bind(
units,
- ClassPathBinder.bindClasspath(Collections.emptyList()),
+ ClassPathBinder.bindClasspath(ImmutableList.of()),
TURBINE_BOOTCLASSPATH,
/* moduleVersion=*/ Optional.empty())
.units();
@@ -192,12 +191,12 @@ public class BinderTest {
try {
Binder.bind(
units,
- ClassPathBinder.bindClasspath(Collections.emptyList()),
+ ClassPathBinder.bindClasspath(ImmutableList.of()),
TURBINE_BOOTCLASSPATH,
/* moduleVersion=*/ Optional.empty());
fail();
} catch (TurbineError e) {
- assertThat(e.getMessage()).contains("cycle in class hierarchy: a.A -> b.B -> a.A");
+ assertThat(e).hasMessageThat().contains("cycle in class hierarchy: a.A -> b.B -> a.A");
}
}
@@ -213,7 +212,7 @@ public class BinderTest {
ImmutableMap<ClassSymbol, SourceTypeBoundClass> bound =
Binder.bind(
units,
- ClassPathBinder.bindClasspath(Collections.emptyList()),
+ ClassPathBinder.bindClasspath(ImmutableList.of()),
TURBINE_BOOTCLASSPATH,
/* moduleVersion=*/ Optional.empty())
.units();
@@ -242,7 +241,7 @@ public class BinderTest {
ImmutableMap<ClassSymbol, SourceTypeBoundClass> bound =
Binder.bind(
units,
- ClassPathBinder.bindClasspath(Collections.emptyList()),
+ ClassPathBinder.bindClasspath(ImmutableList.of()),
TURBINE_BOOTCLASSPATH,
/* moduleVersion=*/ Optional.empty())
.units();
@@ -306,7 +305,7 @@ public class BinderTest {
ImmutableMap<ClassSymbol, SourceTypeBoundClass> bound =
Binder.bind(
units,
- ClassPathBinder.bindClasspath(Collections.emptyList()),
+ ClassPathBinder.bindClasspath(ImmutableList.of()),
TURBINE_BOOTCLASSPATH,
/* moduleVersion=*/ Optional.empty())
.units();
diff --git a/javatests/com/google/turbine/binder/ClassPathBinderTest.java b/javatests/com/google/turbine/binder/ClassPathBinderTest.java
index 0b063d4..3f41706 100644
--- a/javatests/com/google/turbine/binder/ClassPathBinderTest.java
+++ b/javatests/com/google/turbine/binder/ClassPathBinderTest.java
@@ -27,6 +27,7 @@ import static org.junit.Assert.fail;
import com.google.common.base.VerifyException;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;
+import com.google.common.io.MoreFiles;
import com.google.turbine.binder.bound.EnumConstantValue;
import com.google.turbine.binder.bound.TypeBoundClass;
import com.google.turbine.binder.bytecode.BytecodeBoundClass;
@@ -43,7 +44,6 @@ import com.google.turbine.type.AnnoInfo;
import com.google.turbine.type.Type.ClassTy;
import java.io.IOError;
import java.io.IOException;
-import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.Rule;
import org.junit.Test;
@@ -85,7 +85,7 @@ public class ClassPathBinderTest {
.isEqualTo(TurbineTyKind.ANNOTATION);
c = env.get(new ClassSymbol("java/util/ArrayList"));
- assertThat((c.access() & TurbineFlag.ACC_PUBLIC) == TurbineFlag.ACC_PUBLIC).isTrue();
+ assertThat((c.access() & TurbineFlag.ACC_PUBLIC)).isEqualTo(TurbineFlag.ACC_PUBLIC);
assertThat(c.superclass()).isEqualTo(new ClassSymbol("java/util/AbstractList"));
assertThat(c.interfaces()).contains(new ClassSymbol("java/util/List"));
assertThat(c.owner()).isNull();
@@ -143,7 +143,8 @@ public class ClassPathBinderTest {
c.owner();
fail();
} catch (VerifyException e) {
- assertThat(e.getMessage())
+ assertThat(e)
+ .hasMessageThat()
.contains("expected class data for java/util/List, saw java/util/ArrayList instead");
}
}
@@ -151,13 +152,13 @@ public class ClassPathBinderTest {
@Test
public void nonJarFile() throws Exception {
Path lib = temporaryFolder.newFile("NOT_A_JAR").toPath();
- Files.write(lib, "hello".getBytes(UTF_8));
+ MoreFiles.asCharSink(lib, UTF_8).write("hello");
try {
ClassPathBinder.bindClasspath(ImmutableList.of(lib));
fail();
} catch (IOException e) {
- assertThat(e.getMessage()).contains("NOT_A_JAR");
+ assertThat(e).hasMessageThat().contains("NOT_A_JAR");
}
}
}
diff --git a/javatests/com/google/turbine/binder/JimageClassBinderTest.java b/javatests/com/google/turbine/binder/JimageClassBinderTest.java
index bbcb245..11d6823 100644
--- a/javatests/com/google/turbine/binder/JimageClassBinderTest.java
+++ b/javatests/com/google/turbine/binder/JimageClassBinderTest.java
@@ -16,6 +16,7 @@
package com.google.turbine.binder;
+import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_VERSION;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.truth.Truth.assertThat;
@@ -34,7 +35,7 @@ import org.junit.runners.JUnit4;
public class JimageClassBinderTest {
@Test
public void testDefaultJimage() throws IOException {
- if (Double.parseDouble(System.getProperty("java.class.version")) < 53) {
+ if (Double.parseDouble(JAVA_CLASS_VERSION.value()) < 53) {
// only run on JDK 9 and later
return;
}
diff --git a/javatests/com/google/turbine/binder/bytecode/BytecodeBoundClassTest.java b/javatests/com/google/turbine/binder/bytecode/BytecodeBoundClassTest.java
index 4e3ec9a..2a0de48 100644
--- a/javatests/com/google/turbine/binder/bytecode/BytecodeBoundClassTest.java
+++ b/javatests/com/google/turbine/binder/bytecode/BytecodeBoundClassTest.java
@@ -24,7 +24,7 @@ import static java.util.Objects.requireNonNull;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.ByteStreams;
-import com.google.turbine.binder.bound.ClassValue;
+import com.google.turbine.binder.bound.TurbineClassValue;
import com.google.turbine.binder.bound.TypeBoundClass;
import com.google.turbine.binder.bound.TypeBoundClass.MethodInfo;
import com.google.turbine.binder.env.CompoundEnv;
@@ -110,9 +110,9 @@ public class BytecodeBoundClassTest {
BytecodeBoundClass c = getBytecodeBoundClass(VoidAnno.class);
assertThat(c.methods()).hasSize(2);
- assertThat(((ClassValue) c.methods().get(0).defaultValue()).type().tyKind())
+ assertThat(((TurbineClassValue) c.methods().get(0).defaultValue()).type().tyKind())
.isEqualTo(Type.TyKind.VOID_TY);
- assertThat(((ClassValue) c.methods().get(1).defaultValue()).type().tyKind())
+ assertThat(((TurbineClassValue) c.methods().get(1).defaultValue()).type().tyKind())
.isEqualTo(Type.TyKind.ARRAY_TY);
}
diff --git a/javatests/com/google/turbine/deps/AbstractTransitiveTest.java b/javatests/com/google/turbine/deps/AbstractTransitiveTest.java
index 1bd9349..4cb8adf 100644
--- a/javatests/com/google/turbine/deps/AbstractTransitiveTest.java
+++ b/javatests/com/google/turbine/deps/AbstractTransitiveTest.java
@@ -145,17 +145,16 @@ public abstract class AbstractTransitiveTest {
Path libc = temporaryFolder.newFolder().toPath().resolve("out.jar");
List<String> sources =
new SourceBuilder()
- .addSourceLines(
- "c/C.java",
- "package c;",
- "public class C extends b.B {",
- " @Anno(x = 2) static final Inner i; // a.A$Inner ",
- " static final int X = CONST; // a.A#CONST",
- "}")
- .build()
- .stream()
- .map(Path::toString)
- .collect(toImmutableList());
+ .addSourceLines(
+ "c/C.java",
+ "package c;",
+ "public class C extends b.B {",
+ " @Anno(x = 2) static final Inner i; // a.A$Inner ",
+ " static final int X = CONST; // a.A#CONST",
+ "}")
+ .build().stream()
+ .map(Path::toString)
+ .collect(toImmutableList());
boolean ok =
Main.compile(
optionsWithBootclasspath()
diff --git a/javatests/com/google/turbine/deps/DependenciesTest.java b/javatests/com/google/turbine/deps/DependenciesTest.java
index 4c2362f..b1da209 100644
--- a/javatests/com/google/turbine/deps/DependenciesTest.java
+++ b/javatests/com/google/turbine/deps/DependenciesTest.java
@@ -22,6 +22,7 @@ import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Streams;
import com.google.turbine.binder.Binder;
import com.google.turbine.binder.Binder.BindingResult;
import com.google.turbine.binder.ClassPathBinder;
@@ -47,7 +48,6 @@ import java.util.Optional;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -116,7 +116,7 @@ public class DependenciesTest {
}
private Map<Path, DepsProto.Dependency.Kind> depsMap(DepsProto.Dependencies deps) {
- return StreamSupport.stream(deps.getDependencyList().spliterator(), false)
+ return Streams.stream(deps.getDependencyList())
.collect(Collectors.toMap(d -> Paths.get(d.getPath()), DepsProto.Dependency::getKind));
}
@@ -130,7 +130,7 @@ public class DependenciesTest {
.addSourceLines("Test.java", "class Test extends A {}")
.run();
- assertThat(depsMap(deps)).isEqualTo(ImmutableMap.of(liba, DepsProto.Dependency.Kind.EXPLICIT));
+ assertThat(depsMap(deps)).containsExactly(liba, DepsProto.Dependency.Kind.EXPLICIT);
}
@Test
@@ -156,7 +156,7 @@ public class DependenciesTest {
.addSourceLines("Test.java", "class Test extends B {}")
.run();
- assertThat(depsMap(deps)).isEqualTo(ImmutableMap.of(libb, DepsProto.Dependency.Kind.EXPLICIT));
+ assertThat(depsMap(deps)).containsExactly(libb, DepsProto.Dependency.Kind.EXPLICIT);
}
@Test
@@ -184,10 +184,8 @@ public class DependenciesTest {
"}")
.run();
assertThat(depsMap(deps))
- .isEqualTo(
- ImmutableMap.of(
- libb, DepsProto.Dependency.Kind.EXPLICIT,
- liba, DepsProto.Dependency.Kind.EXPLICIT));
+ .containsExactly(
+ libb, DepsProto.Dependency.Kind.EXPLICIT, liba, DepsProto.Dependency.Kind.EXPLICIT);
}
@Test
@@ -227,11 +225,13 @@ public class DependenciesTest {
"class Test extends B {}")
.run();
assertThat(depsMap(deps))
- .isEqualTo(
- ImmutableMap.of(
- libi, DepsProto.Dependency.Kind.EXPLICIT,
- libb, DepsProto.Dependency.Kind.EXPLICIT,
- liba, DepsProto.Dependency.Kind.EXPLICIT));
+ .containsExactly(
+ libi,
+ DepsProto.Dependency.Kind.EXPLICIT,
+ libb,
+ DepsProto.Dependency.Kind.EXPLICIT,
+ liba,
+ DepsProto.Dependency.Kind.EXPLICIT);
}
{
// partial classpath
@@ -244,10 +244,8 @@ public class DependenciesTest {
"class Test extends B {}")
.run();
assertThat(depsMap(deps))
- .isEqualTo(
- ImmutableMap.of(
- libb, DepsProto.Dependency.Kind.EXPLICIT,
- liba, DepsProto.Dependency.Kind.EXPLICIT));
+ .containsExactly(
+ libb, DepsProto.Dependency.Kind.EXPLICIT, liba, DepsProto.Dependency.Kind.EXPLICIT);
}
}
@@ -260,7 +258,7 @@ public class DependenciesTest {
ImmutableSet<String> directJars = ImmutableSet.of();
ImmutableList<String> depsArtifacts = ImmutableList.of();
assertThat(Dependencies.reduceClasspath(classpath, directJars, depsArtifacts))
- .isEqualTo(classpath);
+ .containsExactlyElementsIn(classpath);
}
@Test
diff --git a/javatests/com/google/turbine/lower/IntegrationTestSupport.java b/javatests/com/google/turbine/lower/IntegrationTestSupport.java
index c039241..680b073 100644
--- a/javatests/com/google/turbine/lower/IntegrationTestSupport.java
+++ b/javatests/com/google/turbine/lower/IntegrationTestSupport.java
@@ -25,6 +25,7 @@ import static java.util.stream.Collectors.toList;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
+import com.google.common.io.MoreFiles;
import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;
import com.google.turbine.binder.Binder;
@@ -135,12 +136,10 @@ public class IntegrationTestSupport {
if (!isDeprecated(n.visibleAnnotations)) {
n.access &= ~Opcodes.ACC_DEPRECATED;
}
- n.methods
- .stream()
+ n.methods.stream()
.filter(m -> !isDeprecated(m.visibleAnnotations))
.forEach(m -> m.access &= ~Opcodes.ACC_DEPRECATED);
- n.fields
- .stream()
+ n.fields.stream()
.filter(f -> !isDeprecated(f.visibleAnnotations))
.forEach(f -> f.access &= ~Opcodes.ACC_DEPRECATED);
}
@@ -188,21 +187,18 @@ public class IntegrationTestSupport {
/** Remove elements that are omitted by turbine, e.g. private and synthetic members. */
private static void removeImplementation(ClassNode n) {
n.innerClasses =
- n.innerClasses
- .stream()
+ n.innerClasses.stream()
.filter(x -> (x.access & Opcodes.ACC_SYNTHETIC) == 0 && x.innerName != null)
.collect(toList());
n.methods =
- n.methods
- .stream()
+ n.methods.stream()
.filter(x -> (x.access & (Opcodes.ACC_SYNTHETIC | Opcodes.ACC_PRIVATE)) == 0)
.filter(x -> !x.name.equals("<clinit>"))
.collect(toList());
n.fields =
- n.fields
- .stream()
+ n.fields.stream()
.filter(x -> (x.access & (Opcodes.ACC_SYNTHETIC | Opcodes.ACC_PRIVATE)) == 0)
.collect(toList());
}
@@ -344,14 +340,14 @@ public class IntegrationTestSupport {
if (annos == null) {
return;
}
- annos.stream().forEach(a -> collectTypesFromAnnotation(types, a));
+ annos.forEach(a -> collectTypesFromAnnotation(types, a));
}
private static void addTypesInAnnotations(Set<String> types, List<AnnotationNode> annos) {
if (annos == null) {
return;
}
- annos.stream().forEach(a -> collectTypesFromAnnotation(types, a));
+ annos.forEach(a -> collectTypesFromAnnotation(types, a));
}
private static void collectTypesFromAnnotation(Set<String> types, AnnotationNode a) {
@@ -441,9 +437,7 @@ public class IntegrationTestSupport {
Optional<String> moduleVersion)
throws IOException {
List<Tree.CompUnit> units =
- input
- .entrySet()
- .stream()
+ input.entrySet().stream()
.map(e -> new SourceFile(e.getKey(), e.getValue()))
.map(Parser::parse)
.collect(toList());
@@ -476,7 +470,7 @@ public class IntegrationTestSupport {
if (path.getParent() != null) {
Files.createDirectories(path.getParent());
}
- Files.write(path, entry.getValue().getBytes(UTF_8));
+ MoreFiles.asCharSink(path, UTF_8).write(entry.getValue());
inputs.add(path);
}
diff --git a/javatests/com/google/turbine/lower/LowerTest.java b/javatests/com/google/turbine/lower/LowerTest.java
index ef070f9..0de55c3 100644
--- a/javatests/com/google/turbine/lower/LowerTest.java
+++ b/javatests/com/google/turbine/lower/LowerTest.java
@@ -431,7 +431,7 @@ public class LowerTest {
}
},
0);
- assertThat((acc[0] & Opcodes.ACC_DEPRECATED) == Opcodes.ACC_DEPRECATED).isTrue();
+ assertThat((acc[0] & Opcodes.ACC_DEPRECATED)).isEqualTo(Opcodes.ACC_DEPRECATED);
}
@Test
@@ -635,8 +635,8 @@ public class LowerTest {
}
},
0);
- assertThat((testAccess[0] & TurbineFlag.ACC_PUBLIC) == TurbineFlag.ACC_PUBLIC).isTrue();
- assertThat((testAccess[0] & TurbineFlag.ACC_PROTECTED) == TurbineFlag.ACC_PROTECTED).isFalse();
+ assertThat((testAccess[0] & TurbineFlag.ACC_PUBLIC)).isEqualTo(TurbineFlag.ACC_PUBLIC);
+ assertThat((testAccess[0] & TurbineFlag.ACC_PROTECTED)).isNotEqualTo(TurbineFlag.ACC_PROTECTED);
}
static String lines(String... lines) {
diff --git a/javatests/com/google/turbine/lower/ModuleIntegrationTest.java b/javatests/com/google/turbine/lower/ModuleIntegrationTest.java
index 4067bd1..03c6fb7 100644
--- a/javatests/com/google/turbine/lower/ModuleIntegrationTest.java
+++ b/javatests/com/google/turbine/lower/ModuleIntegrationTest.java
@@ -16,6 +16,7 @@
package com.google.turbine.lower;
+import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_VERSION;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toList;
@@ -61,7 +62,7 @@ public class ModuleIntegrationTest {
@Test
public void test() throws Exception {
- if (Double.parseDouble(System.getProperty("java.class.version")) < 53) {
+ if (Double.parseDouble(JAVA_CLASS_VERSION.value()) < 53) {
// only run on JDK 9 and later
return;
}
@@ -97,7 +98,7 @@ public class ModuleIntegrationTest {
IntegrationTestSupport.runTurbine(
input.sources,
classpathJar,
- Double.parseDouble(System.getProperty("java.class.version")) < 54
+ Double.parseDouble(JAVA_CLASS_VERSION.value()) < 54
? JimageClassBinder.bindDefault()
: CtSymClassBinder.bind("9"),
Optional.of("42"));
@@ -107,8 +108,7 @@ public class ModuleIntegrationTest {
private String dump(Map<String, byte[]> map) throws Exception {
return IntegrationTestSupport.dump(
- map.entrySet()
- .stream()
+ map.entrySet().stream()
.filter(e -> e.getKey().endsWith("module-info"))
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)));
}
diff --git a/javatests/com/google/turbine/main/MainTest.java b/javatests/com/google/turbine/main/MainTest.java
index 654a89b..65f3167 100644
--- a/javatests/com/google/turbine/main/MainTest.java
+++ b/javatests/com/google/turbine/main/MainTest.java
@@ -16,6 +16,7 @@
package com.google.turbine.main;
+import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_VERSION;
import static com.google.common.truth.Truth.assertThat;
import static com.google.turbine.testing.TestClassPaths.optionsWithBootclasspath;
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -23,6 +24,7 @@ import static org.junit.Assert.fail;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;
+import com.google.common.io.MoreFiles;
import com.google.turbine.diag.TurbineError;
import com.google.turbine.options.TurbineOptions;
import java.io.IOException;
@@ -71,14 +73,14 @@ public class MainTest {
.build());
fail();
} catch (TurbineError e) {
- assertThat(e.getMessage()).contains("error: duplicate declaration of Test");
+ assertThat(e).hasMessageThat().contains("error: duplicate declaration of Test");
}
}
@Test
public void packageInfo() throws IOException {
Path src = temporaryFolder.newFile("package-info.jar").toPath();
- Files.write(src, "@Deprecated package test;".getBytes(UTF_8));
+ MoreFiles.asCharSink(src, UTF_8).write("@Deprecated package test;");
Path output = temporaryFolder.newFile("output.jar").toPath();
@@ -130,7 +132,7 @@ public class MainTest {
@Test
public void moduleInfos() throws IOException {
- if (Double.parseDouble(System.getProperty("java.class.version")) < 53) {
+ if (Double.parseDouble(JAVA_CLASS_VERSION.value()) < 53) {
// only run on JDK 9 and later
return;
}
@@ -144,7 +146,7 @@ public class MainTest {
}
Path src = temporaryFolder.newFile("module-info.java").toPath();
- Files.write(src, "module baz {}".getBytes(UTF_8));
+ MoreFiles.asCharSink(src, UTF_8).write("module baz {}");
Path output = temporaryFolder.newFile("output.jar").toPath();
@@ -166,7 +168,7 @@ public class MainTest {
@Test
public void testManifest() throws IOException {
Path src = temporaryFolder.newFile("Foo.java").toPath();
- Files.write(src, "class Foo {}".getBytes(UTF_8));
+ MoreFiles.asCharSink(src, UTF_8).write("class Foo {}");
Path output = temporaryFolder.newFile("output.jar").toPath();
@@ -195,7 +197,7 @@ public class MainTest {
public void emptyBootClassPath() throws IOException {
Path src = temporaryFolder.newFolder().toPath().resolve("java/lang/Object.java");
Files.createDirectories(src.getParent());
- Files.write(src, "package java.lang; public class Object {}".getBytes(UTF_8));
+ MoreFiles.asCharSink(src, UTF_8).write("package java.lang; public class Object {}");
Path output = temporaryFolder.newFile("output.jar").toPath();
@@ -214,7 +216,7 @@ public class MainTest {
@Test
public void emptyBootClassPath_noJavaLang() throws IOException {
Path src = temporaryFolder.newFile("Test.java").toPath();
- Files.write(src, "public class Test {}".getBytes(UTF_8));
+ MoreFiles.asCharSink(src, UTF_8).write("public class Test {}");
Path output = temporaryFolder.newFile("output.jar").toPath();
@@ -233,7 +235,7 @@ public class MainTest {
@Test
public void usage() throws IOException {
Path src = temporaryFolder.newFile("Test.java").toPath();
- Files.write(src, "public class Test {}".getBytes(UTF_8));
+ MoreFiles.asCharSink(src, UTF_8).write("public class Test {}");
try {
Main.compile(optionsWithBootclasspath().addSources(ImmutableList.of(src.toString())).build());
diff --git a/javatests/com/google/turbine/model/ConstTest.java b/javatests/com/google/turbine/model/ConstTest.java
index 7940124..a64d0bf 100644
--- a/javatests/com/google/turbine/model/ConstTest.java
+++ b/javatests/com/google/turbine/model/ConstTest.java
@@ -20,7 +20,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.testing.EqualsTester;
import com.google.turbine.binder.bound.AnnotationValue;
-import com.google.turbine.binder.bound.ClassValue;
+import com.google.turbine.binder.bound.TurbineClassValue;
import com.google.turbine.binder.sym.ClassSymbol;
import com.google.turbine.type.Type.ClassTy;
import com.google.turbine.type.Type.PrimTy;
@@ -72,14 +72,14 @@ public class ConstTest {
new AnnotationValue(
new ClassSymbol("test/Anno"), ImmutableMap.of("value", new Const.IntValue(4))))
.addEqualityGroup(
- new ClassValue(ClassTy.asNonParametricClassTy(new ClassSymbol("test/Clazz"))),
- new ClassValue(ClassTy.asNonParametricClassTy(new ClassSymbol("test/Clazz"))))
+ new TurbineClassValue(ClassTy.asNonParametricClassTy(new ClassSymbol("test/Clazz"))),
+ new TurbineClassValue(ClassTy.asNonParametricClassTy(new ClassSymbol("test/Clazz"))))
.addEqualityGroup(
- new ClassValue(ClassTy.asNonParametricClassTy(new ClassSymbol("test/Other"))),
- new ClassValue(ClassTy.asNonParametricClassTy(new ClassSymbol("test/Other"))))
+ new TurbineClassValue(ClassTy.asNonParametricClassTy(new ClassSymbol("test/Other"))),
+ new TurbineClassValue(ClassTy.asNonParametricClassTy(new ClassSymbol("test/Other"))))
.addEqualityGroup(
- new ClassValue(PrimTy.create(TurbineConstantTypeKind.INT, ImmutableList.of())),
- new ClassValue(PrimTy.create(TurbineConstantTypeKind.INT, ImmutableList.of())))
+ new TurbineClassValue(PrimTy.create(TurbineConstantTypeKind.INT, ImmutableList.of())),
+ new TurbineClassValue(PrimTy.create(TurbineConstantTypeKind.INT, ImmutableList.of())))
.testEquals();
}
}
diff --git a/javatests/com/google/turbine/options/TurbineOptionsTest.java b/javatests/com/google/turbine/options/TurbineOptionsTest.java
index 5953bac..a5872d9 100644
--- a/javatests/com/google/turbine/options/TurbineOptionsTest.java
+++ b/javatests/com/google/turbine/options/TurbineOptionsTest.java
@@ -95,6 +95,7 @@ public class TurbineOptionsTest {
assertThat(options.outputDeps()).hasValue("out.jdeps");
assertThat(options.targetLabel()).hasValue("//java/com/google/test");
assertThat(options.injectingRuleKind()).hasValue("foo_library");
+ assertThat(options.shouldReduceClassPath()).isTrue();
}
@Test
@@ -312,4 +313,41 @@ public class TurbineOptionsTest {
.containsExactly("--release", "8", "--release", "7", "--release")
.inOrder();
}
+
+ @Test
+ public void shouldReduceClasspath() throws Exception {
+ {
+ TurbineOptions options =
+ TurbineOptionsParser.parse(
+ Iterables.concat(BASE_ARGS, ImmutableList.of("--reduce_classpath")));
+ assertThat(options.shouldReduceClassPath()).isTrue();
+ }
+
+ {
+ TurbineOptions options =
+ TurbineOptionsParser.parse(
+ Iterables.concat(BASE_ARGS, ImmutableList.of("--noreduce_classpath")));
+ assertThat(options.shouldReduceClassPath()).isFalse();
+ }
+ }
+
+ @Test
+ public void unescape() throws Exception {
+ String[] lines = {
+ "--sources", "Test.java", "'Foo$Bar.java'",
+ };
+ TurbineOptions options =
+ TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines)));
+ assertThat(options.sources()).containsExactly("Test.java", "Foo$Bar.java").inOrder();
+ }
+
+ @Test
+ public void invalidUnescape() throws Exception {
+ String[] lines = {"--sources", "'Foo$Bar.java"};
+ try {
+ TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines)));
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
}
diff --git a/javatests/com/google/turbine/parse/ParseErrorTest.java b/javatests/com/google/turbine/parse/ParseErrorTest.java
index 53864ef..49fb273 100644
--- a/javatests/com/google/turbine/parse/ParseErrorTest.java
+++ b/javatests/com/google/turbine/parse/ParseErrorTest.java
@@ -40,7 +40,7 @@ public class ParseErrorTest {
parser.expression();
fail("expected parsing to fail");
} catch (TurbineError e) {
- assertThat(e.getMessage()).contains("invalid literal");
+ assertThat(e).hasMessageThat().contains("invalid literal");
}
}
@@ -54,7 +54,7 @@ public class ParseErrorTest {
parser.expression();
fail("expected parsing to fail");
} catch (TurbineError e) {
- assertThat(e.getMessage()).contains("invalid literal");
+ assertThat(e).hasMessageThat().contains("invalid literal");
}
}
@@ -65,7 +65,8 @@ public class ParseErrorTest {
Parser.parse(input);
fail("expected parsing to fail");
} catch (TurbineError e) {
- assertThat(e.getMessage())
+ assertThat(e)
+ .hasMessageThat()
.isEqualTo(
lines(
"<>:1: error: unexpected token: void",
@@ -81,7 +82,8 @@ public class ParseErrorTest {
Parser.parse(input);
fail("expected parsing to fail");
} catch (TurbineError e) {
- assertThat(e.getMessage())
+ assertThat(e)
+ .hasMessageThat()
.isEqualTo(
lines(
"<>:1: error: unexpected identifier 'clas'", //
@@ -97,7 +99,8 @@ public class ParseErrorTest {
Parser.parse(input);
fail("expected parsing to fail");
} catch (TurbineError e) {
- assertThat(e.getMessage())
+ assertThat(e)
+ .hasMessageThat()
.isEqualTo(
lines(
"<>:2: error: unexpected end of input", //
@@ -113,7 +116,8 @@ public class ParseErrorTest {
Parser.parse(input);
fail("expected parsing to fail");
} catch (TurbineError e) {
- assertThat(e.getMessage())
+ assertThat(e)
+ .hasMessageThat()
.isEqualTo(
lines(
"<>:1: error: invalid annotation argument", //
@@ -129,7 +133,8 @@ public class ParseErrorTest {
Parser.parse(input);
fail("expected parsing to fail");
} catch (TurbineError e) {
- assertThat(e.getMessage())
+ assertThat(e)
+ .hasMessageThat()
.isEqualTo(
lines(
"<>:1: error: unexpected end of input", //
@@ -145,7 +150,8 @@ public class ParseErrorTest {
Parser.parse(input);
fail("expected parsing to fail");
} catch (TurbineError e) {
- assertThat(e.getMessage())
+ assertThat(e)
+ .hasMessageThat()
.isEqualTo(
lines(
"<>:1: error: unexpected end of input", //
@@ -161,7 +167,8 @@ public class ParseErrorTest {
Parser.parse(input);
fail("expected parsing to fail");
} catch (TurbineError e) {
- assertThat(e.getMessage())
+ assertThat(e)
+ .hasMessageThat()
.isEqualTo(
lines(
"<>:1: error: unterminated string literal", //
@@ -177,7 +184,8 @@ public class ParseErrorTest {
Parser.parse(input);
fail("expected parsing to fail");
} catch (TurbineError e) {
- assertThat(e.getMessage())
+ assertThat(e)
+ .hasMessageThat()
.isEqualTo(
lines(
"<>:1: error: empty char literal", //
@@ -193,7 +201,8 @@ public class ParseErrorTest {
Parser.parse(input);
fail("expected parsing to fail");
} catch (TurbineError e) {
- assertThat(e.getMessage())
+ assertThat(e)
+ .hasMessageThat()
.isEqualTo(
lines(
"<>:1: error: unterminated char literal", //
@@ -202,6 +211,23 @@ public class ParseErrorTest {
}
}
+ @Test
+ public void unterminatedExpr() {
+ String input = "class T { String s = hello + world }";
+ try {
+ Parser.parse(input);
+ fail("expected parsing to fail");
+ } catch (TurbineError e) {
+ assertThat(e)
+ .hasMessageThat()
+ .isEqualTo(
+ lines(
+ "<>:1: error: unterminated expression, expected ';' not found", //
+ "class T { String s = hello + world }",
+ " ^"));
+ }
+ }
+
private static String lines(String... lines) {
return Joiner.on(System.lineSeparator()).join(lines);
}
diff --git a/pom.xml b/pom.xml
index 46a5100..cbef973 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,7 +17,7 @@
<properties>
<asm.version>7.0</asm.version>
<javac.version>9+181-r4173-1</javac.version>
- <guava.version>25.1-jre</guava.version>
+ <guava.version>27.0.1-jre</guava.version>
</properties>
<dependencies>