blob: d8ff6a713ad6f9ac84781c4c02dd2c7352558ee3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 xored software, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* xored software, Inc. - initial API and Implementation (Alex Panchenko)
*******************************************************************************/
package org.eclipse.dltk.internal.javascript.typeinference;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.dltk.internal.core.ModelElement;
import org.eclipse.dltk.internal.javascript.reference.resolvers.ReferenceResolverContext;
import com.xored.org.mozilla.javascript.Node;
class TransparentRef implements IReference {
private final TypeInferencer typeInferencer;
IReference evaluateReference;
private final String fieldId;
private final Node node;
ReferenceResolverContext cs;
private boolean recursive = false;
TransparentRef(TypeInferencer typeInferencer, IReference evaluateReference,
Node objID, String fieldId, ModelElement parent,
ReferenceResolverContext cs) {
this.typeInferencer = typeInferencer;
this.evaluateReference = evaluateReference;
this.fieldId = fieldId;
this.node = objID;
this.parent = parent;
this.cs = cs;
}
public IReference getChild(String key, boolean resolveLocals) {
if (recursive)
return null;
try {
recursive = true;
IReference child = evaluateReference.getChild(key, resolveLocals);
return child;
} finally {
recursive = false;
}
}
public Set<IReference> getChilds(boolean resolveLocals) {
if (recursive)
return Collections.emptySet();
try {
recursive = true;
return evaluateReference.getChilds(resolveLocals);
} finally {
recursive = false;
}
}
public String getName() {
return fieldId;
}
public String getParentName() {
return fieldId;
}
public void setChild(String key, IReference ref) {
if (recursive)
return;
try {
recursive = true;
evaluateReference.setChild(key, ref);
} finally {
recursive = false;
}
}
public boolean isChildishReference() {
return false;
}
ModelElement parent;
public void patchRef(HostCollection collection) {
if (recursive)
return;
try {
recursive = true;
Set s = evaluateReference.getChilds(false);
IReference queryElement = this.typeInferencer.internalEvaluate(
collection, getName(), node, parent, cs);
if (queryElement != null && queryElement != this) {
// make sure that this doesn't become a transparent to a
// transparent
// (because then circular references can happen)
// just point to the real reference.
while (queryElement instanceof TransparentRef) {
queryElement = ((TransparentRef) queryElement).evaluateReference;
}
if (!(queryElement instanceof CombinedOrReference && ((CombinedOrReference) queryElement)
.testContains(this))) {
this.evaluateReference = queryElement;
}
}
Iterator it = s.iterator();
// TODO REVIEW IT;
while (it.hasNext()) {
Object next = it.next();
if (!(next instanceof IReference))
continue;
IReference r = (IReference) next;
evaluateReference.setChild(r.getName(), r);
}
} finally {
recursive = false;
}
}
public void recordDelete(String fieldId) {
if (recursive)
return;
try {
recursive = true;
evaluateReference.recordDelete(fieldId);
} finally {
recursive = false;
}
}
public IReference getPrototype(boolean resolveLocals) {
if (recursive)
return null;
try {
recursive = true;
return evaluateReference.getPrototype(false);
} finally {
recursive = false;
}
}
public void setPrototype(IReference ref) {
if (recursive)
return;
try {
recursive = true;
evaluateReference.setPrototype(ref);
} finally {
recursive = false;
}
}
int length;
int location;
public void addModelElements(Collection toAdd) {
if (parent != null)
toAdd.add(new FakeField(parent, getName(), location, length));
}
public void setLocationInformation(ModelElement mo, int position, int length) {
this.parent = mo;
this.location = position;
this.length = length;
}
public boolean isFunctionRef() {
if (recursive)
return false;
try {
recursive = true;
return evaluateReference.isFunctionRef();
} finally {
recursive = false;
}
}
public boolean isLocal() {
if (recursive)
return false;
try {
recursive = true;
return evaluateReference.isLocal();
} finally {
recursive = false;
}
}
public void setLocal(boolean local) {
if (recursive)
return;
try {
recursive = true;
evaluateReference.setLocal(local);
} finally {
recursive = false;
}
}
}