package com.redhat.ceylon.eclipse.util; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.ALIAS_REF; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.CASE; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.CATCH; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.CLASS_ALIAS; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.CLASS_REF; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.DOCLINK; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.EXISTS; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.EXPRESSION; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.EXTENDS; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.FUNCTION_REF; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.IMPORT; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.INTERFACE_REF; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.IS; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.META; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.MODULE_REF; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.NONEMPTY; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.OF; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.PACKAGE_REF; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.PARAMETER_LIST; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.SATISFIES; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.TYPE_ALIAS; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.TYPE_ARGUMENT_LIST; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.TYPE_PARAMETER_LIST; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.TYPE_PARAMETER_REF; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.UPPER_BOUND; import static com.redhat.ceylon.ide.common.util.OccurrenceLocation.VALUE_REF; import com.redhat.ceylon.compiler.typechecker.tree.Node; import com.redhat.ceylon.compiler.typechecker.tree.Tree; import com.redhat.ceylon.compiler.typechecker.tree.Tree.QualifiedMemberOrTypeExpression; import com.redhat.ceylon.compiler.typechecker.tree.Tree.Term; import com.redhat.ceylon.compiler.typechecker.tree.Visitor; import com.redhat.ceylon.ide.common.util.OccurrenceLocation; @Deprecated class FindOccurrenceLocationVisitor extends Visitor { private Node node; private int offset; private com.redhat.ceylon.ide.common.util.OccurrenceLocation occurrence; private boolean inTypeConstraint = false; FindOccurrenceLocationVisitor(int offset, Node node) { this.offset = offset; this.node = node; } OccurrenceLocation getOccurrenceLocation() { return occurrence; } @Override public void visitAny(Node that) { if (inBounds(that)) { super.visitAny(that); } //otherwise, as a performance optimization //don't go any further down this branch } @Override public void visit(Tree.Condition that) { if (inBounds(that)) { occurrence = EXPRESSION; } super.visit(that); } @Override public void visit(Tree.ExistsCondition that) { super.visit(that); Tree.Statement var = that.getVariable(); if (var instanceof Tree.Variable ? inBounds(((Tree.Variable)var).getIdentifier()) : inBounds(that)) { occurrence = EXISTS; } } @Override public void visit(Tree.NonemptyCondition that) { super.visit(that); Tree.Statement var = that.getVariable(); if (var instanceof Tree.Variable ? inBounds(((Tree.Variable)var).getIdentifier()) : inBounds(that)) { occurrence = NONEMPTY; } } @Override public void visit(Tree.IsCondition that) { super.visit(that); boolean inBounds; if (that.getVariable()!=null) { inBounds = inBounds(that.getVariable().getIdentifier()); } else if (that.getType()!=null) { inBounds = inBounds(that) && offset>that.getType().getEndIndex(); } else { inBounds = false; } if (inBounds) { occurrence = IS; } } public void visit(Tree.TypeConstraint that) { inTypeConstraint=true; super.visit(that); inTypeConstraint=false; } public void visit(Tree.ImportMemberOrTypeList that) { if (inBounds(that)) { occurrence = IMPORT; } super.visit(that); } public void visit(Tree.ExtendedType that) { if (inBounds(that)) { occurrence = EXTENDS; } super.visit(that); } public void visit(Tree.DelegatedConstructor that) { if (inBounds(that)) { occurrence = EXTENDS; } super.visit(that); } public void visit(Tree.SatisfiedTypes that) { if (inBounds(that)) { occurrence = inTypeConstraint? UPPER_BOUND : SATISFIES; } super.visit(that); } public void visit(Tree.CaseTypes that) { if (inBounds(that)) { occurrence = OF; } super.visit(that); } public void visit(Tree.CatchClause that) { if (inBounds(that) && !inBounds(that.getBlock())) { occurrence = CATCH; } else { super.visit(that); } } public void visit(Tree.CaseItem that) { if (inBounds(that) && (that.getMainEndToken()==null || offset<that.getEndIndex())) { occurrence = CASE; } super.visit(that); } @Override public void visit(Tree.BinaryOperatorExpression that) { Term right = that.getRightTerm(); if (right==null) { right = that; } Term left = that.getLeftTerm(); if (left==null) { left = that; } if (inBounds(left, right)) { occurrence = EXPRESSION; } super.visit(that); } @Override public void visit(Tree.UnaryOperatorExpression that) { Term term = that.getTerm(); if (term==null) { term = that; } if (inBounds(that, term) || inBounds(term, that)) { occurrence = EXPRESSION; } super.visit(that); } @Override public void visit(Tree.ParameterList that) { if (inBounds(that)) { occurrence = PARAMETER_LIST; } super.visit(that); } @Override public void visit(Tree.TypeParameterList that) { if (inBounds(that)) { occurrence = TYPE_PARAMETER_LIST; } super.visit(that); } @Override public void visit(Tree.TypeSpecifier that) { if (inBounds(that)) { occurrence = TYPE_ALIAS; } super.visit(that); } @Override public void visit(Tree.ClassSpecifier that) { if (inBounds(that)) { occurrence = CLASS_ALIAS; } super.visit(that); } @Override public void visit(Tree.SpecifierOrInitializerExpression that) { if (inBounds(that)) { occurrence = EXPRESSION; } super.visit(that); } @Override public void visit(Tree.ArgumentList that) { if (inBounds(that)) { occurrence = EXPRESSION; } super.visit(that); } @Override public void visit(Tree.TypeArgumentList that) { if (inBounds(that)) { occurrence = TYPE_ARGUMENT_LIST; } super.visit(that); } @Override public void visit(QualifiedMemberOrTypeExpression that) { if (inBounds(that.getMemberOperator(), that.getIdentifier())) { occurrence = EXPRESSION; } else { super.visit(that); } } @Override public void visit(Tree.Declaration that) { if (inBounds(that)) { if (occurrence!=PARAMETER_LIST) { occurrence=null; } } super.visit(that); } @Override public void visit(Tree.ObjectExpression that) { if (inBounds(that)) { if (occurrence!=PARAMETER_LIST) { occurrence=null; } } super.visit(that); } @Override public void visit(Tree.FunctionArgument that) { if (inBounds(that)) { if (occurrence!=PARAMETER_LIST) { occurrence=null; } } super.visit(that); } @Override public void visit(Tree.TypedArgument that) { if (inBounds(that)) { if (occurrence!=PARAMETER_LIST) { occurrence=null; } } super.visit(that); } public void visit(Tree.MetaLiteral that) { super.visit(that); if (inBounds(that)) { if (occurrence!=TYPE_ARGUMENT_LIST) { switch (that.getNodeType()) { case "ModuleLiteral": occurrence=MODULE_REF; break; case "PackageLiteral": occurrence=PACKAGE_REF; break; case "ValueLiteral": occurrence=VALUE_REF; break; case "FunctionLiteral": occurrence=FUNCTION_REF; break; case "InterfaceLiteral": occurrence=INTERFACE_REF; break; case "ClassLiteral": occurrence=CLASS_REF; break; case "TypeParameterLiteral": occurrence=TYPE_PARAMETER_REF; break; case "AliasLiteral": occurrence=ALIAS_REF; break; default: occurrence = META; } } } } public void visit(Tree.StringLiteral that) { if (inBounds(that)) { occurrence = DOCLINK; } } public void visit(Tree.DocLink that) { if (this.node instanceof Tree.DocLink) { occurrence = DOCLINK; } } private boolean inBounds(Node that) { return inBounds(that, that); } private boolean inBounds(Node left, Node right) { if (left==null) return false; if (right==null) right=left; Integer startIndex = left.getStartIndex(); Integer endIndex = right.getEndIndex(); return startIndex!=null && endIndex!=null && startIndex <= node.getStartIndex() && endIndex >= node.getEndIndex(); } }