@Override
 public void setInput(RefactoringStatusContext context) {
   if (context instanceof DartStatusContext) {
     DartStatusContext jsc = (DartStatusContext) context;
     IDocument document = null;
     {
       CompilationUnit cunit = jsc.getCompilationUnit();
       if (cunit.isWorkingCopy()) {
         try {
           document = newDocument(cunit.getSource());
         } catch (DartModelException e) {
           // document is null which is a valid input.
         }
       } else {
         IEditorInput editorInput = new FileEditorInput((IFile) cunit.getResource());
         document =
             getDocument(
                 DartToolsPlugin.getDefault().getCompilationUnitDocumentProvider(), editorInput);
       }
       if (document == null) {
         document = new Document(RefactoringMessages.DartStatusContextViewer_no_source_available);
       }
       updateTitle(cunit);
     }
     setInput(document, createRegion(jsc.getSourceRange()));
   } else if (context instanceof DartStringStatusContext) {
     updateTitle(null);
     DartStringStatusContext sc = (DartStringStatusContext) context;
     setInput(newDocument(sc.getSource()), createRegion(sc.getSourceRange()));
   }
 }
Esempio n. 2
0
 /**
  * Parse the source for the specified compilation unit. Any exceptions thrown by the {@link
  * DartParser} will be logged and a {@link DartModelException} thrown.
  *
  * @param compilationUnit the compilation unit (not <code>null</code>)
  * @param parseErrors a collection to which parse errors are appended or <code>null</code> if
  *     parse errors should be ignored
  * @return the parse result
  */
 public static DartUnit parseUnit(
     CompilationUnit compilationUnit, Collection<DartCompilationError> parseErrors)
     throws DartModelException {
   String name = compilationUnit.getElementName();
   String source = compilationUnit.getSource();
   return parseSource(name, source, parseErrors);
 }
 /** Test for {@link DartFunction#isGlobal()} and {@link DartFunction#isLocal()}. */
 public void test_isGlobal_isLocal() throws Exception {
   TestProject testProject = new TestProject("Test");
   try {
     CompilationUnit unit =
         testProject.setUnitContent(
             "Test.dart",
             Joiner.on("\n")
                 .join(
                     "// filler filler filler filler filler filler filler filler filler filler",
                     "f() {",
                     "  v() {};",
                     "}",
                     ""));
     // global function
     DartFunction globalFunction = (DartFunction) unit.getChildren()[0];
     assertTrue(globalFunction.isGlobal());
     assertFalse(globalFunction.isLocal());
     // local functions
     DartElement[] functions = globalFunction.getChildren();
     assertThat(functions).hasSize(1);
     // v
     {
       DartFunction f = (DartFunction) functions[0];
       assertFalse(f.isGlobal());
       assertTrue(f.isLocal());
     }
   } finally {
     testProject.dispose();
   }
 }
Esempio n. 4
0
 /** Initialize this index with information from the user libraries. */
 private boolean indexUserLibraries() {
   boolean librariesIndexed = true;
   try {
     AnalysisServer analysisServer = PackageLibraryManagerProvider.getDefaultAnalysisServer();
     SavedContext savedContext = analysisServer.getSavedContext();
     DartModel model = DartCore.create(ResourcesPlugin.getWorkspace().getRoot());
     for (DartProject project : model.getDartProjects()) {
       for (DartLibrary library : project.getDartLibraries()) {
         CompilationUnit compilationUnit = library.getDefiningCompilationUnit();
         if (compilationUnit == null) {
           continue;
         }
         IResource libraryResource = compilationUnit.getResource();
         if (libraryResource == null) {
           continue;
         }
         IPath libraryLocation = libraryResource.getLocation();
         if (libraryLocation == null) {
           continue;
         }
         File libraryFile = libraryLocation.toFile();
         savedContext.resolve(libraryFile, null);
       }
     }
   } catch (Exception exception) {
     librariesIndexed = false;
     DartCore.logError("Could not index user libraries", exception);
   }
   return librariesIndexed;
 }
Esempio n. 5
0
  private boolean isValidSelectedFile() {
    if (selectedFile == null) {
      return false;
    }

    if (!DartCore.isDartLikeFileName(selectedFile.getName())) {
      return false;
    }

    DartElement element = DartCore.create(selectedFile);

    if (element instanceof CompilationUnit) {
      CompilationUnit cu = (CompilationUnit) element;

      DartLibrary lib = cu.getLibrary();

      if (lib instanceof DartLibraryImpl) {
        DartLibraryImpl impl = (DartLibraryImpl) lib;

        return impl.hasMain() && !impl.isBrowserApplication();
      }
    }

    return false;
  }
