package com.redhat.ceylon.eclipse.code.refactor; import static com.redhat.ceylon.compiler.typechecker.tree.TreeUtil.formatPath; import static com.redhat.ceylon.eclipse.util.Nodes.getImportedName; import java.util.HashSet; import java.util.List; import java.util.Set; import com.redhat.ceylon.compiler.typechecker.tree.CustomTree.GuardedVariable; import com.redhat.ceylon.compiler.typechecker.tree.Node; import com.redhat.ceylon.compiler.typechecker.tree.Tree; import com.redhat.ceylon.compiler.typechecker.tree.Visitor; import com.redhat.ceylon.model.typechecker.model.Constructor; import com.redhat.ceylon.model.typechecker.model.Declaration; import com.redhat.ceylon.model.typechecker.model.Module; import com.redhat.ceylon.model.typechecker.model.Package; import com.redhat.ceylon.model.typechecker.model.Parameter; import com.redhat.ceylon.model.typechecker.model.Referenceable; import com.redhat.ceylon.model.typechecker.model.Setter; import com.redhat.ceylon.model.typechecker.model.Type; import com.redhat.ceylon.model.typechecker.model.TypedDeclaration; import com.redhat.ceylon.model.typechecker.model.Value; @Deprecated /** * @deprecated see com.redhat.ceylon.ide.common.util.FindReferencesVisitor */ class FindReferencesVisitor extends Visitor { protected Referenceable declaration; protected final Set<Node> nodes = new HashSet<Node>(); public FindReferencesVisitor(Referenceable declaration) { if (declaration instanceof Value) { Value value = originalDeclaration((Value) declaration); declaration = value; if (value.isParameter()) { Declaration dec = value.getInitializerParameter() .getDeclaration(); if (dec instanceof Setter) { Setter setter = (Setter) dec; Value getter = setter.getGetter(); declaration = getter!=null ? getter : setter; } } } else if (declaration instanceof Setter) { Setter setter = (Setter) declaration; Value getter = setter.getGetter(); if (getter!=null) { declaration = setter.getGetter(); } } else if (declaration instanceof Constructor) { Constructor constructor = (Constructor) declaration; if (constructor.getName()==null) { //default constructor Type extended = constructor.getExtendedType(); if (extended!=null) { declaration = extended.getDeclaration(); } } } this.declaration = declaration; } private Value originalDeclaration(Value declaration) { TypedDeclaration original = declaration; while (original!=null && original!=declaration && original instanceof Value) { declaration = (Value) original; original = declaration.getOriginalDeclaration(); } return declaration; } public Referenceable getDeclaration() { return declaration; } public Set<Node> getNodes() { return nodes; } protected boolean isReference(Parameter param) { return param!=null && isReference(param.getModel()); } protected boolean isReference(Declaration ref) { if (ref!=null) { //include references to things that the //selected declaration refines, and refs //within setters return isRefinedDeclarationReference(ref) || isSetterParameterReference(ref); } else { return false; } } protected boolean isRefinedDeclarationReference(Declaration ref) { if (declaration instanceof Declaration) { Declaration dec = (Declaration) declaration; return dec.refines(ref); } else { return false; } } private boolean isSetterParameterReference(Declaration ref) { if (ref instanceof Value && ref.isParameter()) { Value value = (Value) ref; Declaration dec = value.getInitializerParameter() .getDeclaration(); if (dec instanceof Setter) { Setter setter = (Setter) dec; return isReference(setter) || isReference(setter.getGetter()); } else { return false; } } else { return false; } } protected boolean isReference(Declaration ref, String id) { return isReference(ref); } private Tree.Variable getConditionVariable(Tree.Condition c) { //NOTE: returns null for a destructuring condition! if (c instanceof Tree.ExistsOrNonemptyCondition) { Tree.ExistsOrNonemptyCondition eonc = (Tree.ExistsOrNonemptyCondition) c; Tree.Statement st = eonc.getVariable(); if (st instanceof Tree.Variable) { return (Tree.Variable) st; } } if (c instanceof Tree.IsCondition) { Tree.IsCondition ic = (Tree.IsCondition) c; return ic.getVariable(); } return null; } @Override public void visit(Tree.CaseClause that) { Tree.CaseItem ci = that.getCaseItem(); if (ci instanceof Tree.IsCase) { Tree.IsCase ic = (Tree.IsCase) ci; Tree.Variable var = ic.getVariable(); if (var!=null) { Value vd = var.getDeclarationModel(); TypedDeclaration od = vd.getOriginalDeclaration(); if (od!=null && od.equals(declaration)) { Referenceable d = declaration; declaration = vd; if (that.getBlock()!=null) { that.getBlock().visit(this); } if (that.getExpression()!=null) { that.getExpression().visit(this); } declaration = d; return; } } } super.visit(that); } @Override public void visit(Tree.WhileClause that) { Tree.ConditionList cl = that.getConditionList(); List<Tree.Condition> conditions = cl.getConditions(); for (int i=0; i<conditions.size(); i++) { Tree.Condition c = conditions.get(i); Tree.Variable var = getConditionVariable(c); if (var!=null && var.getType() instanceof Tree.SyntheticVariable) { Value vd = var.getDeclarationModel(); TypedDeclaration od = vd.getOriginalDeclaration(); if (od!=null && od.equals(declaration)) { for (int j=0; j<=i; j++) { Tree.Condition oc = conditions.get(j); oc.visit(this); } Referenceable d = declaration; declaration = vd; that.getBlock().visit(this); for (int j=i; j<conditions.size(); j++) { Tree.Condition oc = conditions.get(j); oc.visit(this); } declaration = d; return; } } } super.visit(that); } @Override public void visit(Tree.IfClause that) { Tree.ConditionList cl = that.getConditionList(); List<Tree.Condition> conditions = cl.getConditions(); for (int i=0; i<conditions.size(); i++) { Tree.Condition c = conditions.get(i); Tree.Variable var = getConditionVariable(c); if (var!=null && var.getType() instanceof Tree.SyntheticVariable) { Value vd = var.getDeclarationModel(); TypedDeclaration od = vd.getOriginalDeclaration(); if (od!=null && od.equals(declaration)) { for (int j=0; j<=i; j++) { Tree.Condition oc = conditions.get(j); oc.visit(this); } Referenceable d = declaration; declaration = vd; if (that.getBlock()!=null) { that.getBlock().visit(this); } if (that.getExpression()!=null) { that.getExpression().visit(this); } for (int j=i+1; j<conditions.size(); j++) { Tree.Condition oc = conditions.get(j); oc.visit(this); } declaration = d; return; } } } super.visit(that); } @Override public void visit(Tree.ElseClause that) { Tree.Variable var = that.getVariable(); if (var!=null) { Value vd = var.getDeclarationModel(); TypedDeclaration od = vd.getOriginalDeclaration(); if (od!=null && od.equals(declaration)) { Referenceable d = declaration; declaration = vd; if (that.getBlock()!=null) { that.getBlock().visit(this); } if (that.getExpression()!=null) { that.getExpression().visit(this); } declaration = d; return; } } super.visit(that); } @Override public void visit(Tree.Variable that) { if (that instanceof GuardedVariable) { Value d = that.getDeclarationModel(); TypedDeclaration od = d.getOriginalDeclaration(); if (od!=null && od.equals(declaration)) { declaration = d; } } else { super.visit(that); } } @Override public void visit(Tree.Body body) { Referenceable d = declaration; for (Tree.Statement st: body.getStatements()) { if (st instanceof Tree.Assertion) { Tree.Assertion that = (Tree.Assertion) st; Tree.ConditionList cl = that.getConditionList(); for (Tree.Condition c: cl.getConditions()) { Tree.Variable var = getConditionVariable(c); if (var!=null && var.getType() instanceof Tree.SyntheticVariable) { Value vd = var.getDeclarationModel(); TypedDeclaration od = vd.getOriginalDeclaration(); if (od!=null && od.equals(declaration)) { c.visit(this); declaration = vd; break; } } } } st.visit(this); } declaration = d; } @Override public void visit(Tree.ExtendedTypeExpression that) {} @Override public void visit(Tree.StaticMemberOrTypeExpression that) { if (isReference(that.getDeclaration(), id(that.getIdentifier()))) { nodes.add(that); } super.visit(that); } public void visit(Tree.MemberLiteral that) { if (isReference(that.getDeclaration(), id(that.getIdentifier()))) { nodes.add(that); } super.visit(that); } @Override public void visit(Tree.TypedArgument that) { if (isReference(that.getParameter())) { nodes.add(that); } super.visit(that); } @Override public void visit(Tree.SpecifiedArgument that) { if (that.getIdentifier()!=null && that.getIdentifier().getToken()!=null && isReference(that.getParameter())) { nodes.add(that); } super.visit(that); } @Override public void visit(Tree.SimpleType that) { Type type = that.getTypeModel(); if (type!=null && isReference(type.getDeclaration(), id(that.getIdentifier()))) { nodes.add(that); } super.visit(that); } @Override public void visit(Tree.ImportMemberOrType that) { if (isReference(that.getDeclarationModel())) { nodes.add(that); } super.visit(that); } @Override public void visit(Tree.Import that) { super.visit(that); if (declaration instanceof Package) { if (formatPath(that.getImportPath().getIdentifiers()) .equals(declaration.getNameAsString())) { nodes.add(that); } } } @Override public void visit(Tree.ImportModule that) { super.visit(that); if (declaration instanceof Module) { String path = getImportedName(that); if (path!=null && path.equals(declaration.getNameAsString())) { nodes.add(that); } } } @Override public void visit(Tree.InitializerParameter that) { if (isReference(that.getParameterModel())) { nodes.add(that); } else { super.visit(that); } } @Override public void visit(Tree.TypeConstraint that) { if (isReference(that.getDeclarationModel())) { nodes.add(that); } else { super.visit(that); } } private String id(Tree.Identifier that) { return that==null ? null : that.getText(); } }