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:
042: package org.netbeans.modules.cnd.modelimpl.csm;
043:
044: import org.netbeans.modules.cnd.api.model.*;
045: import antlr.collections.AST;
046: import java.io.DataInput;
047: import java.io.DataOutput;
048: import java.io.IOException;
049: import org.netbeans.modules.cnd.api.model.util.CsmKindUtilities;
050: import org.netbeans.modules.cnd.modelimpl.parser.CsmAST;
051: import org.netbeans.modules.cnd.modelimpl.csm.core.*;
052: import org.netbeans.modules.cnd.modelimpl.repository.PersistentUtils;
053: import org.netbeans.modules.cnd.modelimpl.uid.UIDCsmConverter;
054: import org.netbeans.modules.cnd.modelimpl.uid.UIDObjectFactory;
055: import org.netbeans.modules.cnd.utils.cache.CharSequenceKey;
056: import org.netbeans.modules.cnd.modelimpl.textcache.NameCache;
057:
058: /**
059: * Implements CsmUsingDeclaration
060: * @author Vladimir Kvasihn
061: */
062: public class UsingDeclarationImpl extends
063: OffsetableDeclarationBase<CsmUsingDeclaration> implements
064: CsmUsingDeclaration, RawNamable {
065:
066: private final CharSequence name;
067: private final int startOffset;
068: private final CharSequence[] rawName;
069: // TODO: don't store declaration here since the instance might change
070: private CsmUID<CsmDeclaration> referencedDeclarationUID = null;
071:
072: public UsingDeclarationImpl(AST ast, CsmFile file) {
073: super (ast, file);
074: name = NameCache.getManager().getString(ast.getText());
075: // TODO: here we override startOffset which is not good because startPosition is now wrong
076: startOffset = ((CsmAST) ast.getFirstChild()).getOffset();
077: rawName = AstUtil.getRawNameInChildren(ast);
078: }
079:
080: public CsmDeclaration getReferencedDeclaration() {
081: return getReferencedDeclaration(null);
082: }
083:
084: public CsmDeclaration getReferencedDeclaration(Resolver resolver) {
085: // TODO: process preceding aliases
086: // TODO: process non-class elements
087: // if (!Boolean.getBoolean("cnd.modelimpl.resolver"))
088: CsmDeclaration referencedDeclaration = _getReferencedDeclaration();
089: if (referencedDeclaration == null) {
090: _setReferencedDeclaration(null);
091: ProjectBase prjBase = ((ProjectBase) getProject());
092: referencedDeclaration = prjBase.findClassifier(name, true);
093: if (referencedDeclaration == null && rawName != null
094: && rawName.length > 1) {
095: // resolve all before last ::
096: CharSequence[] partial = new CharSequence[rawName.length - 1];
097: System.arraycopy(rawName, 0, partial, 0,
098: rawName.length - 1);
099: CsmObject result = ResolverFactory.createResolver(
100: getContainingFile(), startOffset, resolver)
101: .resolve(partial, Resolver.NAMESPACE);
102: if (CsmKindUtilities.isNamespace(result)) {
103: CharSequence lastName = rawName[rawName.length - 1];
104: CsmDeclaration bestChoice = null;
105: for (CsmDeclaration elem : ((CsmNamespace) result)
106: .getDeclarations()) {
107: if (CharSequenceKey.Comparator.compare(
108: lastName, elem.getName()) == 0) {
109: if (!CsmKindUtilities
110: .isExternVariable(elem)) {
111: referencedDeclaration = elem;
112: break;
113: } else {
114: bestChoice = elem;
115: }
116: }
117: }
118: referencedDeclaration = referencedDeclaration == null ? bestChoice
119: : referencedDeclaration;
120: }
121: }
122: _setReferencedDeclaration(referencedDeclaration);
123: }
124: return referencedDeclaration;
125: }
126:
127: private CsmDeclaration _getReferencedDeclaration() {
128: CsmDeclaration referencedDeclaration = UIDCsmConverter
129: .UIDtoDeclaration(referencedDeclarationUID);
130: // can be null if namespace was removed
131: return referencedDeclaration;
132: }
133:
134: private void _setReferencedDeclaration(
135: CsmDeclaration referencedDeclaration) {
136: this .referencedDeclarationUID = UIDCsmConverter
137: .declarationToUID(referencedDeclaration);
138: assert this .referencedDeclarationUID != null
139: || referencedDeclaration == null;
140: }
141:
142: @Override
143: public int getStartOffset() {
144: return startOffset;
145: }
146:
147: public CsmDeclaration.Kind getKind() {
148: return CsmDeclaration.Kind.USING_DECLARATION;
149: }
150:
151: public CharSequence getName() {
152: return name;
153: }
154:
155: public CharSequence getQualifiedName() {
156: return getName();
157: }
158:
159: public CharSequence[] getRawName() {
160: return rawName;
161: }
162:
163: public CsmScope getScope() {
164: //TODO: implement!
165: return null;
166: }
167:
168: ////////////////////////////////////////////////////////////////////////////
169: // iml of SelfPersistent
170:
171: @Override
172: public void write(DataOutput output) throws IOException {
173: super .write(output);
174: assert this .name != null;
175: output.writeUTF(this .name.toString());
176: output.writeInt(this .startOffset);
177: PersistentUtils.writeStrings(this .rawName, output);
178:
179: // save cached declaration
180: UIDObjectFactory.getDefaultFactory().writeUID(
181: this .referencedDeclarationUID, output);
182: }
183:
184: public UsingDeclarationImpl(DataInput input) throws IOException {
185: super (input);
186: this .name = NameCache.getManager().getString(input.readUTF());
187: assert this .name != null;
188: this .startOffset = input.readInt();
189: this .rawName = PersistentUtils.readStrings(input, NameCache
190: .getManager());
191:
192: // read cached declaration
193: this.referencedDeclarationUID = UIDObjectFactory
194: .getDefaultFactory().readUID(input);
195: }
196: }
|