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-2006 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.php.model.impl.refs.resolvers;
042:
043: import java.util.Collections;
044: import java.util.HashSet;
045: import java.util.LinkedList;
046: import java.util.List;
047: import java.util.Set;
048:
049: import org.netbeans.modules.php.model.ClassConst;
050: import org.netbeans.modules.php.model.ClassFunctionDeclaration;
051: import org.netbeans.modules.php.model.ConstDeclaration;
052: import org.netbeans.modules.php.model.InterfaceBody;
053: import org.netbeans.modules.php.model.InterfaceDefinition;
054: import org.netbeans.modules.php.model.InterfaceStatement;
055: import org.netbeans.modules.php.model.Reference;
056: import org.netbeans.modules.php.model.SourceElement;
057:
058: /**
059: * @author ads
060: *
061: */
062: public class InterfaceStaticMemberReferenceResover extends
063: StaticMemberReferenceResolver {
064:
065: /* (non-Javadoc)
066: * @see org.netbeans.modules.php.model.refs.ReferenceResolver#isApplicable(java.lang.Class)
067: */
068: public <T extends SourceElement> boolean isApplicable(Class<T> clazz) {
069: return InterfaceStatement.class.isAssignableFrom(clazz)
070: || ClassConst.class.isAssignableFrom(clazz);
071: }
072:
073: /* (non-Javadoc)
074: * @see org.netbeans.modules.php.model.impl.refs.resolvers.StaticMemberReferenceResolver#getOwnType()
075: */
076: @Override
077: protected Class<? extends SourceElement> getOwnType() {
078: return InterfaceDefinition.class;
079: }
080:
081: /* (non-Javadoc)
082: * @see org.netbeans.modules.php.model.impl.refs.resolvers.StaticMemberReferenceResolver#resolve(org.netbeans.modules.php.model.SourceElement, java.lang.String, java.lang.Class, org.netbeans.modules.php.model.SourceElement, boolean)
083: */
084: @Override
085: protected <T extends SourceElement> List<T> resolve(
086: String memberName, Class<T> clazz, SourceElement owner,
087: boolean exactComparison) {
088: // avoid cyclic references to super interfaces
089: Set<String> set = new HashSet<String>();
090: return resolve(memberName, clazz, owner, exactComparison, set);
091: }
092:
093: protected <T extends SourceElement> List<T> resolve(
094: String memberName, Class<T> clazz, SourceElement owner,
095: boolean exactComparison, Set<String> ifaceNames) {
096: if (!(owner instanceof InterfaceDefinition)) {
097: return Collections.emptyList();
098: }
099: List<T> result = new LinkedList<T>();
100: InterfaceDefinition definition = (InterfaceDefinition) owner;
101: String name = definition.getName();
102: if (ifaceNames.contains(name)) {
103: return Collections.emptyList();
104: } else {
105: ifaceNames.add(name);
106: }
107: InterfaceBody body = definition.getBody();
108: if (body == null) {
109: return Collections.emptyList();
110: }
111: List<InterfaceStatement> statements = body.getStatements();
112: for (InterfaceStatement interfaceStatement : statements) {
113: findInStatement(memberName, interfaceStatement, clazz,
114: result, exactComparison);
115: }
116:
117: if (exactComparison && result.size() > 0) {
118: return result;
119: }
120:
121: List<Reference<InterfaceDefinition>> super Ifaces = definition
122: .getSuperInterfaces();
123: for (Reference<InterfaceDefinition> reference : super Ifaces) {
124: InterfaceDefinition def = reference.get();
125: if (def == null) {
126: continue;
127: }
128: List<T> list = resolve(memberName, clazz, def,
129: exactComparison, ifaceNames);
130: result.addAll(list);
131:
132: if (exactComparison && result.size() > 0) {
133: return result;
134: }
135: }
136: return result;
137: }
138:
139: protected <T extends SourceElement> void handleFunctionDecl(
140: String name, ClassFunctionDeclaration decl, Class<T> clazz,
141: List<T> collected, boolean exactComparison) {
142: if (!clazz.isAssignableFrom(decl.getElementType())) {
143: return;
144: }
145: String declName = decl.getName();
146: if (exactComparison && name.equals(declName)) {
147: collected.add(clazz.cast(decl));
148: }
149: if (!exactComparison && declName.startsWith(name)) {
150: collected.add(clazz.cast(decl));
151: }
152: }
153:
154: protected <T extends SourceElement> void handleConstDecl(
155: String name, ConstDeclaration decl, Class<T> clazz,
156: List<T> collected, boolean exactComparison) {
157: List<ClassConst> consts = decl.getDeclaredConstants();
158: for (ClassConst cnst : consts) {
159: if (!clazz.isAssignableFrom(cnst.getElementType())) {
160: continue;
161: }
162: String attrName = cnst.getName();
163: if (exactComparison && name.equals(attrName)) {
164: collected.add(clazz.cast(cnst));
165: }
166: if (!exactComparison && attrName.startsWith(name)) {
167: collected.add(clazz.cast(cnst));
168: }
169: }
170: }
171:
172: private <T extends SourceElement> void findInStatement(String name,
173: InterfaceStatement statement, Class<T> clazz,
174: List<T> collected, boolean exactComparison) {
175: if (statement.getElementType().equals(
176: ClassFunctionDeclaration.class)) {
177: handleFunctionDecl(name,
178: (ClassFunctionDeclaration) statement, clazz,
179: collected, exactComparison);
180: } else if (statement.getElementType().equals(
181: ConstDeclaration.class)) {
182: handleConstDecl(name, (ConstDeclaration) statement, clazz,
183: collected, exactComparison);
184: }
185: }
186:
187: }
|