Esempio n. 6
0
 @Override
 public Void visitIdentifier(DartIdentifier node) {
   if (foundElement == null) {
     int start = node.getSourceInfo().getOffset();
     int length = node.getSourceInfo().getLength();
     int end = start + length;
     if (start <= startOffset && endOffset <= end) {
       wordRegion = new Region(start, length);
       Element targetElement = DartAstUtilities.getElement(node, includeDeclarations);
       if (targetElement == null) {
         foundElement = null;
       } else {
         if (targetElement instanceof VariableElement) {
           VariableElement variableElement = (VariableElement) targetElement;
           resolvedElement = variableElement;
           if (variableElement.getKind() == ElementKind.PARAMETER
               || variableElement.getKind() == ElementKind.VARIABLE) {
             foundElement =
                 BindingUtils.getDartElement(compilationUnit.getLibrary(), variableElement);
             candidateRegion =
                 new Region(
                     variableElement.getNameLocation().getOffset(),
                     variableElement.getNameLocation().getLength());
           } else {
             foundElement = null;
           }
         } else {
           findElementFor(targetElement);
           // Import prefix is resolved into LibraryElement, so it is correct that corresponding
           // DartElement is DartLibrary, but this is not what we (and user) wants, because
           // it looses information. We want DartImport, it gives both DartLibrary and name.
           if (foundElement instanceof DartLibrary) {
             try {
               DartImport[] imports = compilationUnit.getLibrary().getImports();
               for (DartImport imprt : imports) {
                 if (Objects.equal(imprt.getLibrary(), foundElement)
                     && Objects.equal(imprt.getPrefix(), node.getName())) {
                   foundElement = imprt;
                   SourceRange range = imprt.getNameRange();
                   candidateRegion = new Region(range.getOffset(), range.getLength());
                 }
               }
             } catch (DartModelException e) {
               DartCore.logError("Cannot resolve import " + foundElement.getElementName(), e);
             }
           }
         }
       }
       throw new DartElementFoundException();
     }
   }
   return null;
 }
Esempio n. 7
0
 @Override
 public Void visitStringLiteral(DartStringLiteral node) {
   if (foundElement == null) {
     int start = node.getSourceInfo().getOffset();
     int length = node.getSourceInfo().getLength();
     int end = start + length;
     if (end == 0) {
       return null;
     }
     if (start <= startOffset && end >= endOffset) {
       wordRegion = computeInternalStringRegion(start, length);
       DartNode parent = node.getParent();
       if (parent instanceof DartSourceDirective
           && ((DartSourceDirective) parent).getSourceUri() == node) {
         // resolvedElement = ((DartSourceDirective) parent).getElement();
         DartLibrary library = compilationUnit.getLibrary();
         String fileName = getFileName(library, node.getValue());
         CompilationUnit sourcedUnit = library.getCompilationUnit(fileName);
         if (sourcedUnit != null && sourcedUnit.exists()) {
           foundElement = sourcedUnit;
         }
       } else if (parent instanceof DartResourceDirective
           && ((DartResourceDirective) parent).getResourceUri() == node) {
         // resolvedElement = ((DartResourceDirective) parent).getElement();
         DartLibrary library = compilationUnit.getLibrary();
         try {
           DartSource unitSource = compilationUnit.getSourceRef();
           if (unitSource != null) {
             LibrarySource librarySource = unitSource.getLibrary();
             if (librarySource != null) {
               DartSource resourceSource = librarySource.getSourceFor(node.getValue());
               if (resourceSource != null) {
                 URI resourceUri = resourceSource.getUri();
                 DartResource resource = library.getResource(resourceUri);
                 if (resource != null && resource.exists()) {
                   foundElement = resource;
                 }
               }
             }
           }
         } catch (DartModelException exception) {
           foundElement = null;
         }
       }
       throw new DartElementFoundException();
     }
   }
   return null;
 }
 /** Test for {@link DartFunction#getVisibleRange()} for local functions. */
 public void test_getVisibleRange() throws Exception {
   TestProject testProject = new TestProject("Test");
   try {
     CompilationUnit unit =
         testProject.setUnitContent(
             "Test.dart",
             Joiner.on("\n")
                 .join(
                     "// filler filler filler filler filler filler filler filler filler filler",
                     "f() {",
                     "  v1() {};",
                     "  {",
                     "    v2() {};",
                     "  }//marker1",
                     "  v3() {};",
                     "}//marker2",
                     ""));
     String source = unit.getSource();
     DartFunction globalFunction = (DartFunction) unit.getChildren()[0];
     DartElement[] functions = globalFunction.getChildren();
     assertThat(functions).hasSize(3);
     // v1
     {
       DartFunction f = (DartFunction) functions[0];
       SourceRange range = f.getVisibleRange();
       assertEquals("v1", f.getElementName());
       assertEquals(source.indexOf("v1"), range.getOffset());
       assertEquals(source.indexOf("marker2") - 1, range.getOffset() + range.getLength());
     }
     // v2
     {
       DartFunction f = (DartFunction) functions[1];
       SourceRange range = f.getVisibleRange();
       assertEquals("v2", f.getElementName());
       assertEquals(source.indexOf("v2"), range.getOffset());
       assertEquals(source.indexOf("marker1") - 1, range.getOffset() + range.getLength());
     }
     // v3
     {
       DartFunction f = (DartFunction) functions[2];
       SourceRange range = f.getVisibleRange();
       assertEquals("v3", f.getElementName());
       assertEquals(source.indexOf("v3"), range.getOffset());
       assertEquals(source.indexOf("marker2") - 1, range.getOffset() + range.getLength());
     }
   } finally {
     testProject.dispose();
   }
 }
