protected void getGoalFromStaticDeclaration( String variableName, final List<IGoal> subGoals, final IType declaringType, IType realType) throws ModelException { ISourceModule sourceModule = declaringType.getSourceModule(); ModuleDeclaration moduleDeclaration = SourceParserUtil.getModuleDeclaration(sourceModule); TypeDeclaration typeDeclaration = PHPModelUtils.getNodeByClass(moduleDeclaration, declaringType); // try to search declarations of type "self::$var =" or // "$this->var =" ClassDeclarationSearcher searcher; if (realType != null) { searcher = new ClassDeclarationSearcher( sourceModule, typeDeclaration, 0, 0, variableName, realType, declaringType); } else { searcher = new ClassDeclarationSearcher(sourceModule, typeDeclaration, 0, 0, variableName); } try { moduleDeclaration.traverse(searcher); Map<ASTNode, IContext> staticDeclarations = searcher.getStaticDeclarations(); for (ASTNode node : staticDeclarations.keySet()) { IContext context = staticDeclarations.get(node); if (context instanceof MethodContext) { MethodContext methodContext = (MethodContext) context; methodContext.setCurrentType(realType); } subGoals.add(new ExpressionTypeGoal(context, node)); } } catch (Exception e) { if (DLTKCore.DEBUG) { e.printStackTrace(); } } }
protected void reportAliasForNS( ICompletionReporter reporter, String suffix, AbstractCompletionContext abstractContext, IModuleSource module, final Map<String, UsePart> result) throws BadLocationException { SourceRange replacementRange = getReplacementRange(abstractContext); IDLTKSearchScope scope = createSearchScope(); for (Iterator iterator = result.keySet().iterator(); iterator.hasNext(); ) { String name = (String) iterator.next(); String fullName = result.get(name).getNamespace().getFullyQualifiedName(); IType[] elements = PhpModelAccess.getDefault() .findTypes( null, fullName + NamespaceReference.NAMESPACE_SEPARATOR, MatchRule.PREFIX, 0, 0, scope, null); for (int i = 0; i < elements.length; i++) { String elementName = elements[i].getElementName(); reportAlias( reporter, scope, module, replacementRange, elements[i], elementName, elementName.replace(fullName, name), suffix); } } }
public IGoal[] init() { ClassVariableDeclarationGoal typedGoal = (ClassVariableDeclarationGoal) goal; IType[] types = typedGoal.getTypes(); if (types == null) { TypeContext context = (TypeContext) typedGoal.getContext(); types = PHPTypeInferenceUtils.getModelElements(context.getInstanceType(), context); } if (types == null) { return null; } IContext context = typedGoal.getContext(); IModelAccessCache cache = null; if (context instanceof IModelCacheContext) { cache = ((IModelCacheContext) context).getCache(); } String variableName = typedGoal.getVariableName(); final List<IGoal> subGoals = new LinkedList<IGoal>(); for (final IType type : types) { try { ITypeHierarchy hierarchy = null; if (cache != null) { hierarchy = cache.getSuperTypeHierarchy(type, null); } IField[] fields = PHPModelUtils.getTypeHierarchyField(type, hierarchy, variableName, true, null); Map<IType, IType> fieldDeclaringTypeSet = new HashMap<IType, IType>(); for (IField field : fields) { IType declaringType = field.getDeclaringType(); if (declaringType != null) { fieldDeclaringTypeSet.put(declaringType, type); ISourceModule sourceModule = declaringType.getSourceModule(); ModuleDeclaration moduleDeclaration = SourceParserUtil.getModuleDeclaration(sourceModule); TypeDeclaration typeDeclaration = PHPModelUtils.getNodeByClass(moduleDeclaration, declaringType); if (typeDeclaration != null && field instanceof SourceRefElement) { SourceRefElement sourceRefElement = (SourceRefElement) field; ISourceRange sourceRange = sourceRefElement.getSourceRange(); ClassDeclarationSearcher searcher = new ClassDeclarationSearcher( sourceModule, typeDeclaration, sourceRange.getOffset(), sourceRange.getLength(), null, type, declaringType); try { moduleDeclaration.traverse(searcher); if (searcher.getResult() != null) { subGoals.add(new ExpressionTypeGoal(searcher.getContext(), searcher.getResult())); } } catch (Exception e) { if (DLTKCore.DEBUG) { e.printStackTrace(); } } } } } if (subGoals.size() == 0) { getGoalFromStaticDeclaration(variableName, subGoals, type, null); } fieldDeclaringTypeSet.remove(type); if (subGoals.size() == 0 && !fieldDeclaringTypeSet.isEmpty()) { for (Iterator iterator = fieldDeclaringTypeSet.keySet().iterator(); iterator.hasNext(); ) { IType fieldDeclaringType = (IType) iterator.next(); getGoalFromStaticDeclaration( variableName, subGoals, fieldDeclaringType, fieldDeclaringTypeSet.get(fieldDeclaringType)); } } } catch (CoreException e) { if (DLTKCore.DEBUG) { e.printStackTrace(); } } } resolveMagicClassVariableDeclaration(types, variableName, cache); return subGoals.toArray(new IGoal[subGoals.size()]); }
protected void reportAlias( ICompletionReporter reporter, String suffix, AbstractCompletionContext abstractContext, IModuleSource module, final Map<String, UsePart> result) throws BadLocationException { SourceRange replacementRange = getReplacementRange(abstractContext); String prefix = abstractContext.getPrefixWithoutProcessing(); IDLTKSearchScope scope = createSearchScope(); for (Iterator iterator = result.keySet().iterator(); iterator.hasNext(); ) { String name = (String) iterator.next(); String fullName = result.get(name).getNamespace().getFullyQualifiedName(); if (fullName.startsWith("\\")) { fullName = fullName.substring(1); } IType[] elements = PhpModelAccess.getDefault() .findTypes(null, fullName, MatchRule.PREFIX, 0, 0, scope, null); try { for (int i = 0; i < elements.length; i++) { String elementName = elements[i].getElementName(); if (!PHPFlags.isNamespace(elements[i].getFlags())) { reportAlias( reporter, scope, module, replacementRange, elements[i], elementName, elementName.replace(fullName, name), suffix); } else { String nsname = prefix.replace(name, fullName); if (nsname.startsWith(elementName + SPLASH) && nsname.lastIndexOf(SPLASH) == elementName.length()) { // namespace strategy will handle this case continue; } IType[] typesOfNS = elements[i].getTypes(); for (int j = 0; j < typesOfNS.length; j++) { reportAlias( reporter, scope, module, replacementRange, typesOfNS[j], elementName + SPLASH + typesOfNS[j].getElementName(), (elementName + SPLASH + typesOfNS[j].getElementName()).replace(fullName, name), suffix); } } } elements = PhpModelAccess.getDefault().findTypes(fullName, MatchRule.EXACT, 0, 0, scope, null); for (int i = 0; i < elements.length; i++) { String elementName = elements[i].getElementName(); if (!PHPFlags.isNamespace(elements[i].getFlags())) { reportAlias( reporter, scope, module, replacementRange, elements[i], elementName, name, suffix); } else { String nsname = prefix.replace(name, fullName); if (nsname.startsWith(elementName + SPLASH) && nsname.lastIndexOf(SPLASH) == elementName.length()) { // namespace strategy will handle this case continue; } IType[] typesOfNS = elements[i].getTypes(); for (int j = 0; j < typesOfNS.length; j++) { reportAlias( reporter, scope, module, replacementRange, typesOfNS[j], elementName + SPLASH + typesOfNS[j].getElementName(), (elementName + SPLASH + typesOfNS[j].getElementName()).replace(fullName, name), suffix); } } } } catch (ModelException e) { e.printStackTrace(); } } }
/** * Creates the text changes for all the affected files. Updates all the include statements in the * current file and all the includes in the "including " files. In case of folders, creates the * changes recursively * * @param pm - progress monitor * @param rootChange - the root change that the new changes are added to * @param sourceResources * @return the root change after the additions * @throws CoreException */ private Change createTextChanges( IProgressMonitor pm, CompositeChange rootChange, Set<IFile> phpFiles, IResource[] sourceResources) throws CoreException { List<ProgramFileChange> changes = new ArrayList<ProgramFileChange>(); try { pm.beginTask(PhpRefactoringCoreMessages.getString("MoveDelegate.1"), 100); // $NON-NLS-1$ // creat text changes: // for each file that will be moved, update its includes // and update all the files that include it, IResource[] uniqueSourceResources = removeDuplicateResources(sourceResources); for (Iterator<IFile> it = phpFiles.iterator(); it.hasNext(); ) { IFile currentMovedResource = it.next(); Map<IFile, Program> participantFiles = collectReferencingFiles(currentMovedResource, pm); for (Entry<IFile, Program> entry : participantFiles.entrySet()) { final IFile file = entry.getKey(); if (phpFiles.contains(file)) { continue; } final Program program = entry.getValue(); final ChangeIncludePath rename = new ChangeIncludePath( currentMovedResource, file, fMainDestinationPath, false, uniqueSourceResources); // aggregate the changes identifiers program.accept(rename); if (pm.isCanceled()) throw new OperationCanceledException(); pm.worked(1); if (rename.hasChanges()) { ProgramFileChange change = new ProgramFileChange(file.getName(), file, program); change.setEdit(new MultiTextEdit()); change.setTextType("php"); // $NON-NLS-1$ changes.add(change); rename.updateChange(change); } } ISourceModule sourceModule = DLTKCore.createSourceModuleFrom(currentMovedResource); if (sourceModule instanceof ISourceModule) { Program program = null; try { program = ASTUtils.createProgramFromSource(sourceModule); } catch (Exception e) { } if (program != null) { final ChangeIncludePath rename = new ChangeIncludePath( currentMovedResource, currentMovedResource, fMainDestinationPath, true, uniqueSourceResources); // aggregate the changes identifiers program.accept(rename); if (pm.isCanceled()) throw new OperationCanceledException(); pm.worked(1); if (rename.hasChanges()) { ProgramFileChange change = new ProgramFileChange( currentMovedResource.getName(), currentMovedResource, program); change.setEdit(new MultiTextEdit()); change.setTextType("php"); // $NON-NLS-1$ changes.add(change); rename.updateChange(change); } } } } pm.worked(70); } finally { pm.done(); } // getChildren() Map<IFile, List<TextEdit>> changeMap = new HashMap<IFile, List<TextEdit>>(); Map<IFile, ProgramFileChange> fileMap = new HashMap<IFile, ProgramFileChange>(); for (ProgramFileChange programFileChange : changes) { List<TextEdit> list = changeMap.get(programFileChange.getFile()); if (list == null) { list = new ArrayList<TextEdit>(); changeMap.put(programFileChange.getFile(), list); fileMap.put(programFileChange.getFile(), programFileChange); } else { } list.addAll(Arrays.asList(programFileChange.getEdit().getChildren())); } for (IFile file : changeMap.keySet()) { ProgramFileChange change = new ProgramFileChange(file.getName(), file, fileMap.get(file).getProgram()); change.setEdit(new MultiTextEdit()); change.setTextType("php"); // $NON-NLS-1$ List<TextEdit> list = changeMap.get(file); Collections.sort( list, new Comparator<TextEdit>() { public int compare(TextEdit o1, TextEdit o2) { return o2.getOffset() - o1.getOffset(); } }); for (TextEdit textEdit : list) { if (textEdit instanceof ReplaceEdit) { ReplaceEdit replaceEdit = (ReplaceEdit) textEdit; change.addEdit( new ReplaceEdit( replaceEdit.getOffset(), replaceEdit.getLength(), replaceEdit.getText())); } } rootChange.add(change); } return rootChange; }