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 }