/** Checks if created method will shadow or will be shadowed by other elements. */ private RefactoringStatus checkPossibleConflicts(IProgressMonitor pm) throws CoreException { List<SearchMatch> references = Lists.newArrayList(); // top-level function if (parentMember.getParent() instanceof DartUnit) { RefactoringStatus conflictsStatus = RenameTopLevelProcessor.analyzePossibleConflicts( unit.getLibrary(), DartElement.FUNCTION, false, references, methodName); if (!conflictsStatus.isOK()) { return convertRenameToCreateStatus(conflictsStatus); } } // method of class if (parentMember.getParent() instanceof DartClass) { ClassElement enclosingClassElement = (ClassElement) parentMember.getParent().getElement(); Type enclosingType = (Type) BindingUtils.getDartElement(enclosingClassElement); RefactoringStatus conflictsStatus = RenameTypeMemberProcessor.analyzePossibleConflicts( DartElement.FUNCTION, enclosingType, methodName, references, methodName, pm); if (!conflictsStatus.isOK()) { return convertRenameToCreateStatus(conflictsStatus); } } // OK return new RefactoringStatus(); }
private boolean inFactoryOrStatic(ClassElement containingClass) { DartClassMember<?> member = context.getCurrentClassMember(); return containingClass == null || containingClass.getKind() != ElementKind.CLASS || member == null || member.getModifiers().isFactory() || member.getModifiers().isStatic(); }
/** * @return <code>true</code> if the given {@link VariableElement} is referenced after the {@link * #selectionRange}. */ private boolean isUsedAfterSelection(final VariableElement element) { final AtomicBoolean result = new AtomicBoolean(); parentMember.accept( new ASTVisitor<Void>() { @Override public Void visitIdentifier(DartIdentifier node) { VariableElement nodeElement = ASTNodes.getVariableElement(node); if (nodeElement == element) { int nodeOffset = node.getSourceInfo().getOffset(); if (nodeOffset > selectionStart + selectionLength) { result.set(true); } } return null; } }); return result.get(); }
/** Fills {@link #occurrences} field. */ private void initializeOccurrences() { // prepare selection SourcePattern selectionPattern = getSourcePattern(selectionRange); final String selectionSource = getNormalizedSource(selectionPattern.patternSource); final Map<String, String> patternToSelectionName = HashBiMap.create(selectionPattern.originalToPatternNames).inverse(); // prepare context and enclosing parent - class or unit DartNode enclosingMemberParent; { DartNode coveringNode = selectionAnalyzer.getLastCoveringNode(); DartClassMember<?> parentMember = ASTNodes.getAncestor(coveringNode, DartClassMember.class); enclosingMemberParent = parentMember.getParent(); } // visit nodes which will able to access extracted method enclosingMemberParent.accept( new ASTVisitor<Void>() { boolean forceStatic = false; @Override public Void visitBlock(DartBlock node) { if (selectionStatements != null) { List<DartStatement> blockStatements = node.getStatements(); int beginStatementIndex = 0; int selectionCount = selectionStatements.size(); while (beginStatementIndex + selectionCount <= blockStatements.size()) { SourceRange nodeRange = SourceRangeFactory.forStartEnd( blockStatements.get(beginStatementIndex), blockStatements.get(beginStatementIndex + selectionCount - 1)); boolean found = tryToFindOccurrence(nodeRange); // next statement if (found) { beginStatementIndex += selectionCount; } else { beginStatementIndex++; } } } return super.visitBlock(node); } @Override public Void visitExpression(DartExpression node) { if (selectionExpression != null && node.getClass() == selectionExpression.getClass()) { SourceRange nodeRange = SourceRangeFactory.create(node); tryToFindOccurrence(nodeRange); } return super.visitExpression(node); } @Override public Void visitInitializer(DartInitializer node) { forceStatic = true; try { return super.visitInitializer(node); } finally { forceStatic = false; } } @Override public Void visitMethodDefinition(DartMethodDefinition node) { forceStatic = node.getModifiers().isStatic(); try { return super.visitMethodDefinition(node); } finally { forceStatic = false; } } /** * Checks if given {@link SourceRange} matched selection source and adds {@link * Occurrence}. */ private boolean tryToFindOccurrence(SourceRange nodeRange) { // prepare normalized node source SourcePattern nodePattern = getSourcePattern(nodeRange); String nodeSource = getNormalizedSource(nodePattern.patternSource); // if matches normalized node source, then add as occurrence if (nodeSource.equals(selectionSource)) { Occurrence occurrence = new Occurrence(nodeRange, SourceRangeUtils.intersects(selectionRange, nodeRange)); occurrences.add(occurrence); // prepare mapping of parameter names to the occurrence variables for (Entry<String, String> entry : nodePattern.originalToPatternNames.entrySet()) { String patternName = entry.getValue(); String originalName = entry.getKey(); String selectionName = patternToSelectionName.get(patternName); occurrence.parameterOldToOccurrenceName.put(selectionName, originalName); } // update static if (forceStatic) { staticContext |= true; } // we have match return true; } // no match return false; } }); }
@Override public Change createChange(IProgressMonitor pm) throws CoreException { pm.beginTask("", 1 + occurrences.size()); // $NON-NLS-1$ try { // configure Change { change = new CompilationUnitChange(unit.getElementName(), unit); change.setEdit(new MultiTextEdit()); change.setKeepPreviewEdits(true); } // replace occurrences with method invocation for (Occurrence occurence : occurrences) { pm.worked(1); SourceRange range = occurence.range; // may be replacement of duplicates disabled if (!replaceAllOccurrences && !occurence.isSelection) { continue; } // prepare invocation source String invocationSource; { StringBuilder sb = new StringBuilder(); // may be returns value if (returnVariable != null) { String varTypeName = ExtractUtils.getTypeSource(returnVariable.getType()); String originalName = returnVariable.getName(); String occurrenceName = occurence.parameterOldToOccurrenceName.get(originalName); if (varTypeName.equals("dynamic")) { sb.append("var "); } else { sb.append(varTypeName); sb.append(" "); } sb.append(occurrenceName); sb.append(" = "); } // invocation itself sb.append(methodName); sb.append("("); boolean firstParameter = true; for (ParameterInfo parameter : parameters) { // may be comma if (firstParameter) { firstParameter = false; } else { sb.append(", "); } // argument name { String parameterOldName = parameter.getOldName(); String argumentName = occurence.parameterOldToOccurrenceName.get(parameterOldName); sb.append(argumentName); } } sb.append(")"); invocationSource = sb.toString(); // statements as extracted with their ";", so add new one after invocation if (selectionStatements != null) { invocationSource += ";"; } } // add replace edit TextEdit edit = new ReplaceEdit(range.getOffset(), range.getLength(), invocationSource); change.addEdit(edit); String msg = Messages.format( occurence.isSelection ? RefactoringCoreMessages.ExtractMethodRefactoring_substitute_with_call : RefactoringCoreMessages.ExtractMethodRefactoring_duplicates_single, methodName); change.addTextEditGroup(new TextEditGroup(msg, edit)); } // add method declaration { // prepare environment String prefix = utils.getNodePrefix(parentMember); String eol = utils.getEndOfLine(); // prepare annotations String annotations = ""; { // may be "static" if (staticContext) { annotations = "static "; } } // prepare declaration source String declarationSource = null; { String returnExpressionSource = getMethodBodySource(); // expression if (selectionExpression != null) { // add return type String returnTypeName = ExtractUtils.getTypeSource(selectionExpression); if (returnTypeName != null && !returnTypeName.equals("dynamic")) { annotations += returnTypeName + " "; } // just return expression declarationSource = annotations + getSignature() + " => " + returnExpressionSource + ";"; } // statements if (selectionStatements != null) { if (returnVariable != null) { String returnTypeName = ExtractUtils.getTypeSource(returnVariable.getType()); if (returnTypeName != null && !returnTypeName.equals("dynamic")) { annotations += returnTypeName + " "; } } else { annotations += "void "; } declarationSource = annotations + getSignature() + " {" + eol; declarationSource += returnExpressionSource; if (returnVariable != null) { declarationSource += prefix + " return " + returnVariable.getName() + ";" + eol; } declarationSource += prefix + "}"; } } // insert declaration if (declarationSource != null) { int offset = parentMember.getSourceInfo().getEnd(); TextEdit edit = new ReplaceEdit(offset, 0, eol + eol + prefix + declarationSource); change.addEdit(edit); change.addTextEditGroup( new TextEditGroup( Messages.format( selectionExpression != null ? RefactoringCoreMessages.ExtractMethodRefactoring_add_method_expression : RefactoringCoreMessages.ExtractMethodRefactoring_add_method, methodName), edit)); } } pm.worked(1); // done return change; } finally { pm.done(); } }
private boolean inFactory() { DartClassMember<?> member = context.getCurrentClassMember(); return member != null && member.getModifiers().isFactory(); }