Skip to content

Commit

Permalink
Avoid unnecessary path scanning during JSNI resolution.
Browse files Browse the repository at this point in the history
This patch:
- caches the set of unresolvable types to avoid file scanning, however the
  cache is cleared between generator invocations (generators may generate
  one of the missing files).
- resolves inner classes by binary name, avoiding looking for files in
  subdirectories.

Change-Id: Ic848d63f81400effdc92fa50f60e1e63200eed19
Bug-Link: #8960
  • Loading branch information
rluble authored and Gerrit Code Review committed Nov 10, 2015
1 parent 0a7b1bd commit 0b0723f
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 14 deletions.
18 changes: 16 additions & 2 deletions dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
Expand Up @@ -30,6 +30,7 @@
import com.google.gwt.thirdparty.guava.common.collect.ImmutableMap; import com.google.gwt.thirdparty.guava.common.collect.ImmutableMap;
import com.google.gwt.thirdparty.guava.common.collect.ListMultimap; import com.google.gwt.thirdparty.guava.common.collect.ListMultimap;
import com.google.gwt.thirdparty.guava.common.collect.Maps; import com.google.gwt.thirdparty.guava.common.collect.Maps;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import com.google.gwt.thirdparty.guava.common.io.BaseEncoding; import com.google.gwt.thirdparty.guava.common.io.BaseEncoding;


