001 /* Copyright 2000, 2001, Compaq Computer Corporation */
002
003 package escjava.translate;
004
005 import javafe.util.ClipPolicy;
006 import escjava.ast.TagConstants;
007
008 public class AssocDeclClipPolicy extends ClipPolicy {
009
010 public boolean containsEndOfConstruct(/*@ non_null @*/ String s, int pos) {
011 if (s.startsWith(TagConstants.toString(TagConstants.NON_NULL), pos) ||
012 s.startsWith(TagConstants.toString(TagConstants.UNINITIALIZED), pos) ||
013 (s.startsWith(TagConstants.toString(TagConstants.MONITORED), pos) &&
014 !s.startsWith(TagConstants.toString(TagConstants.MONITORED_BY),
015 pos))) {
016 return true;
017 }
018
019 // look forward
020 FORWARD:
021 for (int i = pos; i < s.length(); i++) {
022 char ch = s.charAt(i);
023 // System.out.println("DEBUG: FORWARD ch='" + ch + "'");
024 if (ch == '\"') {
025 // Find end of string literal.
026 do {
027 i = s.indexOf('\"', i+1);
028 if (i == -1) {
029 // Something's strange is going on; this should never happen.
030 // End the forward search
031 break FORWARD;
032 }
033 // check the character at i-1 for being a backslash
034 } while (s.charAt(i-1) == '\\');
035 } else if (ch == '\'') {
036 // Find end of character literal
037 // The following loop should never execute more than twice.
038 do {
039 i = s.indexOf('\'', i+1);
040 if (i == -1) {
041 // Something's strange is going on; this should never happen.
042 // End the forward search
043 break FORWARD;
044 }
045 // check the character at i-1 for being a backslash
046 } while (s.charAt(i-1) == '\\');
047 } else if (ch == '\\') {
048 // escape character
049 i++; // This will skip over one of the escaped characters, but that's
050 // good enough even if there's more than one escaped character.
051 } else if (ch == ';') {
052 // This indicates the end of the pragma
053 return true;
054 } else if (s.startsWith("//", i)) {
055 // The rest of the line is a comment, so we have not yet found the end
056 // of the current construct.
057 break FORWARD;
058 } else if (s.startsWith("/*", i)) {
059 int k = s.indexOf("*/", i+2);
060 if (k == -1) {
061 // This should never happen.
062 break FORWARD;
063 }
064 // skip nested comment
065 i = k+1 /* +1 as will be done by the 'for' loop */;
066 } else if (s.startsWith("*/", i) || s.startsWith("</esc>", i)) {
067 return true;
068 }
069 }
070
071 // look backward (but if we reach character 0, we have no hope, so let's
072 // loop back only until 1; this also means that we can use i-1 as an index
073 // inside the loop body)
074 for (int i = pos; 1 <= --i; ) {
075 char ch = s.charAt(i);
076 // System.out.println("DEBUG: BACKWARD ch='" + ch + "'");
077 if (ch == '/') {
078 if (s.charAt(i-1) == '/') {
079 // the pragma ends at end-of-line
080 return true;
081 }
082 } else if (ch == '\"') {
083 // Search backwards for the beginning of the string literal.
084 do {
085 i = s.lastIndexOf('\"', i-1);
086 if (i == -1) {
087 // This should never happen. Since things seem screwed up, let's just
088 // return 'true', which will have the effect of not introducing an
089 // ellipsis (which would probably just confuse the user even more).
090 return true;
091 }
092 } while (0 < i && s.charAt(i-1) == '\\');
093 } else if (ch == '\'') {
094 // Search backwards for the beginning of the character literal.
095 // The following loop should never execute more than twice.
096 do {
097 i = s.lastIndexOf('\'', i-1);
098 if (i == -1) {
099 // This should never happen. Since things seem screwed up, let's just
100 // return 'true', which will have the effect of not introducing an
101 // ellipsis (which would probably just confuse the user even more).
102 return true;
103 }
104 } while (0 < i && s.charAt(i-1) == '\\');
105 } else if (s.startsWith("*/", i-1) ||
106 (2 <= i && s.startsWith("*/*", i-2))) {
107 // This must be a nested /*...*/-comment (in the second case, it's
108 // a nested comment followed by a "*"), which is legal only inside
109 // a //-comment, so we might as well end our search now.
110 return true;
111 } else if (s.startsWith("/*", i-1)) {
112 // We are now looking at either the start of the comment.
113 // So, as far as we can tell, the construct may spill over
114 // to the next line.
115 return false;
116 } else if (4 <= i && s.startsWith("<esc>", i-4)) {
117 // The begin-comment marker must have been "/*", because if it
118 // were "//" we would have found the "</esc>" in the forward loop
119 // above. So, as far as we can tell, the construct may spill over
120 // to the next line.
121 return false;
122 }
123 }
124
125 // We have been unable to determine that the construct ends on this line
126 return false;
127 }
128 }