Skip to content

Commit

Permalink
Factor ReferenceCollection out of ReferenceCollectingCallback.
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=155629421
  • Loading branch information
brad4d authored and dimvar committed May 10, 2017
1 parent d236b78 commit 7580f65
Show file tree
Hide file tree
Showing 17 changed files with 218 additions and 227 deletions.
1 change: 0 additions & 1 deletion src/com/google/javascript/jscomp/AbstractCompiler.java
Expand Up @@ -20,7 +20,6 @@
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceCollection;
import com.google.javascript.jscomp.deps.ModuleLoader;
import com.google.javascript.jscomp.parsing.Config;
import com.google.javascript.jscomp.parsing.parser.trees.Comment;
Expand Down
Expand Up @@ -22,7 +22,6 @@
import com.google.javascript.jscomp.GlobalNamespace.Name;
import com.google.javascript.jscomp.GlobalNamespace.Ref;
import com.google.javascript.jscomp.GlobalNamespace.Ref.Type;
import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceCollection;
import com.google.javascript.rhino.IR;
import com.google.javascript.rhino.Node;
import java.util.ArrayDeque;
Expand Down
1 change: 0 additions & 1 deletion src/com/google/javascript/jscomp/Compiler.java
Expand Up @@ -31,7 +31,6 @@
import com.google.javascript.jscomp.CompilerOptions.DevMode;
import com.google.javascript.jscomp.CoverageInstrumentationPass.CoverageReach;
import com.google.javascript.jscomp.CoverageInstrumentationPass.InstrumentOption;
import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceCollection;
import com.google.javascript.jscomp.WarningsGuard.DiagnosticGroupState;
import com.google.javascript.jscomp.deps.JsFileParser;
import com.google.javascript.jscomp.deps.ModuleLoader;
Expand Down
Expand Up @@ -20,7 +20,6 @@
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.javascript.jscomp.CodingConvention.SubclassRelationship;
import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceCollection;
import com.google.javascript.rhino.IR;
import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.Token;
Expand Down
1 change: 0 additions & 1 deletion src/com/google/javascript/jscomp/Denormalize.java
Expand Up @@ -20,7 +20,6 @@

import com.google.javascript.jscomp.NodeTraversal.Callback;
import com.google.javascript.jscomp.ReferenceCollectingCallback.Behavior;
import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceCollection;
import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceMap;
import com.google.javascript.rhino.IR;
import com.google.javascript.rhino.Node;
Expand Down
Expand Up @@ -17,7 +17,6 @@
package com.google.javascript.jscomp;

import com.google.common.base.Preconditions;
import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceCollection;
import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceMap;
import com.google.javascript.rhino.InputId;
import com.google.javascript.rhino.Node;
Expand Down
1 change: 0 additions & 1 deletion src/com/google/javascript/jscomp/HoistVarsOutOfBlocks.java
Expand Up @@ -16,7 +16,6 @@
package com.google.javascript.jscomp;

import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback;
import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceCollection;
import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceMap;
import com.google.javascript.rhino.IR;
import com.google.javascript.rhino.Node;
Expand Down
1 change: 0 additions & 1 deletion src/com/google/javascript/jscomp/InferConsts.java
Expand Up @@ -16,7 +16,6 @@

package com.google.javascript.jscomp;

import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceCollection;
import com.google.javascript.rhino.JSDocInfo;
import com.google.javascript.rhino.Node;

Expand Down
1 change: 0 additions & 1 deletion src/com/google/javascript/jscomp/InlineObjectLiterals.java
Expand Up @@ -21,7 +21,6 @@
import com.google.common.base.Supplier;
import com.google.common.collect.Lists;
import com.google.javascript.jscomp.ReferenceCollectingCallback.Behavior;
import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceCollection;
import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceMap;
import com.google.javascript.rhino.IR;
import com.google.javascript.rhino.Node;
Expand Down
1 change: 0 additions & 1 deletion src/com/google/javascript/jscomp/InlineVariables.java
Expand Up @@ -21,7 +21,6 @@
import com.google.common.base.Predicates;
import com.google.javascript.jscomp.CodingConvention.SubclassRelationship;
import com.google.javascript.jscomp.ReferenceCollectingCallback.Behavior;
import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceCollection;
import com.google.javascript.jscomp.ReferenceCollectingCallback.ReferenceMap;
import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.TypeI;
Expand Down
212 changes: 0 additions & 212 deletions src/com/google/javascript/jscomp/ReferenceCollectingCallback.java
Expand Up @@ -16,7 +16,6 @@

package com.google.javascript.jscomp;

import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

Expand All @@ -28,7 +27,6 @@
import com.google.javascript.rhino.StaticSymbolTable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -389,214 +387,4 @@ public interface Behavior {
public void afterExitScope(NodeTraversal t, ReferenceMap referenceMap) {}
};

