001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.cnd.completion.impl.xref;
042:
043: import java.util.ArrayList;
044: import java.util.EnumSet;
045: import java.util.List;
046: import org.netbeans.editor.BaseDocument;
047: import org.netbeans.modules.cnd.api.model.CsmFile;
048: import org.netbeans.modules.cnd.api.model.CsmOffsetable;
049: import org.netbeans.modules.cnd.api.model.CsmScope;
050: import org.netbeans.modules.cnd.api.model.services.CsmFileReferences;
051: import org.netbeans.modules.cnd.api.model.util.CsmKindUtilities;
052: import org.netbeans.modules.cnd.api.model.xref.CsmReference;
053: import org.netbeans.modules.cnd.api.model.xref.CsmReferenceKind;
054: import org.netbeans.modules.cnd.completion.cplusplus.utils.Token;
055: import org.netbeans.modules.cnd.completion.cplusplus.utils.TokenUtilities;
056: import org.netbeans.modules.cnd.editor.cplusplus.CCTokenContext;
057:
058: /**
059: *
060: * @author Sergey Grinev
061: */
062: public class FileReferencesImpl extends CsmFileReferences {
063:
064: public FileReferencesImpl() {
065: /*System.err.println("FileReferencesImpl registered");
066: CsmModelAccessor.getModel().addProgressListener(new CsmProgressAdapter() {
067:
068: @Override
069: public void fileParsingStarted(CsmFile file) {
070: System.err.println("remove cache for " + file);
071: cache.remove(file);
072: }
073:
074: public @Override void fileInvalidated(CsmFile file) {
075: System.err.println("remove cache for " + file);
076: cache.remove(file);
077: }
078: });*/
079: }
080:
081: // private final Map<CsmFile, List<CsmReference>> cache = new HashMap<CsmFile, List<CsmReference>>();
082:
083: public void accept(CsmScope csmScope, Visitor visitor) {
084: accept(csmScope, visitor, CsmReferenceKind.ALL);
085: }
086:
087: public void accept(CsmScope csmScope, Visitor visitor,
088: EnumSet<CsmReferenceKind> kinds) {
089: if (!CsmKindUtilities.isOffsetable(csmScope)
090: && !CsmKindUtilities.isFile(csmScope)) {
091: return;
092: }
093: CsmFile csmFile = null;
094: int start = 0;
095: int end = Integer.MAX_VALUE;
096: if (CsmKindUtilities.isFile(csmScope)) {
097: csmFile = (CsmFile) csmScope;
098: } else {
099: csmFile = ((CsmOffsetable) csmScope).getContainingFile();
100: start = ((CsmOffsetable) csmScope).getStartOffset();
101: end = ((CsmOffsetable) csmScope).getEndOffset();
102: }
103: for (CsmReference ref : getIdentifierReferences(csmFile, start,
104: end, kinds)) {
105: visitor.visit(ref);
106: }
107: }
108:
109: private List<CsmReference> getIdentifierReferences(CsmFile csmFile,
110: int start, int end, EnumSet<CsmReferenceKind> kinds) {
111: List<CsmReference> out = new ArrayList<CsmReference>();
112: BaseDocument doc = ReferencesSupport.getDocument(csmFile);
113: assert doc != null;
114: boolean needAfterDereferenceUsages = kinds
115: .contains(CsmReferenceKind.AFTER_DEREFERENCE_USAGE);
116: List<Token> tokens = TokenUtilities.getTokens(doc, start, end);
117: Token lastToken = null;
118: for (Token token : tokens) {
119: if (token.getEndOffset() > end) {
120: break;
121: }
122: if (token.getStartOffset() >= start) {
123: if (token.getTokenID() == CCTokenContext.IDENTIFIER) {
124: boolean skip = false;
125:
126: if (!needAfterDereferenceUsages
127: && lastToken != null) {
128: switch (lastToken.getTokenID().getNumericID()) {
129: case CCTokenContext.DOT_ID:
130: case CCTokenContext.DOTMBR_ID:
131: case CCTokenContext.ARROW_ID:
132: case CCTokenContext.ARROWMBR_ID:
133: case CCTokenContext.SCOPE_ID:
134: skip = true;
135: }
136: }
137: if (!skip) {
138: ReferenceImpl ref = ReferencesSupport
139: .createReferenceImpl(csmFile, doc,
140: token.getStartOffset(), token);
141: out.add(ref);
142: }
143: }
144: }
145: lastToken = token;
146: }
147: return out;
148: }
149: }
|