diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2019-01-31 04:05:36 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2019-01-31 04:05:36 +0000 |
commit | d87cc65560859f5b2a7c53b2fb16108508e15180 (patch) | |
tree | 1341c1adbe2adae484c8f3018179457ca5a39a6c | |
parent | 082cea924ba463533756b929845f7e5cbdfe6fe3 (diff) | |
parent | b472a8a886d074fa48cd2df6d01c5824541449ae (diff) | |
download | turbine-d87cc65560859f5b2a7c53b2fb16108508e15180.tar.gz |
Snap for 5271441 from b472a8a886d074fa48cd2df6d01c5824541449ae to qt-release
Change-Id: I99d729abe28b7d27f9e9be91c8278aeebc4a82aa
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); } @@ -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> |