Skip to content

Commit

Permalink
Fix java.lang.Object methods when called on native JsType.
Browse files Browse the repository at this point in the history
Change-Id: I4d31517f4ad430df4563f08be47c42d92630096e
  • Loading branch information
rluble committed Nov 5, 2015
1 parent 38039e3 commit 91fdb93
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 5 deletions.
5 changes: 5 additions & 0 deletions dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java
Expand Up @@ -94,6 +94,11 @@ public boolean canBeImplementedExternally() {
return getLeafType().canBeImplementedExternally();
}

@Override
public boolean isJsNative() {
return getLeafType().isJsNative();
}

@Override
public boolean isJsoType() {
return false;
Expand Down
Expand Up @@ -203,7 +203,7 @@ private void computeCastMap(JReferenceType type) {
}

if (!typeOracle.isInstantiatedType(type) ||
type.isJsoType()) {
type.isJsoType() || type.isJsNative()) {
return;
}

Expand Down
Expand Up @@ -24,6 +24,7 @@
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JInstanceOf;
import com.google.gwt.dev.jjs.ast.JInterfaceType;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodCall;
import com.google.gwt.dev.jjs.ast.JModVisitor;
Expand Down Expand Up @@ -197,6 +198,8 @@ public void endVisit(JInstanceOf x, Context ctx) {
toType = (JReferenceType) program.normalizeJsoType(toType);
}

assert !toType.isJsNative() || !(toType instanceof JInterfaceType);

boolean isTrivialCast = program.typeOracle.castSucceedsTrivially(argType, toType)
// don't depend on type-tightener having run
|| (program.typeOracle.isEffectivelyJavaScriptObject(argType)
Expand Down
Expand Up @@ -208,7 +208,7 @@ private class NormalizeVisitor extends JModVisitor {
@Override
public void endVisit(JClassLiteral x, Context ctx) {
JType type = x.getRefType();
if (type instanceof JArrayType) {
if (type instanceof JArrayType && !type.isJsNative()) {
// Replace array class literals by an expression to obtain the class literal from the
// leaf type of the array.
JArrayType arrayType = (JArrayType) type;
Expand Down Expand Up @@ -443,7 +443,7 @@ private void resolveClassLiteral(JClassLiteral x) {
* </pre>
*/
private JField resolveClassLiteralField(JType type) {
type = program.normalizeJsoType(type);
type = type.isJsNative() ? program.getJavaScriptObject() : program.normalizeJsoType(type);
JField field = classLiteralFields.get(type);
if (field == null) {
// Create the allocation expression FIRST since this may be recursive on
Expand Down
2 changes: 1 addition & 1 deletion dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
Expand Up @@ -1355,7 +1355,7 @@ private void instantiate(JDeclaredType type) {

private boolean requiresDevirtualization(JDeclaredType type) {
// NOTE: these types are the ones {@link Devirtualizer} handles.
return isJso(type) ||
return isJso(type) || type.isJsNative() ||
// Use the version that takes names instead of instances as some
// relevant instances might have not been leaded yet.
JProgram.isRepresentedAsNative(type.getName());
Expand Down
2 changes: 1 addition & 1 deletion dev/core/test/com/google/gwt/dev/CompilerTest.java
Expand Up @@ -1252,7 +1252,7 @@ public void testChangeJsType() throws Exception {
* <p>An unrelated and non-updated @JsType is also included in each compile to verify that updated
* exports do not forget non-edited items in a recompile.
*/
public void __disabled__testChangeJsTypeNative() throws Exception {
public void testChangeJsTypeNative() throws Exception {
CompilerOptions compilerOptions = new CompilerOptionsImpl();
compilerOptions.setUseDetailedTypeIds(true);

Expand Down
84 changes: 84 additions & 0 deletions user/test/com/google/gwt/core/client/interop/NativeJsTypeTest.java
@@ -0,0 +1,84 @@
/*
* Copyright 2013 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
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.core.client.interop;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.junit.client.GWTTestCase;

import jsinterop.annotations.JsType;

/**
* Tests JsType functionality.
*/
@SuppressWarnings("cast")
public class NativeJsTypeTest extends GWTTestCase {

@Override
public String getModuleName() {
return "com.google.gwt.core.Core";
}

@JsType(isNative = true)
static class MyNativeJsType {
// TODO(rluble): these methods should be synthesyzed by the compiler.
@Override
public native String toString();
@Override
public native boolean equals(Object o);
@Override
public native int hashCode();
}

@JsType(isNative = true)
interface MyNativeJsTypeInterface {
}

public void testClassLiterals() {
assertEquals(JavaScriptObject.class, MyNativeJsType.class);
assertEquals(JavaScriptObject.class, MyNativeJsTypeInterface.class);
assertEquals(JavaScriptObject.class, MyNativeJsType[].class);
assertEquals(JavaScriptObject.class, MyNativeJsTypeInterface[].class);
assertEquals(JavaScriptObject.class, MyNativeJsType[][].class);
assertEquals(JavaScriptObject.class, MyNativeJsTypeInterface[][].class);

Object nativeObject = createNativeObjectWithoutToString();
assertEquals(JavaScriptObject.class, nativeObject.getClass());
assertEquals(JavaScriptObject.class, ((MyNativeJsTypeInterface) nativeObject).getClass());
}

public void testToString() {
Object nativeObjectWithToString = createNativeObjectWithToString();
assertEquals("Native type", nativeObjectWithToString.toString());

Object nativeObjectWithoutToString = createNativeObjectWithoutToString();
assertEquals("[object Object]", nativeObjectWithoutToString.toString());

Object nativeArray = createNativeArray();
assertEquals("", nativeArray.toString());
}

private static native MyNativeJsType createNativeObjectWithToString() /*-{
return {toString: function() { return "Native type"; } };
}-*/;

private static native MyNativeJsType createNativeObjectWithoutToString() /*-{
return {};
}-*/;

private static native Object createNativeArray() /*-{
return [];
}-*/;
}

0 comments on commit 91fdb93

Please sign in to comment.