import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.compiler.CharOperation;
Expand Down Expand Up @@ -104,7 +105,7 @@ public class JdtCompiler {
* types are encountered during compilation. Currently used for allowing * types are encountered during compilation. Currently used for allowing
* external tools to provide source lazily when undefined references appear. * external tools to provide source lazily when undefined references appear.
*/ */
public static interface AdditionalTypeProviderDelegate { public interface AdditionalTypeProviderDelegate {
/** /**
* Checks for additional packages which may contain additional compilation * Checks for additional packages which may contain additional compilation
* units. * units.
Expand Down Expand Up @@ -760,6 +761,11 @@ private static void resolveRecursive(ReferenceBinding outerType) {
private final Map<String, NameEnvironmentAnswer> cachedClassPathAnswerByInternalName = private final Map<String, NameEnvironmentAnswer> cachedClassPathAnswerByInternalName =
Maps.newHashMap(); Maps.newHashMap();


/**
* Remembers types that where not found during resolution to avoid unnecessary file scanning.
*/
private final Set<String> unresolvableReferences = Sets.newHashSet();

/** /**
* Only active during a compile. * Only active during a compile.
*/ */
Expand Down Expand Up @@ -1035,7 +1041,15 @@ public void doCompile(TreeLogger logger, Collection<CompilationUnitBuilder> buil
} }


public ReferenceBinding resolveType(String sourceOrBinaryName) { public ReferenceBinding resolveType(String sourceOrBinaryName) {
return resolveType(compilerImpl.lookupEnvironment, sourceOrBinaryName); if (unresolvableReferences.contains(sourceOrBinaryName)) {
return null;
}
ReferenceBinding typeBinding =
resolveType(compilerImpl.lookupEnvironment, sourceOrBinaryName);
if (typeBinding == null) {
unresolvableReferences.add(sourceOrBinaryName);
}
return typeBinding;
} }


public void setAdditionalTypeProviderDelegate(AdditionalTypeProviderDelegate newDelegate) { public void setAdditionalTypeProviderDelegate(AdditionalTypeProviderDelegate newDelegate) {
Expand Down
20 changes: 18 additions & 2 deletions dev/core/src/com/google/gwt/dev/javac/JdtUtil.java
Expand Up @@ -108,9 +108,25 @@ public static String getDefiningCompilationUnitType(ReferenceBinding binding) {
} }


public static String getSourceName(TypeBinding classBinding) { public static String getSourceName(TypeBinding classBinding) {
return getSourceName(CharOperation.charToString(classBinding.qualifiedPackageName()),
CharOperation.charToString(classBinding.qualifiedSourceName()));
}

public static String getSourceName(String qualifiedPackageName, String qualifiedSourceName) {
return Joiner.on(".").skipNulls().join(new String[] {
Strings.emptyToNull(qualifiedPackageName),
qualifiedSourceName});
}

public static String getBinaryName(TypeBinding classBinding) {
return getBinaryName(CharOperation.charToString(classBinding.qualifiedPackageName()),
CharOperation.charToString(classBinding.qualifiedSourceName()));
}

public static String getBinaryName(String qualifiedPackageName, String qualifiedSourceName) {
return Joiner.on(".").skipNulls().join(new String[] { return Joiner.on(".").skipNulls().join(new String[] {
Strings.emptyToNull(CharOperation.charToString(classBinding.qualifiedPackageName())), Strings.emptyToNull(qualifiedPackageName),
CharOperation.charToString(classBinding.qualifiedSourceName())}); qualifiedSourceName.replace('.','$')});
} }


public static boolean isInnerClass(ReferenceBinding binding) { public static boolean isInnerClass(ReferenceBinding binding) {
Expand Down
25 changes: 15 additions & 10 deletions dev/core/src/com/google/gwt/dev/javac/JsniReferenceResolver.java
Expand Up @@ -295,9 +295,10 @@ private void resolveClassReference(JsniRef jsniRef) {
originalName.substring(importedClassName.length())); originalName.substring(importedClassName.length()));
return; return;
} }
String fullClassName = declaringClassName + "." + originalName; String fullClassName =
JdtUtil.getBinaryName(declaringClass) + "$" + originalName.replace('.', '$');
if (typeResolver.resolveType(fullClassName) != null) { if (typeResolver.resolveType(fullClassName) != null) {
jsniRef.setResolvedClassName(fullClassName); jsniRef.setResolvedClassName(JdtUtil.getSourceName(declaringClass) + "." + originalName);
return; return;
} }
declaringClass = declaringClass.enclosingTypeAt(1); declaringClass = declaringClass.enclosingTypeAt(1);
Expand All @@ -315,12 +316,16 @@ private void resolveClassReference(JsniRef jsniRef) {
} }


// 4. Check to see if this name is resolvable from the current package. // 4. Check to see if this name is resolvable from the current package.
String currentPackageClassName = String currentPackageBinaryClassName =
String.valueOf(method.binding.declaringClass.qualifiedPackageName()); JdtUtil.getBinaryName(
currentPackageClassName += (currentPackageClassName.isEmpty() ? "" : ".") + originalName; CharOperation.charToString(method.binding.declaringClass.qualifiedPackageName()),

originalName);
if (typeResolver.resolveType(currentPackageClassName) != null) {
jsniRef.setResolvedClassName(currentPackageClassName); if (typeResolver.resolveType(currentPackageBinaryClassName) != null) {
jsniRef.setResolvedClassName(
JdtUtil.getSourceName(
CharOperation.charToString(method.binding.declaringClass.qualifiedPackageName()),
originalName));
return; return;
} }


Expand All @@ -333,9 +338,9 @@ private void resolveClassReference(JsniRef jsniRef) {
importPackages.add(JdtUtil.asDottedString(importReference.getImportName())); importPackages.add(JdtUtil.asDottedString(importReference.getImportName()));
} }
for (String importPackage : importPackages) { for (String importPackage : importPackages) {
String fullClassName = importPackage + "." + originalName; String fullClassName = importPackage + "." + originalName.replace('.', '$');
if (typeResolver.resolveType(fullClassName) != null) { if (typeResolver.resolveType(fullClassName) != null) {
jsniRef.setResolvedClassName(fullClassName); jsniRef.setResolvedClassName(importPackage + "." + originalName);
return; return;
} }
} }
Expand Down

0 comments on commit 0b0723f

Please sign in to comment.