/**
* A collection of references. Can be subclassed to apply checks or
* store additional state when adding.
*/
public static final class ReferenceCollection implements Iterable<Reference> {

List<Reference> references = new ArrayList<>();

@Override
public Iterator<Reference> iterator() {
return references.iterator();
}

void add(Reference reference) {
references.add(reference);
}

/**
* Determines if the variable for this reference collection is
* "well-defined." A variable is well-defined if we can prove at
* compile-time that it's assigned a value before it's used.
*
* Notice that if this function returns false, this doesn't imply that the
* variable is used before it's assigned. It just means that we don't
* have enough information to make a definitive judgment.
*/
protected boolean isWellDefined() {
int size = references.size();
if (size == 0) {
return false;
}

// If this is a declaration that does not instantiate the variable,
// it's not well-defined.
Reference init = getInitializingReference();
if (init == null) {
return false;
}

checkState(references.get(0).isDeclaration());
BasicBlock initBlock = init.getBasicBlock();
for (int i = 1; i < size; i++) {
if (!initBlock.provablyExecutesBefore(
references.get(i).getBasicBlock())) {
return false;
}
}

return true;
}

/**
* Whether the variable is escaped into an inner function.
*/
boolean isEscaped() {
Scope hoistScope = null;
for (Reference ref : references) {
if (hoistScope == null) {
hoistScope = ref.getScope().getClosestHoistScope();
} else if (hoistScope != ref.getScope().getClosestHoistScope()) {
return true;
}
}
return false;
}

/**
* @param index The index into the references array to look for an
* assigning declaration.
*
* This is either the declaration if a value is assigned (such as
* "var a = 2", "function a()...", "... catch (a)...").
*/
private boolean isInitializingDeclarationAt(int index) {
Reference maybeInit = references.get(index);
if (maybeInit.isInitializingDeclaration()) {
// This is a declaration that represents the initial value.
// Specifically, var declarations without assignments such as "var a;"
// are not.
return true;
}
return false;
}

/**
* @param index The index into the references array to look for an
* initialized assignment reference. That is, an assignment immediately
* follow a variable declaration that itself does not initialize the
* variable.
*/
private boolean isInitializingAssignmentAt(int index) {
if (index < references.size() && index > 0) {
Reference maybeDecl = references.get(index - 1);
if (maybeDecl.isVarDeclaration() || maybeDecl.isLetDeclaration()) {
checkState(!maybeDecl.isInitializingDeclaration());
Reference maybeInit = references.get(index);
if (maybeInit.isSimpleAssignmentToName()) {
return true;
}
}
}
return false;
}

/**
* @return The reference that provides the value for the variable at the
* time of the first read, if known, otherwise null.
*
* This is either the variable declaration ("var a = ...") or first
* reference following the declaration if it is an assignment.
*/
Reference getInitializingReference() {
if (isInitializingDeclarationAt(0)) {
return references.get(0);
} else if (isInitializingAssignmentAt(1)) {
return references.get(1);
}
return null;
}

/**
* Constants are allowed to be defined after their first use.
*/
Reference getInitializingReferenceForConstants() {
int size = references.size();
for (int i = 0; i < size; i++) {
if (isInitializingDeclarationAt(i) || isInitializingAssignmentAt(i)) {
return references.get(i);
}
}
return null;
}

/**
* @return Whether the variable is only assigned a value once for its
* lifetime.
*/
boolean isAssignedOnceInLifetime() {
Reference ref = getOneAndOnlyAssignment();
if (ref == null) {
return false;
}

// Make sure this assignment is not in a loop or an enclosing function.
for (BasicBlock block = ref.getBasicBlock();
block != null; block = block.getParent()) {
if (block.isFunction()) {
if (ref.getSymbol().getScope().getClosestHoistScope()
!= ref.getScope().getClosestHoistScope()) {
return false;
}
break;
} else if (block.isLoop()) {
return false;
}
}

return true;
}

/**
* @return The one and only assignment. Returns null if the number of assignments is not
* exactly one.
*/
private Reference getOneAndOnlyAssignment() {
Reference assignment = null;
int size = references.size();
for (int i = 0; i < size; i++) {
Reference ref = references.get(i);
if (ref.isLvalue() || ref.isInitializingDeclaration()) {
if (assignment == null) {
assignment = ref;
} else {
return null;
}
}
}
return assignment;
}

/**
* @return Whether the variable is never assigned a value.
*/
boolean isNeverAssigned() {
int size = references.size();
for (int i = 0; i < size; i++) {
Reference ref = references.get(i);
if (ref.isLvalue() || ref.isInitializingDeclaration()) {
return false;
}
}
return true;
}

boolean firstReferenceIsAssigningDeclaration() {
int size = references.size();
return size > 0 && references.get(0).isInitializingDeclaration();
}

@Override
public String toString() {
return toStringHelper(this)
.add("initRef", getInitializingReference())
.add("references", references)
.add("wellDefined", isWellDefined())
.add("assignedOnce", isAssignedOnceInLifetime())
.toString();
}
}

}

0 comments on commit 7580f65

Please sign in to comment.