Skip to content

Commit

Permalink
Adds a system for sharing indexes (+builder) across multiple passes.
Browse files Browse the repository at this point in the history
Following CLs will use this system to register incrementally updated
shared datastructures and the first will be for DefinitionUseSiteFinder.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=159857712
  • Loading branch information
stalcup authored and blickly committed Jun 22, 2017
1 parent e5083c5 commit 5334563
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 5 deletions.
9 changes: 9 additions & 0 deletions src/com/google/javascript/jscomp/AbstractCompiler.java
Expand Up @@ -316,6 +316,15 @@ LifeCycleStage getLifeCycleStage() {
*/
abstract void removeChangeHandler(CodeChangeHandler handler);

/** Register a provider for some type of index. */
abstract void addIndexProvider(IndexProvider<?> indexProvider);

/**
* Returns, from a provider, the desired index of type T, otherwise null if no provider is
* registered for the given type.
*/
abstract <T> T getIndex(Class<T> type);

/** Let the PhaseOptimizer know which scope a pass is currently analyzing */
abstract void setChangeScope(Node n);

Expand Down
31 changes: 26 additions & 5 deletions src/com/google/javascript/jscomp/Compiler.java
Expand Up @@ -304,9 +304,9 @@ public Compiler() {
/**
* Creates a Compiler that reports errors and warnings to an output stream.
*/
public Compiler(PrintStream stream) {
public Compiler(PrintStream outStream) {
addChangeHandler(recentChange);
this.outStream = stream;
this.outStream = outStream;
}

/**
Expand Down Expand Up @@ -2500,6 +2500,8 @@ void recordFunctionInformation() {

protected final RecentChange recentChange = new RecentChange();
private final List<CodeChangeHandler> codeChangeHandlers = new ArrayList<>();
private final Map<Class<?>, IndexProvider<?>> indexProvidersByType =
new LinkedHashMap<>();

/** Name of the synthetic input that holds synthesized externs. */
static final String SYNTHETIC_EXTERNS = "{SyntheticVarsDeclar}";
Expand All @@ -2525,6 +2527,25 @@ void removeChangeHandler(CodeChangeHandler handler) {
codeChangeHandlers.remove(handler);
}

@Override
void addIndexProvider(IndexProvider<?> indexProvider) {
Class<?> type = indexProvider.getType();
if (indexProvidersByType.put(type, indexProvider) != null) {
throw new IllegalStateException(
"A provider is already registered for index of type " + type.getSimpleName());
}
}

@SuppressWarnings("unchecked")
@Override
<T> T getIndex(Class<T> key) {
IndexProvider<T> indexProvider = (IndexProvider<T>) indexProvidersByType.get(key);
if (indexProvider == null) {
return null;
}
return indexProvider.get();
}

Node getExternsRoot() {
return externsRoot;
}
Expand Down Expand Up @@ -2585,12 +2606,12 @@ private Node getChangeScopeForNode(Node n) {
return n;
}

n = NodeUtil.getEnclosingChangeScopeRoot(n.getParent());
if (n == null) {
Node enclosingScopeNode = NodeUtil.getEnclosingChangeScopeRoot(n.getParent());
if (enclosingScopeNode == null) {
throw new IllegalStateException(
"An enclosing scope is required for change reports but node " + n + " doesn't have one.");
}
return n;
return enclosingScopeNode;
}

private void recordChange(Node n) {
Expand Down
27 changes: 27 additions & 0 deletions src/com/google/javascript/jscomp/IndexProvider.java
@@ -0,0 +1,27 @@
/*
* Copyright 2017 The Closure Compiler Authors.
*
* 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.javascript.jscomp;

/** Builds a datastructure and incrementally updates it when scopes change. */
interface IndexProvider<T> {

/** Returns an instance of type T. */
T get();

/** Returns a class literal specialized on T. */
Class<T> getType();
}
60 changes: 60 additions & 0 deletions test/com/google/javascript/jscomp/CompilerTest.java
Expand Up @@ -1337,6 +1337,66 @@ public void testGetChangesAndDeletions_onlySeesChangesSinceLastRequest() {
assertThat(compiler.getDeletedScopeNodesForPass("FunctionInliner")).isEmpty();
}

public void testAddIndexProvider_ThenGetIndex() {
Compiler compiler = new Compiler();

compiler.addIndexProvider(new IndexProvider<String>() {
@Override
public String get() {
// Normally some shared index would be constructed/updated/returned here.
return "String";
}

@Override
public Class<String> getType() {
return String.class;
}});
compiler.addIndexProvider(new IndexProvider<Double>() {
@Override
public Double get() {
// Normally some shared index would be constructed/updated/returned here.
return Double.MAX_VALUE;
}

@Override
public Class<Double> getType() {
return Double.class;
}});

// Have registered providers.
assertThat(compiler.getIndex(String.class)).isEqualTo("String");
assertThat(compiler.getIndex(Double.class)).isEqualTo(Double.MAX_VALUE);

// Has no registered provider.
assertThat(compiler.getIndex(Object.class)).isNull();
}

public void testAddIndexProviderTwice_isException() {
Compiler compiler = new Compiler();

IndexProvider<String> stringIndexProvider =
new IndexProvider<String>() {
@Override
public String get() {
// Normally some shared index would be constructed/updated/returned here.
return "String";
}

@Override
public Class<String> getType() {
return String.class;
}
};
compiler.addIndexProvider(stringIndexProvider);

try {
compiler.addIndexProvider(stringIndexProvider);
fail("expected duplicate index addition to fail");
} catch (IllegalStateException e) {
// expected
}
}

private static CompilerOptions createNewFlagBasedOptions() {
CompilerOptions opt = new CompilerOptions();
CompilationLevel.ADVANCED_OPTIMIZATIONS.setOptionsForCompilationLevel(opt);
Expand Down

0 comments on commit 5334563

Please sign in to comment.