PageRenderTime 39ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/bundles/plugins-trunk/RubyPlugin/src/org/jedit/ruby/ast/RubyMembers.java

#
Java | 214 lines | 149 code | 31 blank | 34 comment | 42 complexity | 3554fb35c6a6fc4ed3048591e2c8c7c5 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * RubyMembers.java - Represents members in a Ruby file
  3. *
  4. * Copyright 2005 Robert McKinnon
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. */
  20. package org.jedit.ruby.ast;
  21. import java.util.ArrayList;
  22. import java.util.List;
  23. /**
  24. * @author robmckinnon at users.sourceforge.net
  25. */
  26. public final class RubyMembers {
  27. private static final int ROOT = -1;
  28. private final Member[] members;
  29. private List<Member> memberList;
  30. private List<Problem> problems;
  31. private Root rootMember;
  32. public RubyMembers(Member[] memberArray, List<Problem> problems, int textLength) {
  33. members = memberArray;
  34. setProblems(problems);
  35. if (members != null) {
  36. memberList = new ArrayList<Member>();
  37. populateMemberList(memberArray, memberList);
  38. rootMember = new Root(textLength);
  39. }
  40. }
  41. public final void setProblems(List<Problem> problems) {
  42. this.problems = problems;
  43. }
  44. public final boolean containsErrors() {
  45. return members == null;
  46. }
  47. public final Problem[] getProblems() {
  48. return problems.toArray(new Problem[problems.size()]);
  49. }
  50. private void populateMemberList(Member[] members, List<Member> list) {
  51. for(Member member : members) {
  52. list.add(member);
  53. if(member.hasChildMembers()) {
  54. populateMemberList(member.getChildMembers(), list);
  55. }
  56. }
  57. }
  58. /**
  59. * @throws RuntimeException if {@link #containsErrors()} returns true
  60. * @return size
  61. */
  62. public final int size() {
  63. return members.length;
  64. }
  65. public final Member getNextMember(int caretPosition) {
  66. int index = getLastMemberIndexBefore(caretPosition);
  67. if (index == ROOT) {
  68. if(memberList.size() > 0) {
  69. return memberList.get(0);
  70. } else {
  71. return null;
  72. }
  73. } else if (index < memberList.size() - 1) {
  74. return memberList.get(index + 1);
  75. } else {
  76. return null;
  77. }
  78. }
  79. public final Member getPreviousMember(int caretPosition) {
  80. int index = getLastMemberIndexBefore(caretPosition);
  81. Member lastMember = memberList.get(index);
  82. if (index > 0) {
  83. Member member = memberList.get(index - 1);
  84. if (member.getEndOffset() < lastMember.getEndOffset() || caretPosition == lastMember.getStartOffset()) {
  85. return member;
  86. } else {
  87. return lastMember;
  88. }
  89. } else if(lastMember.getStartOffset() < caretPosition) {
  90. return lastMember;
  91. } else {
  92. return null;
  93. }
  94. }
  95. /**
  96. * Returns member at caret position, if caret position
  97. * is outside a Ruby member then the file's {@link Root}
  98. * member is returned.
  99. *
  100. * @param caretPosition caret position
  101. * @return {@link Member} at caret or file {@link Root} member
  102. */
  103. public final Member getMemberAt(int caretPosition) {
  104. int index = getMemberIndexAt(caretPosition);
  105. return index == ROOT ? rootMember : memberList.get(index);
  106. }
  107. public final Member getLastMemberBefore(int caretPosition) {
  108. int index = getLastMemberIndexBefore(caretPosition);
  109. return index == ROOT ? null : memberList.get(index);
  110. }
  111. private int getLastMemberIndexBefore(int caretPosition) {
  112. int lastIndex = memberList.size() - 1;
  113. int memberIndex = ROOT;
  114. for (int i = 0; memberIndex == ROOT && i < memberList.size(); i++) {
  115. Member member = memberList.get(i);
  116. int start = member.getStartOffset();
  117. if (caretPosition >= start) {
  118. if (i < lastIndex) {
  119. Member nextMember = memberList.get(i + 1);
  120. int nextOffset = nextMember.getStartOffset();
  121. if (caretPosition < nextOffset) {
  122. memberIndex = i;
  123. }
  124. } else {
  125. memberIndex = i;
  126. }
  127. }
  128. }
  129. return memberIndex;
  130. }
  131. private int getMemberIndexAt(int caretPosition) {
  132. int memberIndex = ROOT;
  133. for (int i = 0; i < memberList.size(); i++) {
  134. Member member = memberList.get(i);
  135. int offset = member.getStartOuterOffset();
  136. if (caretPosition >= offset && caretPosition <= member.getEndOffset()) {
  137. memberIndex = i;
  138. }
  139. }
  140. return memberIndex;
  141. }
  142. public final Member[] getMembers() {
  143. return members;
  144. }
  145. public final Member[] combineMembersAndProblems(int offsetLimit) {
  146. if (members != null && problems != null) {
  147. List<Member> accesibleMembers = new ArrayList<Member>();
  148. for (Member member : members) {
  149. if(member.getStartOffset() < offsetLimit) {
  150. accesibleMembers.add(member);
  151. }
  152. }
  153. Member[] combined = new Member[accesibleMembers.size() + problems.size()];
  154. int index = 0;
  155. for (Member member : accesibleMembers) {
  156. combined[index++] = member;
  157. }
  158. for (Problem problem : problems) {
  159. combined[index++] = problem;
  160. }
  161. return combined;
  162. } else {
  163. throw new IllegalStateException("Can only call when members and problems are non-null arrays");
  164. }
  165. }
  166. public final Member get(int index) {
  167. return members[index];
  168. }
  169. public final List<Member> getClasses() {
  170. final List<Member> classes = new ArrayList<Member>();
  171. visitMembers(new MemberVisitorAdapter() {
  172. public void handleClass(org.jedit.ruby.ast.ClassMember classMember) {
  173. classes.add(classMember);
  174. }
  175. });
  176. return classes;
  177. }
  178. public final void visitMembers(MemberVisitor visitor) {
  179. for(Member member : memberList) {
  180. member.accept(visitor);
  181. }
  182. }
  183. }