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(); } } }
private Map<IFile, Program> collectReferencingFiles(IFile sourceFile, IProgressMonitor pm) { ISourceModule sourceModule = DLTKCore.createSourceModuleFrom(sourceFile); Map<IFile, Program> participantFiles = new HashMap<IFile, Program>(); Collection<Node> references = MoveUtils.getReferencingFiles(sourceModule); if (references != null) { for (Iterator<Node> it = references.iterator(); it.hasNext(); ) { Node node = it.next(); IFile file = (IFile) node.getFile().getResource(); try { participantFiles.put(file, RefactoringUtility.getProgramForFile(file)); } catch (Exception e) { } } } return participantFiles; }
public boolean visit(Expression e) throws Exception { if (typeDeclaration.sourceStart() < e.sourceStart() && typeDeclaration.sourceEnd() > e.sourceEnd()) { if (e instanceof Assignment) { if (e.sourceStart() == offset && e.sourceEnd() - e.sourceStart() == length) { result = ((Assignment) e).getValue(); context = contextStack.peek(); } else if (variableName != null) { Assignment assignment = (Assignment) e; Expression left = assignment.getVariable(); Expression right = assignment.getValue(); if (left instanceof StaticFieldAccess) { StaticFieldAccess fieldAccess = (StaticFieldAccess) left; Expression dispatcher = fieldAccess.getDispatcher(); if (dispatcher instanceof TypeReference && "self".equals(((TypeReference) dispatcher).getName())) { // $NON-NLS-1$ Expression field = fieldAccess.getField(); if (field instanceof VariableReference && variableName.equals(((VariableReference) field).getName())) { staticDeclarations.put(right, contextStack.peek()); } } } else if (left instanceof FieldAccess) { FieldAccess fieldAccess = (FieldAccess) left; Expression dispatcher = fieldAccess.getDispatcher(); if (dispatcher instanceof VariableReference && "$this".equals(((VariableReference) dispatcher).getName())) { // $NON-NLS-1$ Expression field = fieldAccess.getField(); if (field instanceof SimpleReference && variableName.equals('$' + ((SimpleReference) field).getName())) { staticDeclarations.put(right, contextStack.peek()); } } } } } } return visitGeneral(e); }
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()]); }
public IGoal[] init() { PHPDocClassVariableGoal typedGoal = (PHPDocClassVariableGoal) goal; TypeContext context = (TypeContext) typedGoal.getContext(); String variableName = typedGoal.getVariableName(); int offset = typedGoal.getOffset(); IModelAccessCache cache = context.getCache(); IType[] types = PHPTypeInferenceUtils.getModelElements(context.getInstanceType(), context, offset, cache); Map<PHPDocBlock, IField> docs = new HashMap<PHPDocBlock, IField>(); // remove array index from field name if (variableName.endsWith("]")) { // $NON-NLS-1$ int index = variableName.indexOf("["); // $NON-NLS-1$ if (index != -1) { variableName = variableName.substring(0, index); } } if (types != null) { for (IType type : types) { try { // we look in whole hiearchy ITypeHierarchy superHierarchy; if (cache != null) { superHierarchy = cache.getSuperTypeHierarchy(type, null); } else { superHierarchy = type.newSupertypeHierarchy(null); } IType[] superTypes = superHierarchy.getAllTypes(); for (IType superType : superTypes) { IField[] typeField = PHPModelUtils.getTypeField(superType, variableName, true); if (typeField.length > 0) { PHPDocBlock docBlock = PHPModelUtils.getDocBlock(typeField[0]); if (docBlock != null) { docs.put(docBlock, typeField[0]); } } } } catch (ModelException e) { if (DLTKCore.DEBUG) { e.printStackTrace(); } } } } for (Entry<PHPDocBlock, IField> entry : docs.entrySet()) { PHPDocBlock doc = entry.getKey(); IField typeField = entry.getValue(); IType currentNamespace = PHPModelUtils.getCurrentNamespace(typeField); IModelElement space = currentNamespace != null ? currentNamespace : typeField.getSourceModule(); for (PHPDocTag tag : doc.getTags(PHPDocTag.VAR)) { // do it like for // PHPDocumentationContentAccess#handleBlockTags(List tags): // variable name can be optional, but if present keep only // the good ones if (tag.getVariableReference() != null && !tag.getVariableReference().getName().equals(variableName)) { continue; } evaluated.addAll( Arrays.asList( PHPEvaluationUtils.evaluatePHPDocType( tag.getTypeReferences(), space, tag.sourceStart(), null))); } } return IGoal.NO_GOALS; }
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; }