Esempio n. 9
0
 /** 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();
 }
Esempio n. 10
0
 @Override
 public Void visitImportDirective(DartImportDirective node) {
   DartLibrary library = compilationUnit.getLibrary();
   try {
     if (Objects.equal(compilationUnit, library.getDefiningCompilationUnit())) {
       DartImport[] imports = library.getImports();
       for (DartImport imprt : imports) {
         // on URI of library - return defining Unit of imported Library
         SourceRange uriRange = imprt.getUriRange();
         if (SourceRangeUtils.contains(uriRange, startOffset)) {
           resolvedElement = null;
           foundElement = imprt.getLibrary().getDefiningCompilationUnit();
           wordRegion = new Region(uriRange.getOffset(), uriRange.getLength());
           candidateRegion = new Region(0, 0);
           throw new DartElementFoundException();
         }
         // on #import directive - return DartImport element
         SourceRange sourceRange = imprt.getSourceRange();
         if (SourceRangeUtils.contains(sourceRange, startOffset)) {
           resolvedElement = null;
           foundElement = imprt;
           wordRegion = new Region(sourceRange.getOffset(), sourceRange.getLength());
           candidateRegion = new Region(sourceRange.getOffset(), sourceRange.getLength());
           throw new DartElementFoundException();
         }
       }
     }
   } catch (DartModelException e) {
     DartCore.logError("Cannot access imports of " + library.getElementName(), e);
   }
   return super.visitImportDirective(node);
 }
 /** Attempts to find {@link DartElement} at the <code>offset</code> position. */
 @SuppressWarnings("unchecked")
 protected static <T extends DartElement> T findElement(CompilationUnit unit, int offset)
     throws Exception {
   DartElement[] elements = unit.codeSelect(offset, 0);
   assertThat(elements).hasSize(1);
   return (T) elements[0];
 }
Esempio n. 12
0
 /**
  * Compute a region that represents the portion of the string literal between the opening and
  * closing quotes.
  *
  * @param nodeStart the index of the first character of the string literal
  * @param nodeLength the length of the string literal (including quotes)
  * @return the region that was computed
  */
 private IRegion computeInternalStringRegion(int nodeStart, int nodeLength) {
   int start = nodeStart;
   int end = nodeStart + nodeLength - 1;
   try {
     String source = compilationUnit.getBuffer().getContents();
     if (source.charAt(start) == '@') {
       start++;
     }
     if (source.charAt(start) == '\'') {
       while (source.charAt(start) == '\'') {
         start++;
       }
       while (source.charAt(end) == '\'') {
         end--;
       }
     } else {
       while (source.charAt(start) == '"') {
         start++;
       }
       while (source.charAt(end) == '"') {
         end--;
       }
     }
   } catch (DartModelException exception) {
   }
   if (start >= end) {
     return new Region(nodeStart, nodeLength);
   }
   return new Region(start, end - start + 1);
 }
Esempio n. 13
0
 /**
  * Return the existing document for the given compilation unit, or a DocumentAdapter if none.
  *
  * @return the existing document for the given compilation unit
  */
 protected IDocument getDocument(CompilationUnit cu) throws DartModelException {
   Buffer buffer = cu.getBuffer();
   if (buffer instanceof IDocument) {
     return (IDocument) buffer;
   }
   return new DocumentAdapter(buffer);
 }
