Skip to content

Commit

Permalink
Update JDT to version 3.13.0 and add Java 9 language features support.
Browse files Browse the repository at this point in the history
Change-Id: I073275a065caec0510708bdc7bd63bc53953752a
  • Loading branch information
rluble committed Dec 12, 2017
1 parent b6140dd commit 6407ba9
Show file tree
Hide file tree
Showing 22 changed files with 343 additions and 193 deletions.
8 changes: 4 additions & 4 deletions dev/build.xml
Expand Up @@ -135,9 +135,9 @@
<zipfileset src="${gwt.tools.lib}/apache/ant-1.6.5.jar"/>
<zipfileset src="${gwt.tools.lib}/colt/colt-1.2.jar"/>
<zipfileset
src="${gwt.tools.lib}/eclipse/org.eclipse.jdt.core_3.11.2-CUSTOM-GWT-2.8-20160205.jar"/>
src="${gwt.tools.lib}/eclipse/org.eclipse.jdt.core_3.13.50.v20171007-0855.jar"/>
<zipfileset
src="${gwt.tools.lib}/eclipse/jdtCompilerAdapter_3.11.2-CUSTOM-GWT-2.8-20160205.jar"/>
src="${gwt.tools.lib}/eclipse/jdtCompilerAdapter_3.13.50.v20171007-0855.jar"/>
<zipfileset src="${gwt.tools.lib}/guava/guava-19.0/guava-19.0-rebased.jar"/>
<zipfileset src="${gwt.tools.lib}/icu4j/50.1.1/icu4j.jar"/>
<zipfileset
Expand Down Expand Up @@ -228,9 +228,9 @@
<pathelement
location="${gwt.tools.lib}/apache/commons/commons-collections-3.2.2.jar"/>
<pathelement
location="${gwt.tools.lib}/eclipse/org.eclipse.jdt.core_3.11.2-CUSTOM-GWT-2.8-20160205.jar"/>
location="${gwt.tools.lib}/eclipse/org.eclipse.jdt.core_3.13.50.v20171007-0855.jar"/>
<pathelement
location="${gwt.tools.lib}/eclipse/jdtCompilerAdapter_3.11.2-CUSTOM-GWT-2.8-20160205.jar"/>
location="${gwt.tools.lib}/eclipse/jdtCompilerAdapter_3.13.50.v20171007-0855.jar"/>
<pathelement
location="${gwt.tools.lib}/guava/guava-19.0/guava-19.0-rebased.jar"/>
<pathelement location="${gwt.tools.lib}/gson/gson-2.6.2.jar"/>
Expand Down
3 changes: 2 additions & 1 deletion dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
Expand Up @@ -813,7 +813,8 @@ private static void resolveRecursive(ReferenceBinding outerType) {
*/
private static final Map<SourceLevel, Long> jdtLevelByGwtLevel =
ImmutableMap.<SourceLevel, Long>of(
SourceLevel.JAVA8, ClassFileConstants.JDK1_8);
SourceLevel.JAVA8, ClassFileConstants.JDK1_8,
SourceLevel.JAVA9, ClassFileConstants.JDK9);

