/******************************************************************************* * Copyright (c) 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Zend Technologies *******************************************************************************/ package org.eclipse.php.internal.core.typeinference; import org.eclipse.dltk.core.*; import org.eclipse.dltk.internal.core.ModelElement; import org.eclipse.php.core.compiler.PHPFlags; import org.eclipse.php.internal.core.PHPCorePlugin; public class FakeConstructor extends FakeMethod { /** * the code assist if happens in the class itself for example class Foo{ * function Foo($name){} function clone(){return new Foo("foo")} } */ private boolean isEnclosingClass; public FakeConstructor(ModelElement parent, String name, int offset, int length, int nameOffset, int nameLength, boolean isEnclosingClass) { super(parent, name, offset, length, nameOffset, nameLength); this.isEnclosingClass = isEnclosingClass; } public boolean isConstructor() throws ModelException { return true; } public boolean isEnclosingClass() { return isEnclosingClass; } public void setEnclosingClass(boolean isEnclosingClass) { this.isEnclosingClass = isEnclosingClass; } public static FakeConstructor createFakeConstructor(IMethod ctor, IType type, boolean isEnclosingClass) { ISourceRange sourceRange; try { sourceRange = type.getSourceRange(); FakeConstructor ctorMethod = new FakeConstructor((ModelElement) type, type.getElementName(), sourceRange.getOffset(), sourceRange.getLength(), sourceRange.getOffset(), sourceRange.getLength(), isEnclosingClass); if (ctor != null) { ctorMethod.setParameters(ctor.getParameters()); } return ctorMethod; } catch (ModelException e) { PHPCorePlugin.log(e); } return null; } /** * * @param type * @param isEnclosingClass * @return IMethod[] constructors[0] is the type's constructor * constructors[1] is an available FakeConstructor for * constructors[0] both constructors[0] and constructors[1] could be * null */ public static IMethod[] getConstructors(IType type, boolean isEnclosingClass) { IMethod[] constructors = new IMethod[2]; try { constructors = getConstructorsOfType(type, isEnclosingClass); // try to find constructor in super classes if (constructors[0] == null) { ITypeHierarchy newSupertypeHierarchy = type.newSupertypeHierarchy(null); IType[] allSuperclasses = newSupertypeHierarchy.getAllSuperclasses(type); if (allSuperclasses != null && allSuperclasses.length > 0) { for (IType superClass : allSuperclasses) { if (constructors[0] == null) { constructors = getConstructorsOfType(superClass, isEnclosingClass); } else { break; } } } } } catch (ModelException e) { if (!e.isDoesNotExist()) { PHPCorePlugin.log(e); } } return constructors; } private static IMethod[] getConstructorsOfType(IType type, boolean isEnclosingClass) throws ModelException { IMethod[] constructors = new IMethod[2]; IMethod[] methods = type.getMethods(); if (methods != null && methods.length > 0) { for (IMethod method : methods) { if (method.isConstructor() && method.getParameters() != null && method.getParameters().length > 0) { constructors[0] = method; if (isEnclosingClass || !PHPFlags.isPrivate(constructors[0].getFlags())) { constructors[1] = FakeConstructor.createFakeConstructor(constructors[0], type, isEnclosingClass); } } } } return constructors; } }