Esempio n. 14
0
  private DartElement getEnclosingMethod(CompilationUnit input, ITextSelection selection) {
    try {
      DartElement enclosingElement = input.getElementAt(selection.getOffset());
      if (enclosingElement instanceof Method || enclosingElement instanceof Field) {
        // opening on the enclosing type would be too confusing (since the type resolves to the
        // constructors)
        return enclosingElement;
      }
    } catch (DartModelException e) {
      DartToolsPlugin.log(e);
    }

    return null;
  }
Esempio n. 15
0
  /**
   * Parse the source for the specified compilation unit and resolve any elements found in it. Any
   * exceptions thrown by the {@link DartParser} will be added to the given collection.
   *
   * @param compilationUnit the compilation unit (not <code>null</code>)
   * @param parseErrors a collection to which parse errors are added or <code>null</code> if parse
   *     errors should be ignored
   * @return the parse result
   */
  public static DartUnit resolveUnit(
      CompilationUnit compilationUnit, Collection<DartCompilationError> parseErrors)
      throws DartModelException {

    long start = System.currentTimeMillis();

    DartLibraryImpl library = (DartLibraryImpl) compilationUnit.getLibrary();
    if (library == null) {
      // If we cannot get the library, we cannot resolve any elements so we
      // revert to simply parsing the compilation unit.
      DartUnit ret = parseUnit(compilationUnit, parseErrors);

      long elapsed = System.currentTimeMillis() - start;
      Instrumentation.metric("DartCompilerUtils-resolveUnit", elapsed)
          .with("ParseOnlyFallback", "true")
          .log();

      Instrumentation.operation("DartCompilerUtils-resolveUnit", elapsed)
          .with("ParseOnlyFallback", "true")
          .with("CompilaitonUnit-ElementName", compilationUnit.getElementName())
          .log();

      return ret;
    }
    IResource resource = compilationUnit.getResource();
    URI unitUri = null;
    if (resource != null) {
      unitUri = resource.getLocationURI();
    }
    if (unitUri == null && compilationUnit instanceof ExternalCompilationUnitImpl) {
      unitUri = ((ExternalCompilationUnitImpl) compilationUnit).getUri();
    }
    if (unitUri == null) {
      unitUri = ((CompilationUnitImpl) compilationUnit).getSourceRef().getUri();
    }
    String unitSource = compilationUnit.getSource();
    Map<URI, String> suppliedSources = new HashMap<URI, String>();
    if (unitSource != null) {
      suppliedSources.put(unitUri, unitSource);
    }
    DartUnit ret =
        resolveUnit(library.getLibrarySourceFile(), unitUri, suppliedSources, parseErrors);

    long elapsed = System.currentTimeMillis() - start;
    Instrumentation.metric("DartCompilerUtils-resolveUnit", elapsed)
        .with("ParseOnlyFallback", "false")
        .log();

    Instrumentation.operation("DartCompilerUtils-resolveUnit", elapsed)
        .with("ParseOnlyFallback", "false")
        .with("CompilaitonUnit-ElementName", compilationUnit.getElementName())
        .with("compilationUnit.LastModified", compilationUnit.getModificationStamp())
        .log();

    return ret;
  }
Esempio n. 16
0
 /**
  * Given a compiler element representing some portion of the code base, set {@link #foundElement}
  * to the editor model element that corresponds to it.
  *
  * @param targetSymbol the compiler element representing some portion of the code base
  */
 private void findElementFor(Element targetSymbol) {
   if (targetSymbol == null) {
     return;
   }
   LibraryElement definingLibraryElement = BindingUtils.getLibrary(targetSymbol);
   DartLibrary definingLibrary = null;
   if (definingLibraryElement != null) {
     definingLibrary =
         BindingUtils.getDartElement(compilationUnit.getLibrary(), definingLibraryElement);
   }
   if (definingLibrary == null) {
     definingLibrary = compilationUnit.getLibrary();
   }
   resolvedElement = targetSymbol;
   foundElement = BindingUtils.getDartElement(definingLibrary, targetSymbol);
   if (foundElement instanceof SourceReference) {
     try {
       SourceRange range = ((SourceReference) foundElement).getNameRange();
       candidateRegion = new Region(range.getOffset(), range.getLength());
     } catch (DartModelException exception) {
       // Ignored
     }
   }
 }
