Author: [email protected] Date: Tue Jun 30 07:54:21 2009 New Revision: 5640 Modified: trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRebinds.java trunk/user/src/com/google/gwt/core/client/impl/Impl.java
Log: Add Impl.getNameOf() to expose JNameOf nodes to Java code. http://gwt-code-reviews.appspot.com/46802/show Patch by: bobv Review by: scottb Modified: trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java (original) +++ trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java Tue Jun 30 07:54:21 2009 @@ -77,6 +77,7 @@ "com.google.gwt.lang.ClassLiteralHolder", "com.google.gwt.core.client.RunAsyncCallback", "com.google.gwt.core.client.impl.AsyncFragmentLoader", + "com.google.gwt.core.client.impl.Impl", "com.google.gwt.lang.EntryMethodHolder",})); static final Map<String, Set<String>> traceMethods = new HashMap<String, Set<String>>(); Modified: trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRebinds.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRebinds.java (original) +++ trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRebinds.java Tue Jun 30 07:54:21 2009 @@ -20,15 +20,21 @@ import com.google.gwt.dev.jdt.RebindPermutationOracle; import com.google.gwt.dev.jjs.InternalCompilerException; import com.google.gwt.dev.jjs.ast.Context; +import com.google.gwt.dev.jjs.ast.HasEnclosingType; +import com.google.gwt.dev.jjs.ast.HasName; import com.google.gwt.dev.jjs.ast.JClassLiteral; import com.google.gwt.dev.jjs.ast.JClassType; +import com.google.gwt.dev.jjs.ast.JDeclaredType; import com.google.gwt.dev.jjs.ast.JExpression; import com.google.gwt.dev.jjs.ast.JGwtCreate; import com.google.gwt.dev.jjs.ast.JMethod; import com.google.gwt.dev.jjs.ast.JMethodCall; import com.google.gwt.dev.jjs.ast.JModVisitor; +import com.google.gwt.dev.jjs.ast.JNameOf; import com.google.gwt.dev.jjs.ast.JProgram; import com.google.gwt.dev.jjs.ast.JReferenceType; +import com.google.gwt.dev.jjs.ast.JStringLiteral; +import com.google.gwt.dev.util.JsniRef; import java.util.ArrayList; import java.util.List; @@ -40,30 +46,85 @@ private class RebindVisitor extends JModVisitor { + private final JMethod nameOfMethod; private final JMethod rebindCreateMethod; - public RebindVisitor(JMethod rebindCreateMethod) { + public RebindVisitor(JMethod nameOfMethod, JMethod rebindCreateMethod) { + this.nameOfMethod = nameOfMethod; this.rebindCreateMethod = rebindCreateMethod; } @Override public void endVisit(JMethodCall x, Context ctx) { JMethod method = x.getTarget(); - if (method == rebindCreateMethod) { - assert (x.getArgs().size() == 1); - JExpression arg = x.getArgs().get(0); - assert (arg instanceof JClassLiteral); - JClassLiteral classLiteral = (JClassLiteral) arg; - JReferenceType sourceType = (JReferenceType) classLiteral.getRefType(); - List<JClassType> allRebindResults = getAllPossibleRebindResults(sourceType); - JGwtCreate gwtCreate = new JGwtCreate(x.getSourceInfo(), sourceType, - allRebindResults, program.getTypeJavaLangObject()); - if (allRebindResults.size() == 1) { - // Just replace with the instantiation expression. - ctx.replaceMe(gwtCreate.getInstantiationExpressions().get(0)); - } else { - ctx.replaceMe(gwtCreate); + if (method == nameOfMethod) { + replaceImplNameOf(x, ctx); + + } else if (method == rebindCreateMethod) { + replaceGwtCreate(x, ctx); + } + } + + private void replaceGwtCreate(JMethodCall x, Context ctx) { + assert (x.getArgs().size() == 1); + JExpression arg = x.getArgs().get(0); + assert (arg instanceof JClassLiteral); + JClassLiteral classLiteral = (JClassLiteral) arg; + JReferenceType sourceType = (JReferenceType) classLiteral.getRefType(); + List<JClassType> allRebindResults = getAllPossibleRebindResults(sourceType); + JGwtCreate gwtCreate = new JGwtCreate(x.getSourceInfo(), sourceType, + allRebindResults, program.getTypeJavaLangObject()); + if (allRebindResults.size() == 1) { + // Just replace with the instantiation expression. + ctx.replaceMe(gwtCreate.getInstantiationExpressions().get(0)); + } else { + ctx.replaceMe(gwtCreate); + } + } + + private void replaceImplNameOf(JMethodCall x, Context ctx) { + JExpression arg0 = x.getArgs().get(0); + assert arg0 instanceof JStringLiteral; + String stringLiteral = ((JStringLiteral) arg0).getValue(); + + HasName named = null; + + JDeclaredType refType; + JsniRef ref = JsniRef.parse(stringLiteral); + + if (ref != null) { + final List<String> errors = new ArrayList<String>(); + HasEnclosingType node = JsniRefLookup.findJsniRefTarget(ref, program, + new JsniRefLookup.ErrorReporter() { + public void reportError(String error) { + errors.add(error); + } + }); + + if (!errors.isEmpty()) { + for (String error : errors) { + logger.log(TreeLogger.ERROR, error); + } } + + if (node instanceof HasName) { + named = (HasName) node; + } + + } else { + // See if it's just @foo.Bar, which would result in the class seed + refType = program.getFromTypeMap(stringLiteral.charAt(0) == '@' + ? stringLiteral.substring(1) : stringLiteral); + if (refType != null) { + named = refType; + } + } + + if (named == null) { + // Not found, must be null + ctx.replaceMe(program.getLiteralNull()); + } else { + ctx.replaceMe(new JNameOf(x.getSourceInfo(), program, named)); } } } @@ -108,6 +169,7 @@ private boolean execImpl() { RebindVisitor rebinder = new RebindVisitor( + program.getIndexedMethod("Impl.getNameOf"), program.getIndexedMethod("GWT.create")); rebinder.accept(program); return rebinder.didChange(); Modified: trunk/user/src/com/google/gwt/core/client/impl/Impl.java ============================================================================== --- trunk/user/src/com/google/gwt/core/client/impl/Impl.java (original) +++ trunk/user/src/com/google/gwt/core/client/impl/Impl.java Tue Jun 30 07:54:21 2009 @@ -15,6 +15,8 @@ */ package com.google.gwt.core.client.impl; +import com.google.gwt.core.client.GWT; + /** * Private implementation class for GWT core. This API is should not be * considered public or stable. @@ -65,6 +67,29 @@ public static native String getModuleName() /*-{ return $moduleName; }-*/; + + /** + * Returns the obfuscated name of members in the compiled output. This is a + * thin wrapper around JNameOf AST nodes and is therefore meaningless to + * implement in hosted mode. + * + * @param jsniIdent a string literal specifying a type, field, or method. Raw + * type names may also be used to obtain the name of the type's seed + * function. + * @return the name by which the named member can be accessed at runtime, or + * <code>null</code> if the requested member has been pruned from the + * output. + * @see com.google.gwt.core.client.ArtificialRescue + */ + public static String getNameOf(String jsniIdent) { + /* + * In web mode, the compiler directly replaces calls to this method with a + * string literal expression. + */ + assert !GWT.isScript() : "ReplaceRebinds failed to replace this method"; + throw new UnsupportedOperationException( + "Impl.getNameOf() is unimplemented in hosted mode"); + } public static native String getPermutationStrongName() /*-{ return $strongName; --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---
