Changeset 1567fcce2711ee19e98902f8ef734f1a7dd9731f
- Timestamp:
- 06/28/09 23:36:50 (14 months ago)
- Author:
- mb0 <mb0@…>
- Children:
- b32f7a496c511e07158f0d0752addedc2b378328
- Parents:
- 364575fc79ca0a2d7d0efbd5c165c1d2dfc36a3b
- git-author:
- mb0 <mb0@…> (06/11/09 05:29:42)
- git-committer:
- mb0 <mb0@…> (06/28/09 23:36:50)
- Message:
-
content proposer uses new parse stream when using backup ast.
if there is an error we can still collect accurate token information.
- Files:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r49cbb50
|
r1567fcc
|
|
| 28 | 28 | import org.eclipse.imp.editor.SourceProposal; |
| 29 | 29 | import org.eclipse.imp.parser.IParseController; |
| | 30 | import org.eclipse.imp.parser.IParser; |
| 30 | 31 | import org.eclipse.imp.services.IContentProposer; |
| 31 | | import org.eclipse.jface.text.BadLocationException; |
| 32 | 32 | import org.eclipse.jface.text.ITextViewer; |
| 33 | 33 | import org.eclipse.jface.text.contentassist.ICompletionProposal; |
| … |
… |
|
| 38 | 38 | |
| 39 | 39 | private boolean offsetWithinToken; |
| 40 | | private boolean usingBackup; |
| 41 | 40 | private int offset; |
| 42 | 41 | private AS3ParseController control; |
| … |
… |
|
| 56 | 55 | private ITextViewer viewer; |
| 57 | 56 | |
| 58 | | private boolean dontTrustTokens; |
| | 57 | private boolean usingBackup; |
| 59 | 58 | |
| 60 | 59 | private int originalOffset; |
| 61 | 60 | |
| 62 | | private boolean offsetBeforeToken; |
| 63 | 61 | |
| 64 | 62 | private int offsetDiff; |
| … |
… |
|
| 67 | 65 | |
| 68 | 66 | private void clear() { |
| 69 | | offsetWithinToken = offsetAfterToken = offsetBeforeToken = nextIsSemi = false; |
| 70 | | usingBackup = dontTrustTokens = false; |
| | 67 | offsetWithinToken = offsetAfterToken = nextIsSemi = false; |
| 71 | 68 | prefix = null; |
| 72 | 69 | ancestors = null; |
| 73 | 70 | token = previous = next = null; |
| 74 | | ast = node = null; |
| 75 | | originalOffset = offset; |
| | 71 | node = null; |
| 76 | 72 | } |
| 77 | 73 | |
| 78 | 74 | public AS3ContentProposer() { |
| 79 | | } |
| 80 | | private boolean tokenIsValid(IToken t) { |
| 81 | | String text = t.toString(); |
| 82 | | try { |
| 83 | | String string = viewer.getDocument().get(t.getStartOffset(), text.length()); |
| 84 | | return text.equals(string); |
| 85 | | } catch (BadLocationException e) { |
| 86 | | AS3Plugin.getDefault().debug("error validating token", e); |
| 87 | | } |
| 88 | | return false; |
| 89 | | } |
| 90 | | private String tokenIsValid(IToken t, int diff, int lendiff) { |
| 91 | | try { |
| 92 | | String text = t.toString(); |
| 93 | | int offset = t.getStartOffset()+diff; |
| 94 | | int length = text.length()+lendiff; |
| 95 | | String string = viewer.getDocument().get(offset, length); |
| 96 | | if (lendiff>0) { |
| 97 | | if (string.startsWith(text)) { |
| 98 | | return string; |
| 99 | | } |
| 100 | | } else if (diff != 0) { |
| 101 | | if (text.equals(string)) |
| 102 | | return string; |
| 103 | | } |
| 104 | | } catch (Exception e) { |
| 105 | | AS3Plugin.getDefault().debug("error validating token", e); |
| 106 | | } |
| 107 | | return null; |
| 108 | 75 | } |
| 109 | 76 | protected boolean collectInfo(IParseController controller, int offset, ITextViewer viewer) { |
| … |
… |
|
| 112 | 79 | this.offset = offset; |
| 113 | 80 | offsetDiff = offset - originalOffset; |
| | 81 | usingBackup = false; |
| | 82 | ast = null; |
| 114 | 83 | ASTNode newast = getAst(); |
| 115 | 84 | if (newast != null && newast == ast) { |
| 116 | 85 | AS3Plugin.getDefault().debug("using old ast nothing changed"); |
| 117 | 86 | return true; |
| | 87 | } |
| | 88 | IParser parser = control.getParser(); |
| | 89 | IPrsStream stream = parser.getIPrsStream(); |
| | 90 | if (stream == null) { |
| | 91 | AS3Plugin.getDefault().debug("no error lexing."); |
| | 92 | return false; |
| 118 | 93 | } |
| 119 | 94 | if (newast == null) { |
| … |
… |
|
| 125 | 100 | } |
| 126 | 101 | newast = (ASTNode) backupAst; |
| 127 | | String validPrefix = tokenIsValid(token,0,offsetDiff); |
| 128 | | if (validPrefix != null) { |
| 129 | | if (offsetDiff>0) { |
| 130 | | boolean previousIsValid = tokenIsValid(previous); |
| 131 | | boolean nextIsValid = null != tokenIsValid(next,offsetDiff,0); |
| 132 | | if (previousIsValid && nextIsValid) { |
| 133 | | prefix = validPrefix; |
| 134 | | dontTrustTokens = true; |
| 135 | | this.offset = offset; |
| 136 | | AS3Plugin.getDefault().debug("recovery ok."); |
| 137 | | return true; |
| 138 | | } |
| 139 | | } |
| 140 | | } |
| 141 | | return false; |
| | 102 | usingBackup = true; |
| | 103 | } else { |
| | 104 | originalOffset = offset; |
| 142 | 105 | } |
| 143 | 106 | clear(); |
| 144 | 107 | try { |
| 145 | 108 | ast = newast; |
| 146 | | IPrsStream stream = control.getParser().getIPrsStream(); |
| 147 | | int index = stream.getTokenIndexAtCharacter(offset); |
| | 109 | int myOffset = offset; |
| | 110 | int index = stream.getTokenIndexAtCharacter(myOffset); |
| 148 | 111 | token = getToken(stream, index < 0 ? -index + 1: index); |
| 149 | 112 | previous = getToken(stream, token.getTokenIndex()-1); |
| 150 | | if (previous.getEndOffset() == offset - 1) { |
| 151 | | offsetAfterToken = true; |
| | 113 | offsetAfterToken = previous.getEndOffset() == myOffset - 1; |
| | 114 | if (offsetAfterToken || token.getKind() == Sym.TK_SEMI |
| | 115 | || (myOffset < token.getStartOffset()&& stream.getILexStream().getLineNumberOfCharAt(myOffset) < token.getLine())) { |
| 152 | 116 | next = token; |
| 153 | 117 | token = previous; |
| 154 | 118 | previous = stream.getIToken(token.getTokenIndex()-1); |
| 155 | | } else { |
| | 119 | } |
| | 120 | if (next == null){ |
| 156 | 121 | next = stream.getIToken(stream.getNext(token.getTokenIndex())); |
| 157 | 122 | } |
| 158 | 123 | nextIsSemi = next.getKind() == Sym.TK_SEMI; |
| 159 | | offsetWithinToken = Sym.isWithinToken(offset, token); |
| 160 | | offsetBeforeToken = offset < token.getStartOffset(); |
| | 124 | offsetWithinToken = Sym.isWithinToken(myOffset, token); |
| 161 | 125 | if ((offsetAfterToken||offsetWithinToken) && Sym.isKeyword(token)) |
| 162 | 126 | return false; |
| 163 | | this.prefix = offsetWithinToken ? Sym.getPrefix(offset, token) |
| | 127 | this.prefix = offsetWithinToken ? Sym.getPrefix(myOffset, token) |
| 164 | 128 | : ( offsetAfterToken ? token.toString() : ""); |
| 165 | 129 | node = getNode(token); |
| … |
… |
|
| 229 | 193 | // in package header |
| 230 | 194 | IName nameNode = packdef.getName(); |
| 231 | | prefix = fetchName((IAst) nameNode); |
| | 195 | if (!usingBackup) |
| | 196 | prefix = fetchName((IAst) nameNode); |
| 232 | 197 | IResource project = control.getProject().getResource(); |
| 233 | 198 | String expectedName = AS3Util.getExpectedPackageName(project,project.getFullPath().append(control.getPath())); |
| … |
… |
|
| 236 | 201 | } else { |
| 237 | 202 | proposals.addUnitScopeProposals(node); |
| 238 | | if (prefix.startsWith("import")) { |
| | 203 | boolean isImport = token.getKind() == Sym.TK_import; |
| | 204 | if (isImport || prefix.startsWith("import")) { |
| 239 | 205 | for (String packname:Index0r.getInstance().getPackageNames()) { |
| 240 | | proposals.addSourceProposal("import "+packname+".*", prefix, ImportDirective.class, !nextIsSemi); |
| | 206 | String proposed = (isImport ? "":"import ")+packname+".*"; |
| | 207 | proposals.addSourceProposal(proposed, prefix, ImportDirective.class, !nextIsSemi); |
| 241 | 208 | } |
| 242 | 209 | } |
| … |
… |
|
| 244 | 211 | } else if (ancestor instanceof ImportDirective) { |
| 245 | 212 | IName nameNode = ((ImportDirective)ancestor).getName(); |
| 246 | | prefix = fetchName((IAst) nameNode); |
| | 213 | if (!usingBackup) |
| | 214 | prefix = fetchName((IAst) nameNode); |
| 247 | 215 | int dotIndex = prefix.lastIndexOf('.'); |
| 248 | 216 | Collection<String> packageNames = Index0r.getInstance().getPackageNames(); |