Esempio n. 17
0
 /**
  * Search within the given AST node for an identifier representing a {@link DartElement Dart
  * element} in the specified source range. Return the element that was found, or <code>null</code>
  * if no element was found.
  *
  * @param node the AST node within which to search
  * @return the element that was found
  */
 public DartElement searchWithin(DartNode node) {
   try {
     node.accept(this);
   } catch (DartElementFoundException exception) {
     // A node with the right source position was found.
   } catch (Exception exception) {
     DartCore.logInformation(
         "Unable to locate element at offset ("
             + startOffset
             + " - "
             + endOffset
             + ") in "
             + compilationUnit.getElementName(),
         exception);
     return null;
   }
   return foundElement;
 }
Esempio n. 18
0
 /**
  * Compute a region representing the portion of the source containing a binary operator.
  *
  * @param left the index of the first character to the right of the left operand
  * @param right the index of the first character to the left of the right operand
  * @return the region that was computed
  */
 private IRegion computeOperatorRegion(int left, int right) {
   int start = left;
   int end = right;
   try {
     String source = compilationUnit.getBuffer().getContents();
     // TODO(brianwilkerson) This doesn't handle comments that occur between left and right, but
     // should.
     while (Character.isWhitespace(source.charAt(start))) {
       start++;
     }
     while (Character.isWhitespace(source.charAt(end))) {
       end--;
     }
   } catch (DartModelException exception) {
   }
   if (start > end) {
     return new Region(left, right - left + 1);
   }
   return new Region(start, end - start + 1);
 }
  private void acceptPotentialMethodDeclaration(CompletionProposal proposal) {
    try {
      DartElement enclosingElement = null;
      if (getContext().isExtended()) {
        enclosingElement = getContext().getEnclosingElement();
      } else if (fCompilationUnit != null) {
        enclosingElement = fCompilationUnit.getElementAt(proposal.getCompletionLocation() + 1);
      }
      if (enclosingElement == null) {
        return;
      }
      Type type = enclosingElement.getAncestor(Type.class);
      if (type != null) {
        String prefix = String.valueOf(proposal.getName());
        int completionStart = proposal.getReplaceStart();
        int completionEnd = proposal.getReplaceEnd();
        int relevance = computeRelevance(proposal);

        GetterSetterCompletionProposal.evaluateProposals(
            type,
            prefix,
            completionStart,
            completionEnd - completionStart,
            proposal.getReplaceEndIdentifier() - completionStart,
            relevance + 2,
            fSuggestedMethodNames,
            fDartProposals);
        MethodDeclarationCompletionProposal.evaluateProposals(
            type,
            prefix,
            completionStart,
            completionEnd - completionStart,
            proposal.getReplaceEndIdentifier() - completionStart,
            relevance,
            fSuggestedMethodNames,
            fDartProposals);
      }
    } catch (CoreException e) {
      DartToolsPlugin.log(e);
    }
  }
 /** @return the offset of given <code>search</code> string. Fails test if not found. */
 protected static int findOffset(CompilationUnit unit, String search) throws Exception {
   String source = unit.getSource();
   int offset = source.indexOf(search);
   assertThat(offset).describedAs(source).isNotEqualTo(-1);
   return offset;
 }
 /**
  * Creates a new instance ready to collect proposals. If the passed <code>CompilationUnit</code>
  * is not contained in an {@link DartProject}, no Dart doc will be available as {@link
  * org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo() additional
  * info} on the created proposals.
  *
  * @param cu the compilation unit that the result collector will operate on
  * @param ignoreAll <code>true</code> to ignore all kinds of completion proposals
  */
 public CompletionProposalCollector(CompilationUnit cu, boolean ignoreAll) {
   this(cu == null ? null : cu.getDartProject(), cu, ignoreAll); // TODO Remove getDartProject()
 }
Esempio n. 22
0
 @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();
   }
 }
 /** Asserts that {@link CompilationUnit} has expected content. */
 protected static void assertUnitContent(CompilationUnit unit, String... lines) throws Exception {
   assertEquals(makeSource(lines), unit.getSource());
 }
 /** Prints lines of code to insert into {@link #assertUnitContent(String...)}. */
 protected static void printUnitLinesSource(CompilationUnit unit) throws Exception {
   String source = unit.getSource();
   Iterable<String> lines = Splitter.on('\n').split(source);
   System.out.println(getLinesForSource(lines));
 }
 /**
  * Creates a new instance ready to collect proposals. If the passed <code>CompilationUnit</code>
  * is not contained in an {@link DartProject}, no Dart doc will be available as {@link
  * org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo() additional
  * info} on the created proposals.
  *
  * @param cu the compilation unit that the result collector will operate on
  */
 public CompletionProposalCollector(CompilationUnit cu) {
   this(cu.getDartProject(), cu, false);
 }