private RefactoringStatus checkExpression() throws JavaScriptModelException {
    RefactoringStatus result = new RefactoringStatus();
    result.merge(checkExpressionBinding());
    if (result.hasFatalError()) return result;
    checkAllStaticFinal();

    IExpressionFragment selectedExpression = getSelectedExpression();
    Expression associatedExpression = selectedExpression.getAssociatedExpression();
    if (associatedExpression instanceof NullLiteral)
      result.merge(
          RefactoringStatus.createFatalErrorStatus(
              RefactoringCoreMessages.ExtractConstantRefactoring_null_literals));
    else if (!ConstantChecks.isLoadTimeConstant(selectedExpression))
      result.merge(
          RefactoringStatus.createFatalErrorStatus(
              RefactoringCoreMessages.ExtractConstantRefactoring_not_load_time_constant));
    else if (associatedExpression instanceof SimpleName) {
      if (associatedExpression.getParent() instanceof QualifiedName
              && associatedExpression.getLocationInParent() == QualifiedName.NAME_PROPERTY
          || associatedExpression.getParent() instanceof FieldAccess
              && associatedExpression.getLocationInParent() == FieldAccess.NAME_PROPERTY)
        return RefactoringStatus.createFatalErrorStatus(
            RefactoringCoreMessages.ExtractConstantRefactoring_select_expression);
    }

    return result;
  }
 private Type getConstantType() throws JavaScriptModelException {
   if (fConstantTypeCache == null) {
     IExpressionFragment fragment = getSelectedExpression();
     ITypeBinding typeBinding = fragment.getAssociatedExpression().resolveTypeBinding();
     AST ast = fCuRewrite.getAST();
     typeBinding = Bindings.normalizeForDeclarationUse(typeBinding, ast);
     fConstantTypeCache = fCuRewrite.getImportRewrite().addImport(typeBinding, ast);
   }
   return fConstantTypeCache;
 }
 private String[] getExcludedVariableNames() {
   if (fExcludedVariableNames == null) {
     try {
       IExpressionFragment expr = getSelectedExpression();
       Collection takenNames =
           new ScopeAnalyzer(fCuRewrite.getRoot())
               .getUsedVariableNames(expr.getStartPosition(), expr.getLength());
       fExcludedVariableNames = (String[]) takenNames.toArray(new String[takenNames.size()]);
     } catch (JavaScriptModelException e) {
       fExcludedVariableNames = new String[0];
     }
   }
   return fExcludedVariableNames;
 }
  /* bd is a static field declaration or static initializer */
  private static boolean depends(IExpressionFragment selected, BodyDeclaration bd) {
    /* We currently consider selected to depend on bd only if db includes a declaration
     * of a static field on which selected depends.
     *
     * A more accurate strategy might be to also check if bd contains (or is) a
     * static initializer containing code which changes the value of a static field on
     * which selected depends.  However, if a static is written to multiple times within
     * during class initialization, it is difficult to predict which value should be used.
     * This would depend on which value is used by expressions instances for which the new
     * constant will be substituted, and there may be many of these; in each, the
     * static field in question may have taken on a different value (if some of these uses
     * occur within static initializers).
     */

    if (bd instanceof FieldDeclaration) {
      FieldDeclaration fieldDecl = (FieldDeclaration) bd;
      for (Iterator fragments = fieldDecl.fragments().iterator(); fragments.hasNext(); ) {
        VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.next();
        SimpleName staticFieldName = fragment.getName();
        if (selected.getSubFragmentsMatching(
                    ASTFragmentFactory.createFragmentForFullSubtree(staticFieldName))
                .length
            != 0) return true;
      }
    }
    return false;
  }
  //	 !!! -- same as in ExtractTempRefactoring
  private boolean isLiteralNodeSelected() throws JavaScriptModelException {
    IExpressionFragment fragment = getSelectedExpression();
    if (fragment == null) return false;
    Expression expression = fragment.getAssociatedExpression();
    if (expression == null) return false;
    switch (expression.getNodeType()) {
      case ASTNode.BOOLEAN_LITERAL:
      case ASTNode.CHARACTER_LITERAL:
      case ASTNode.NULL_LITERAL:
      case ASTNode.NUMBER_LITERAL:
      case ASTNode.UNDEFINED_LITERAL:
      case ASTNode.REGULAR_EXPRESSION_LITERAL:
        return true;

      default:
        return false;
    }
  }
 public Change createChange(IProgressMonitor monitor) throws CoreException {
   final Map arguments = new HashMap();
   String project = null;
   IJavaScriptProject javaProject = fCu.getJavaScriptProject();
   if (javaProject != null) project = javaProject.getElementName();
   int flags =
       JavaScriptRefactoringDescriptor.JAR_REFACTORING
           | JavaScriptRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
   if (JdtFlags.getVisibilityCode(fVisibility) != Modifier.PRIVATE)
     flags |= RefactoringDescriptor.STRUCTURAL_CHANGE;
   String pattern = ""; // $NON-NLS-1$
   try {
     pattern =
         BindingLabelProvider.getBindingLabel(
                 getContainingTypeBinding(), JavaScriptElementLabels.ALL_FULLY_QUALIFIED)
             + "."; //$NON-NLS-1$
   } catch (JavaScriptModelException exception) {
     JavaScriptPlugin.log(exception);
   }
   final String expression = ASTNodes.asString(fSelectedExpression.getAssociatedExpression());
   final String description =
       Messages.format(
           RefactoringCoreMessages.ExtractConstantRefactoring_descriptor_description_short,
           fConstantName);
   final String header =
       Messages.format(
           RefactoringCoreMessages.ExtractConstantRefactoring_descriptor_description,
           new String[] {pattern + fConstantName, expression});
   final JDTRefactoringDescriptorComment comment =
       new JDTRefactoringDescriptorComment(project, this, header);
   comment.addSetting(
       Messages.format(
           RefactoringCoreMessages.ExtractConstantRefactoring_constant_name_pattern,
           fConstantName));
   comment.addSetting(
       Messages.format(
           RefactoringCoreMessages.ExtractConstantRefactoring_constant_expression_pattern,
           expression));
   String visibility = fVisibility;
   if ("".equals(visibility)) // $NON-NLS-1$
   visibility = RefactoringCoreMessages.ExtractConstantRefactoring_default_visibility;
   comment.addSetting(
       Messages.format(
           RefactoringCoreMessages.ExtractConstantRefactoring_visibility_pattern, visibility));
   if (fReplaceAllOccurrences)
     comment.addSetting(RefactoringCoreMessages.ExtractConstantRefactoring_replace_occurrences);
   if (fQualifyReferencesWithDeclaringClassName)
     comment.addSetting(RefactoringCoreMessages.ExtractConstantRefactoring_qualify_references);
   final JDTRefactoringDescriptor descriptor =
       new JDTRefactoringDescriptor(
           IJavaScriptRefactorings.EXTRACT_CONSTANT,
           project,
           description,
           comment.asString(),
           arguments,
           flags);
   arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_INPUT, descriptor.elementToHandle(fCu));
   arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_NAME, fConstantName);
   arguments.put(
       JDTRefactoringDescriptor.ATTRIBUTE_SELECTION,
       new Integer(fSelectionStart).toString()
           + " "
           + new Integer(fSelectionLength).toString()); // $NON-NLS-1$
   arguments.put(ATTRIBUTE_REPLACE, Boolean.valueOf(fReplaceAllOccurrences).toString());
   arguments.put(
       ATTRIBUTE_QUALIFY, Boolean.valueOf(fQualifyReferencesWithDeclaringClassName).toString());
   arguments.put(
       ATTRIBUTE_VISIBILITY, new Integer(JdtFlags.getVisibilityCode(fVisibility)).toString());
   return new RefactoringDescriptorChange(
       descriptor,
       RefactoringCoreMessages.ExtractConstantRefactoring_name,
       new Change[] {fChange});
 }
  private void createConstantDeclaration() throws CoreException {
    Type type = getConstantType();

    IExpressionFragment fragment = getSelectedExpression();
    String initializerSource =
        fCu.getBuffer().getText(fragment.getStartPosition(), fragment.getLength());

    AST ast = fCuRewrite.getAST();
    VariableDeclarationFragment variableDeclarationFragment = ast.newVariableDeclarationFragment();
    variableDeclarationFragment.setName(ast.newSimpleName(fConstantName));
    variableDeclarationFragment.setInitializer(
        (Expression)
            fCuRewrite
                .getASTRewrite()
                .createStringPlaceholder(initializerSource, ASTNode.SIMPLE_NAME));

    FieldDeclaration fieldDeclaration = ast.newFieldDeclaration(variableDeclarationFragment);
    fieldDeclaration.setType(type);
    Modifier.ModifierKeyword accessModifier = Modifier.ModifierKeyword.toKeyword(fVisibility);
    if (accessModifier != null) fieldDeclaration.modifiers().add(ast.newModifier(accessModifier));
    fieldDeclaration.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD));
    fieldDeclaration.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD));

    boolean createComments =
        JavaPreferencesSettings.getCodeGenerationSettings(fCu.getJavaScriptProject())
            .createComments;
    if (createComments) {
      String comment =
          CodeGeneration.getFieldComment(
              fCu, getConstantTypeName(), fConstantName, StubUtility.getLineDelimiterUsed(fCu));
      if (comment != null && comment.length() > 0) {
        JSdoc doc =
            (JSdoc) fCuRewrite.getASTRewrite().createStringPlaceholder(comment, ASTNode.JSDOC);
        fieldDeclaration.setJavadoc(doc);
      }
    }

    AbstractTypeDeclaration parent = getContainingTypeDeclarationNode();
    ListRewrite listRewrite =
        fCuRewrite.getASTRewrite().getListRewrite(parent, parent.getBodyDeclarationsProperty());
    TextEditGroup msg =
        fCuRewrite.createGroupDescription(
            RefactoringCoreMessages.ExtractConstantRefactoring_declare_constant);
    if (insertFirst()) {
      listRewrite.insertFirst(fieldDeclaration, msg);
    } else {
      listRewrite.insertAfter(fieldDeclaration, getNodeToInsertConstantDeclarationAfter(), msg);
    }

    if (fLinkedProposalModel != null) {
      ASTRewrite rewrite = fCuRewrite.getASTRewrite();
      LinkedProposalPositionGroup nameGroup = fLinkedProposalModel.getPositionGroup(KEY_NAME, true);
      nameGroup.addPosition(rewrite.track(variableDeclarationFragment.getName()), true);

      String[] nameSuggestions = guessConstantNames();
      if (nameSuggestions.length > 0 && !nameSuggestions[0].equals(fConstantName)) {
        nameGroup.addProposal(fConstantName, null, nameSuggestions.length + 1);
      }
      for (int i = 0; i < nameSuggestions.length; i++) {
        nameGroup.addProposal(nameSuggestions[i], null, nameSuggestions.length - i);
      }

      LinkedProposalPositionGroup typeGroup = fLinkedProposalModel.getPositionGroup(KEY_TYPE, true);
      typeGroup.addPosition(rewrite.track(type), true);

      ITypeBinding typeBinding = fragment.getAssociatedExpression().resolveTypeBinding();
      if (typeBinding != null) {
        ITypeBinding[] relaxingTypes = ASTResolving.getNarrowingTypes(ast, typeBinding);
        for (int i = 0; i < relaxingTypes.length; i++) {
          typeGroup.addProposal(relaxingTypes[i], fCuRewrite.getCu(), relaxingTypes.length - i);
        }
      }
      ModifierCorrectionSubProcessor.installLinkedVisibilityProposals(
          fLinkedProposalModel, rewrite, fieldDeclaration.modifiers(), false);
    }
  }