public JdtCompiler(CompilerContext compilerContext, UnitProcessor processor) {
this.compilerContext = compilerContext;
Expand Down
Expand Up @@ -218,7 +218,7 @@ private void mergeTypeParamBounds(JTypeParameter[] typeParams,
JClassType[] typeArgs) {
int n = typeArgs.length;
for (int i = 0; i < n; ++i) {
JWildcardType wildcard = typeArgs[i].isWildcard();
JWildcardType wildcard = typeArgs[i] == null ? null : typeArgs[i].isWildcard();
// right now we only replace Foo<?> with the constraints defined on the
// definition (which appears to match the existing TypeOracleUpdater)
// but other cases may need to be handled.
Expand Down
78 changes: 48 additions & 30 deletions dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
Expand Up @@ -1215,21 +1215,22 @@ public void endVisit(LambdaExpression x, BlockScope blockScope) {
// And its JInterface container we must implement
// There may be more than more JInterface containers to be implemented
// if the lambda expression is cast to a IntersectionCastType.
JInterfaceType[] funcType;
JInterfaceType[] lambdaInterfaces;
if (binding instanceof IntersectionTypeBinding18) {
funcType = processIntersectionTypeForLambda((IntersectionTypeBinding18) binding, blockScope,
JdtUtil.signature(samBinding));
IntersectionTypeBinding18 type = (IntersectionTypeBinding18) binding;
lambdaInterfaces =
processIntersectionType(type, new JInterfaceType[type.intersectingTypes.length]);
} else {
funcType = new JInterfaceType[] {(JInterfaceType) typeMap.get(binding)};
lambdaInterfaces = new JInterfaceType[] {(JInterfaceType) typeMap.get(binding)};
}
SourceInfo info = makeSourceInfo(x);

// Create an inner class to implement the interface and SAM method.
// class lambda$0$Type implements T {}

String innerLambdaImplementationClassShortName = String.valueOf(x.binding.selector);
JClassType innerLambdaClass = createInnerClass(
curClass.getClassOrInterface(), innerLambdaImplementationClassShortName, info, funcType);
JClassType innerLambdaClass = createInnerClass(curClass.getClassOrInterface(),
innerLambdaImplementationClassShortName, info, lambdaInterfaces);
JConstructor ctor = new JConstructor(info, innerLambdaClass, AccessModifier.PRIVATE);

// locals captured by the lambda and saved as fields on the anonymous inner class
Expand Down Expand Up @@ -2224,12 +2225,32 @@ private JBlock normalizeTryWithResources(SourceInfo info, TryStatement x, JBlock
List<JLocal> resourceVariables = Lists.newArrayList();
for (int i = x.resources.length - 1; i >= 0; i--) {
// Needs to iterate back to front to be inline with the contents of the stack.
Statement resource = x.resources[i];
JStatement resourceStatement = pop(resource);

JDeclarationStatement resourceDecl = pop(x.resources[i]);
JLocal resourceVar;
if (resource instanceof LocalDeclaration) {
resourceVar = (JLocal) curMethod.locals.get(((LocalDeclaration) resource).binding);
} else {
// JLS 14.20.3.1 - Java 9 extension to try-with-resources
// try (expr) {}
// which is equivalent to
// try (T $resource = expr) {}
SourceInfo sourceInfo = resourceStatement.getSourceInfo();
JExpression expression = ((JExpressionStatement) resourceStatement).getExpr();
resourceVar = createLocal(
sourceInfo, "$resource", expression.getType());
resourceStatement =
new JBinaryOperation(
sourceInfo,
expression.getType(),
JBinaryOperator.ASG,
resourceVar.createRef(sourceInfo),
expression).makeStatement();
}

JLocal resourceVar = (JLocal) curMethod.locals.get(x.resources[i].binding);
resourceVariables.add(0, resourceVar);
tryBlock.addStmt(0, resourceDecl);
tryBlock.addStmt(0, resourceStatement);
}

// add exception variable
Expand Down Expand Up @@ -2273,9 +2294,13 @@ private JBlock normalizeTryWithResources(SourceInfo info, TryStatement x, JBlock
}

private JLocal createLocalThrowable(SourceInfo info, String prefix) {
return createLocal(info, prefix, javaLangThrowable);
}

private JLocal createLocal(SourceInfo info, String prefix, JType type) {
int index = curMethod.body.getLocals().size() + 1;
return JProgram.createLocal(info, prefix + "_" + index,
javaLangThrowable, false, curMethod.body);
type, false, curMethod.body);
}

private JStatement createCloseBlockFor(
Expand Down Expand Up @@ -3624,37 +3649,29 @@ private JCastOperation buildCastOperation(SourceInfo info, JType[] castTypes,
}
}

private JReferenceType[] processIntersectionCastType(IntersectionTypeBinding18 type) {
JReferenceType[] castTypes = new JReferenceType[type.intersectingTypes.length];
private JReferenceType[] processIntersectionType(IntersectionTypeBinding18 type) {
return processIntersectionType(type, new JReferenceType[type.intersectingTypes.length]);
}

private <T extends JReferenceType> T[] processIntersectionType(
IntersectionTypeBinding18 type, T[] intersectionTypes) {
int i = 0;
for (ReferenceBinding intersectingTypeBinding : type.intersectingTypes) {
JType intersectingType = typeMap.get(intersectingTypeBinding);
assert (intersectingType instanceof JReferenceType);
castTypes[i++] = ((JReferenceType) intersectingType);
intersectionTypes[i++] = (T) intersectingType;
}
return castTypes;
return intersectionTypes;
}

private JType[] processCastType(TypeBinding type) {
if (type instanceof IntersectionTypeBinding18) {
return processIntersectionCastType((IntersectionTypeBinding18) type);
return processIntersectionType((IntersectionTypeBinding18) type);
} else {
return new JType[] {typeMap.get(type)};
}
}

private JInterfaceType[] processIntersectionTypeForLambda(IntersectionTypeBinding18 type,
BlockScope scope, String samSignature) {
List<JInterfaceType> interfaces = Lists.newArrayList();
for (ReferenceBinding intersectingTypeBinding : type.intersectingTypes) {
if (shouldImplements(intersectingTypeBinding, scope, samSignature)) {
JType intersectingType = typeMap.get(intersectingTypeBinding);
assert (intersectingType instanceof JInterfaceType);
interfaces.add(((JInterfaceType) intersectingType));
}
}
return Iterables.toArray(interfaces, JInterfaceType.class);
}

private boolean isFunctionalInterfaceWithMethod(ReferenceBinding referenceBinding, Scope scope,
String samSignature) {
Expand Down Expand Up @@ -3723,9 +3740,9 @@ private List<MethodBinding> getInterfaceAbstractMethods(ReferenceBinding referen
}
}

private <T extends JType> Iterable<T> mapTypes(TypeBinding[] types) {
private <T extends JType, B extends TypeBinding> Iterable<T> mapTypes(B[] types) {
return FluentIterable.from(Arrays.asList(types)).transform(
new Function<TypeBinding, T>() {
new Function<B, T>() {
@Override
public T apply(TypeBinding typeBinding) {
return (T) typeMap.get(typeBinding.erasure());
Expand Down Expand Up @@ -4347,7 +4364,8 @@ private void createTypes(TypeDeclaration x) {

JDeclaredType type;
if (binding.isClass()) {
type = new JClassType(info, name, binding.isAbstract(), binding.isFinal());
type = new JClassType(
info, name, binding.isAbstract(), binding.isFinal() || binding.isAnonymousType());
} else if (binding.isInterface() || binding.isAnnotationType()) {
type = new JInterfaceType(info, name);
} else if (binding.isEnum()) {
Expand Down
4 changes: 2 additions & 2 deletions dev/core/src/com/google/gwt/dev/util/arg/SourceLevel.java
Expand Up @@ -23,7 +23,8 @@
*/
public enum SourceLevel {
// Source levels must appear in ascending order for the default setting logic to work.
JAVA8("1.8", "8");
JAVA8("1.8", "8"),
JAVA9("1.9", "9");

/**
* The default java sourceLevel.
Expand Down Expand Up @@ -75,7 +76,6 @@ public static SourceLevel fromString(String sourceLevelString) {
}

private static SourceLevel getJvmBestMatchingSourceLevel() {
// If everything fails set default to JAVA8.
String javaSpecLevel = System.getProperty("java.specification.version");
return getBestMatchingVersion(javaSpecLevel);
}
Expand Down
8 changes: 4 additions & 4 deletions dev/core/test/com/google/gwt/dev/CompilerTest.java
Expand Up @@ -957,7 +957,7 @@ public void testSourceLevelSelection() {

assertEquals(SourceLevel.JAVA8, SourceLevel.getBestMatchingVersion("1.7"));
assertEquals(SourceLevel.JAVA8, SourceLevel.getBestMatchingVersion("1.8"));
assertEquals(SourceLevel.JAVA8, SourceLevel.getBestMatchingVersion("1.9"));
assertEquals(SourceLevel.JAVA9, SourceLevel.getBestMatchingVersion("1.9"));

// not proper version strings => default to JAVA8.
assertEquals(SourceLevel.JAVA8, SourceLevel.getBestMatchingVersion("1.6u3"));
Expand Down Expand Up @@ -1696,7 +1696,7 @@ public void testIncrementalRecompile_withErrors()
File applicationDir = Files.createTempDir();
CompilerOptions compilerOptions = new CompilerOptionsImpl();
compilerOptions.setUseDetailedTypeIds(true);
compilerOptions.setSourceLevel(SourceLevel.JAVA8);
compilerOptions.setSourceLevel(SourceLevel.JAVA9);

// Compile the application with no errors.
compileToJs(TreeLogger.NULL, compilerOptions, applicationDir, "com.foo.Errors",
Expand Down Expand Up @@ -1759,7 +1759,7 @@ public void testIncrementalRecompile_representedAsNative()
File applicationDir = Files.createTempDir();
CompilerOptions compilerOptions = new CompilerOptionsImpl();
compilerOptions.setUseDetailedTypeIds(true);
compilerOptions.setSourceLevel(SourceLevel.JAVA8);
compilerOptions.setSourceLevel(SourceLevel.JAVA9);
compilerOptions.setGenerateJsInteropExports(false);

// Compile the application with no errors.
Expand Down Expand Up @@ -2110,7 +2110,7 @@ private void checkIncrementalRecompile_defaultMethod(JsOutputOption output)

CompilerOptions compilerOptions = new CompilerOptionsImpl();
compilerOptions.setUseDetailedTypeIds(true);
compilerOptions.setSourceLevel(SourceLevel.JAVA8);
compilerOptions.setSourceLevel(SourceLevel.JAVA9);

checkRecompiledModifiedApp(compilerOptions, "com.foo.DefaultMethod",
Lists.newArrayList(moduleResource, entryPointResource, aSubclass,
Expand Down
Expand Up @@ -40,6 +40,7 @@
import org.eclipse.jdt.internal.compiler.env.ITypeAnnotationWalker;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.ExternalAnnotationStatus;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
Expand Down Expand Up @@ -86,6 +87,11 @@ public IBinaryField[] getFields() {
return null;
}

@Override
public char[] getModule() {
return null;
}

@Override
public char[] getFileName() {
return (qualifiedTypeName.replace('.', File.separatorChar) + ".java").toCharArray();
Expand Down Expand Up @@ -171,6 +177,10 @@ public ITypeAnnotationWalker enrichWithExternalAnnotationsFor(
ITypeAnnotationWalker walker, Object member, LookupEnvironment environment) {
return walker;
}
@Override
public ExternalAnnotationStatus getExternalAnnotationStatus() {
return null;
}
}

private static final String BINARY_TYPE_NAME = "BinaryType";
Expand Down
Expand Up @@ -50,7 +50,7 @@ public void testCompileMultiExceptions() throws Exception {

@Override
protected SourceLevel getSourceLevel() {
// Always compile this tests as Java 8.
return SourceLevel.JAVA8;
// Always compile this tests as Java 9.
return SourceLevel.JAVA9;
}
}
Expand Up @@ -183,7 +183,7 @@ public void setUp() {
}

public void testNestedClassDisposition() throws UnableToCompleteException {
sourceLevel = SourceLevel.JAVA8;
sourceLevel = SourceLevel.JAVA9;

sources.add(JavaResourceBase.createMockJavaResource("test.NestedClasses",
"package test;",
Expand Down Expand Up @@ -237,7 +237,7 @@ public void testNestedClassDisposition() throws UnableToCompleteException {
}

public void testIntersectionBound() throws UnableToCompleteException {
sourceLevel = SourceLevel.JAVA8;
sourceLevel = SourceLevel.JAVA9;

sources.add(JavaResourceBase.createMockJavaResource("test.IntersectionBound",
"package test;",
Expand Down
Expand Up @@ -30,7 +30,7 @@ public class Java7AstTest extends JJSTestBase {
// of nodes.
@Override
public void setUp() {
sourceLevel = SourceLevel.JAVA8;
sourceLevel = SourceLevel.JAVA9;
addAll(JavaResourceBase.AUTOCLOSEABLE, Java7MockResources.TEST_RESOURCE,
Java7MockResources.EXCEPTION1, Java7MockResources.EXCEPTION2);
}
Expand Down
31 changes: 4 additions & 27 deletions dev/core/test/com/google/gwt/dev/jjs/impl/Java8AstTest.java
@@ -1,5 +1,5 @@
/*
* Copyright 2014 Google Inc.
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
Expand Down Expand Up @@ -37,7 +37,7 @@ public class Java8AstTest extends FullCompileTestBase {

@Override
public void setUp() throws Exception {
sourceLevel = SourceLevel.JAVA8;
sourceLevel = SourceLevel.JAVA9;
super.setUp();
addAll(LAMBDA_METAFACTORY);

Expand Down Expand Up @@ -1092,29 +1092,6 @@ public void testMultipleIntersectionCastOfLambda() throws Exception {
formatSource(samMethod.toSource()));
}

public void testIntersectionCastOfLambdaWithClassType() throws Exception {
addSnippetClassDecl("interface I1 { public void foo(); }");
addSnippetClassDecl("class A { }");
String lambda = "Object o = (A & I1) () -> {};";
assertEqualBlock("Object o=(EntryPoint$A)(EntryPoint$I1)new EntryPoint$lambda$0$Type();",
lambda);

JProgram program = compileSnippet("void", lambda, false);

assertNotNull(getMethod(program, "lambda$0"));

JClassType lambdaInnerClass = (JClassType) getType(program, "test.EntryPoint$lambda$0$Type");
assertNotNull(lambdaInnerClass);
assertEquals("java.lang.Object", lambdaInnerClass.getSuperClass().getName());
assertEquals(1, lambdaInnerClass.getImplements().size());
assertTrue(
lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.EntryPoint$I1")));
// should implement foo method
JMethod samMethod = findMethod(lambdaInnerClass, "foo");
assertEquals("public final void foo(){EntryPoint.lambda$0();}",
formatSource(samMethod.toSource()));
}

public void testIntersectionCastOfLambdaOneAbstractMethod() throws Exception {
addSnippetClassDecl("interface I1 { public void foo(); }");
addSnippetClassDecl("interface I2 extends I1{ public void foo();}");
Expand All @@ -1141,7 +1118,7 @@ public void testIntersectionCastOfLambdaOneAbstractMethod() throws Exception {

public void testIntersectionCastMultipleAbstractMethods() throws Exception {
addSnippetClassDecl("interface I1 { public void foo(); }");
addSnippetClassDecl("interface I2 { public void bar(); public void fun();}");
addSnippetClassDecl("interface I2 { public void foo(); }");
String lambda = "Object o = (I1 & I2) () -> {};";
assertEqualBlock("Object o=(EntryPoint$I1)(EntryPoint$I2)new EntryPoint$lambda$0$Type();",
lambda);
Expand All @@ -1153,7 +1130,7 @@ public void testIntersectionCastMultipleAbstractMethods() throws Exception {
JClassType lambdaInnerClass = (JClassType) getType(program, "test.EntryPoint$lambda$0$Type");
assertNotNull(lambdaInnerClass);
assertEquals("java.lang.Object", lambdaInnerClass.getSuperClass().getName());
assertEquals(1, lambdaInnerClass.getImplements().size());
assertEquals(2, lambdaInnerClass.getImplements().size());
assertTrue(
lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.EntryPoint$I1")));
// should implement foo method
Expand Down

0 comments on commit 6407ba9

Please sign in to comment.