Example usage for org.eclipse.jdt.core.dom MethodInvocation EXPRESSION_PROPERTY

List of usage examples for org.eclipse.jdt.core.dom MethodInvocation EXPRESSION_PROPERTY

Introduction

In this page you can find the example usage for org.eclipse.jdt.core.dom MethodInvocation EXPRESSION_PROPERTY.

Prototype

ChildPropertyDescriptor EXPRESSION_PROPERTY

To view the source code for org.eclipse.jdt.core.dom MethodInvocation EXPRESSION_PROPERTY.

Click Source Link

Document

The "expression" structural property of this node type (child type: Expression ).

Usage

From source file:com.bsiag.eclipse.jdt.java.formatter.linewrap.WrapPreparator.java

License:Open Source License

@Override
public boolean visit(MethodInvocation node) {
    handleArguments(node.arguments(), this.options.alignment_for_arguments_in_method_invocation);

    boolean isInvocationChainRoot = !(node.getParent() instanceof MethodInvocation)
            || node.getLocationInParent() != MethodInvocation.EXPRESSION_PROPERTY;
    if (isInvocationChainRoot) {
        Expression expression = node;
        MethodInvocation invocation = node;
        while (expression instanceof MethodInvocation) {
            invocation = (MethodInvocation) expression;
            expression = invocation.getExpression();
            if (expression != null)
                this.wrapIndexes.add(this.tm.firstIndexBefore(invocation.getName(), TokenNameDOT));
        }/*from  w w w. j  a va2s  .  com*/
        Collections.reverse(this.wrapIndexes);
        this.wrapParentIndex = (expression != null) ? this.tm.lastIndexIn(expression, -1)
                : this.tm.lastIndexIn(invocation, -1);
        this.wrapGroupEnd = this.tm.firstIndexIn(node.getName(), -1);
        handleWrap(this.options.alignment_for_selector_in_method_invocation);
    }
    return true;
}

From source file:com.google.gdt.eclipse.designer.builders.participant.MyCompilationParticipant.java

License:Open Source License

/**
 * Adds error markers for types that are not visible in inherited "source" packages.
 *//* w w  w .  ja v  a  2  s  .  c  om*/
private void addMarkers_notImportedTypes(final List<MarkerInfo> newMarkers,
        final IResourcesProvider resourcesProvider, ModuleDescription moduleDescription,
        CompilationUnit astUnit, final IFile file, final IDocument document) throws Exception {
    final IJavaProject javaProject = JavaCore.create(file.getProject());
    // prepare list of source packages
    final List<SourcePackageDescriptor> sourcePackages = Lists.newArrayList();
    ModuleVisitor.accept(moduleDescription, new ModuleVisitor() {
        @Override
        public void visitSourcePackage(ModuleElement module, String packageName, boolean superSource)
                throws Exception {
            sourcePackages.add(new SourcePackageDescriptor(packageName, superSource));
        }
    });
    // validate all types in CompilationUnit
    astUnit.accept(new ASTVisitor() {
        private final Set<String> m_validClasses = Sets.newTreeSet();
        private final Set<String> m_invalidClasses = Sets.newTreeSet();

        @Override
        public boolean visit(SingleMemberAnnotation node) {
            return false;
        }

        @Override
        public boolean visit(NormalAnnotation node) {
            return false;
        }

        @Override
        public void postVisit(final ASTNode node) {
            ExecutionUtils.runIgnore(new RunnableEx() {
                public void run() throws Exception {
                    postVisitEx(node);
                }
            });
        }

        private void postVisitEx(ASTNode node) throws Exception {
            // ignore imports
            if (AstNodeUtils.getEnclosingNode(node, ImportDeclaration.class) != null) {
                return;
            }
            // check known cases
            if (node instanceof SimpleType) {
                SimpleType simpleType = (SimpleType) node;
                ITypeBinding typeBinding = simpleType.resolveBinding();
                checkNode(node, typeBinding);
            } else if (node instanceof SimpleName) {
                SimpleName simpleName = (SimpleName) node;
                if (simpleName.resolveBinding().getKind() == IBinding.TYPE
                        && node.getLocationInParent() == MethodInvocation.EXPRESSION_PROPERTY) {
                    ITypeBinding typeBinding = simpleName.resolveTypeBinding();
                    checkNode(node, typeBinding);
                }
            }
        }

        private void checkNode(ASTNode node, ITypeBinding typeBinding) throws Exception {
            if (typeBinding != null) {
                // ignore generics type variable
                if (typeBinding.isTypeVariable()) {
                    return;
                }
                // only top level types can be found as source
                while (typeBinding.getDeclaringClass() != null) {
                    typeBinding = typeBinding.getDeclaringClass();
                }
                // check this type
                String typeName = AstNodeUtils.getFullyQualifiedName(typeBinding, true);
                if (isSecondarySourceType(typeName)) {
                    return;
                }
                checkClass(node, typeName);
            }
        }

        private boolean isSecondarySourceType(String typeName) throws Exception {
            // usually secondary type can not be found using this way
            IType type = javaProject.findType(typeName);
            if (type == null) {
                return true;
            }
            // "secondary source type" has compilation unit
            ICompilationUnit compilationUnit = type.getCompilationUnit();
            if (compilationUnit == null) {
                return false;
            }
            // check if type name in same as unit name
            String unitName = compilationUnit.getElementName();
            unitName = StringUtils.removeEnd(unitName, ".java");
            return !typeName.endsWith("." + unitName);
        }

        /**
         * Check that class with given name is defined in this or inherited module.
         */
        private void checkClass(ASTNode node, String className) throws Exception {
            if (!isValid(className)) {
                markAsInvalid(node, className);
            }
        }

        /**
         * @return <code>true</code> if given class is valid.
         */
        private boolean isValid(String className) {
            // check cached valid classes
            if (m_validClasses.contains(className)) {
                return true;
            }
            // check cached invalid classes
            if (m_invalidClasses.contains(className)) {
                return false;
            }
            // no information in caches, do checks 
            for (SourcePackageDescriptor sourcePackageDescriptor : sourcePackages) {
                if (sourcePackageDescriptor.isValidClass(resourcesProvider, className)) {
                    m_validClasses.add(className);
                    return true;
                }
            }
            // mark as invalid
            m_invalidClasses.add(className);
            return false;
        }

        private void markAsInvalid(ASTNode node, String className) throws Exception {
            String message = className + " can not be found in source packages. "
                    + "Check the inheritance chain from your module; "
                    + "it may not be inheriting a required module or a module "
                    + "may not be adding its source path entries properly.";
            String moduleNameToImport = getEnclosingModule(resourcesProvider, className);
            newMarkers.add(createMarkerInfo_importModule(file, document, node.getStartPosition(),
                    node.getLength(), message, moduleNameToImport));
        }
    });
}

From source file:com.intel.ide.eclipse.mpt.ast.UnresolvedElementsSubProcessor.java

License:Open Source License

public static void getVariableProposals(IInvocationContext context, IProblemLocation problem,
        IVariableBinding resolvedField, Map<String, Map> proposals) throws CoreException {

    ICompilationUnit cu = context.getCompilationUnit();

    CompilationUnit astRoot = context.getASTRoot();
    ASTNode selectedNode = problem.getCoveredNode(astRoot);
    if (selectedNode == null) {
        return;//from   ww  w  . j  av  a 2s.co  m
    }

    // type that defines the variable
    ITypeBinding binding = null;
    ITypeBinding declaringTypeBinding = Bindings.getBindingOfParentTypeContext(selectedNode);
    if (declaringTypeBinding == null) {
        return;
    }

    // possible type kind of the node
    boolean suggestVariableProposals = true;
    while (selectedNode instanceof ParenthesizedExpression) {
        selectedNode = ((ParenthesizedExpression) selectedNode).getExpression();
    }

    Name node = null;

    switch (selectedNode.getNodeType()) {
    case ASTNode.SIMPLE_NAME:
        node = (SimpleName) selectedNode;

        if (!isVariableProposalSafe(node))
            return;
        ASTNode parent = node.getParent();
        StructuralPropertyDescriptor locationInParent = node.getLocationInParent();
        if (locationInParent == MethodInvocation.EXPRESSION_PROPERTY) {
        } else if (locationInParent == FieldAccess.NAME_PROPERTY) {
            Expression expression = ((FieldAccess) parent).getExpression();
            if (expression != null) {
                binding = expression.resolveTypeBinding();
                if (binding == null) {
                    node = null;
                }
            }
        } else if (parent instanceof SimpleType) {
            suggestVariableProposals = false;
        } else if (parent instanceof QualifiedName) {
            Name qualifier = ((QualifiedName) parent).getQualifier();
            if (qualifier != node) {
                binding = qualifier.resolveTypeBinding();
            } else {
            }
            ASTNode outerParent = parent.getParent();
            while (outerParent instanceof QualifiedName) {
                outerParent = outerParent.getParent();
            }
            if (outerParent instanceof SimpleType) {
                suggestVariableProposals = false;
            }
        } else if (locationInParent == SwitchCase.EXPRESSION_PROPERTY) {
            ITypeBinding switchExp = ((SwitchStatement) node.getParent().getParent()).getExpression()
                    .resolveTypeBinding();
            if (switchExp != null && switchExp.isEnum()) {
                binding = switchExp;
            }
        } else if (locationInParent == SuperFieldAccess.NAME_PROPERTY) {
            binding = declaringTypeBinding.getSuperclass();
        }
        break;
    case ASTNode.QUALIFIED_NAME:
        QualifiedName qualifierName = (QualifiedName) selectedNode;
        ITypeBinding qualifierBinding = qualifierName.getQualifier().resolveTypeBinding();
        if (qualifierBinding != null) {
            node = qualifierName.getName();
            binding = qualifierBinding;
        } else {
            node = qualifierName.getQualifier();
            suggestVariableProposals = node.isSimpleName();
        }
        if (selectedNode.getParent() instanceof SimpleType) {
            suggestVariableProposals = false;
        }
        break;
    case ASTNode.FIELD_ACCESS:
        FieldAccess access = (FieldAccess) selectedNode;
        Expression expression = access.getExpression();
        if (expression != null) {
            binding = expression.resolveTypeBinding();
            if (binding != null) {
                node = access.getName();
            }
        }
        break;
    case ASTNode.SUPER_FIELD_ACCESS:
        binding = declaringTypeBinding.getSuperclass();
        node = ((SuperFieldAccess) selectedNode).getName();
        break;
    default:
    }

    if (node == null) {
        return;
    }

    if (!suggestVariableProposals) {
        return;
    }

    SimpleName simpleName = node.isSimpleName() ? (SimpleName) node : ((QualifiedName) node).getName();
    boolean isWriteAccess = ASTResolving.isWriteAccess(node);

    if (resolvedField == null || binding == null
            || resolvedField.getDeclaringClass() != binding.getTypeDeclaration()
                    && Modifier.isPrivate(resolvedField.getModifiers())) {

        // new fields
        addNewFieldProposals(cu, astRoot, binding, declaringTypeBinding, simpleName, isWriteAccess, proposals);
    }
}

From source file:org.eclipse.ajdt.internal.ui.editor.quickfix.UnresolvedElementsSubProcessor.java

License:Open Source License

public static void getVariableProposals(IInvocationContext context, IProblemLocation problem,
        IVariableBinding resolvedField, Collection proposals) throws CoreException {

    ICompilationUnit cu = context.getCompilationUnit();

    CompilationUnit astRoot = context.getASTRoot();
    ASTNode selectedNode = problem.getCoveredNode(astRoot);
    if (selectedNode == null) {
        return;/*from  ww w. ja v  a 2 s.  c o  m*/
    }

    // type that defines the variable
    ITypeBinding binding = null;
    ITypeBinding declaringTypeBinding = Bindings.getBindingOfParentTypeContext(selectedNode);
    if (declaringTypeBinding == null) {
        return;
    }

    // possible type kind of the node
    boolean suggestVariableProposals = true;
    int typeKind = 0;

    while (selectedNode instanceof ParenthesizedExpression) {
        selectedNode = ((ParenthesizedExpression) selectedNode).getExpression();
    }

    Name node = null;

    switch (selectedNode.getNodeType()) {
    case ASTNode.SIMPLE_NAME:
        node = (SimpleName) selectedNode;
        ASTNode parent = node.getParent();
        StructuralPropertyDescriptor locationInParent = node.getLocationInParent();
        if (locationInParent == MethodInvocation.EXPRESSION_PROPERTY) {
            typeKind = SimilarElementsRequestor.CLASSES;
        } else if (locationInParent == FieldAccess.NAME_PROPERTY) {
            Expression expression = ((FieldAccess) parent).getExpression();
            if (expression != null) {
                binding = expression.resolveTypeBinding();
                if (binding == null) {
                    node = null;
                }
            }
        } else if (parent instanceof SimpleType) {
            suggestVariableProposals = false;
            typeKind = SimilarElementsRequestor.REF_TYPES;
        } else if (parent instanceof QualifiedName) {
            Name qualifier = ((QualifiedName) parent).getQualifier();
            if (qualifier != node) {
                binding = qualifier.resolveTypeBinding();
            } else {
                typeKind = SimilarElementsRequestor.REF_TYPES & ~SimilarElementsRequestor.VARIABLES;
            }
            ASTNode outerParent = parent.getParent();
            while (outerParent instanceof QualifiedName) {
                outerParent = outerParent.getParent();
            }
            if (outerParent instanceof SimpleType) {
                typeKind = SimilarElementsRequestor.REF_TYPES & ~SimilarElementsRequestor.VARIABLES;
                suggestVariableProposals = false;
            }
        } else if (locationInParent == SwitchCase.EXPRESSION_PROPERTY) {
            ITypeBinding switchExp = ((SwitchStatement) node.getParent().getParent()).getExpression()
                    .resolveTypeBinding();
            if (switchExp != null && switchExp.isEnum()) {
                binding = switchExp;
            }
        } else if (locationInParent == SuperFieldAccess.NAME_PROPERTY) {
            binding = declaringTypeBinding.getSuperclass();
        }
        break;
    case ASTNode.QUALIFIED_NAME:
        QualifiedName qualifierName = (QualifiedName) selectedNode;
        ITypeBinding qualifierBinding = qualifierName.getQualifier().resolveTypeBinding();
        if (qualifierBinding != null) {
            node = qualifierName.getName();
            binding = qualifierBinding;
        } else {
            node = qualifierName.getQualifier();
            typeKind = SimilarElementsRequestor.REF_TYPES & ~SimilarElementsRequestor.VARIABLES;
            suggestVariableProposals = node.isSimpleName();
        }
        if (selectedNode.getParent() instanceof SimpleType) {
            typeKind = SimilarElementsRequestor.REF_TYPES & ~SimilarElementsRequestor.VARIABLES;
            suggestVariableProposals = false;
        }
        break;
    case ASTNode.FIELD_ACCESS:
        FieldAccess access = (FieldAccess) selectedNode;
        Expression expression = access.getExpression();
        if (expression != null) {
            binding = expression.resolveTypeBinding();
            if (binding != null) {
                node = access.getName();
            }
        }
        break;
    case ASTNode.SUPER_FIELD_ACCESS:
        binding = declaringTypeBinding.getSuperclass();
        node = ((SuperFieldAccess) selectedNode).getName();
        break;
    default:
    }

    if (node == null) {
        return;
    }

    // add type proposals
    if (typeKind != 0) {
        if (!JavaModelUtil.is50OrHigher(cu.getJavaProject())) {
            typeKind = typeKind & ~(SimilarElementsRequestor.ANNOTATIONS | SimilarElementsRequestor.ENUMS
                    | SimilarElementsRequestor.VARIABLES);
        }

        int relevance = Character.isUpperCase(ASTNodes.getSimpleNameIdentifier(node).charAt(0)) ? 5 : -2;
        addSimilarTypeProposals(typeKind, cu, node, relevance + 1, proposals);
        addNewTypeProposals(cu, node, typeKind, relevance, proposals);
    }

    if (!suggestVariableProposals) {
        return;
    }

    SimpleName simpleName = node.isSimpleName() ? (SimpleName) node : ((QualifiedName) node).getName();
    boolean isWriteAccess = ASTResolving.isWriteAccess(node);

    // similar variables
    addSimilarVariableProposals(cu, astRoot, binding, simpleName, isWriteAccess, proposals);

    if (resolvedField == null || binding == null
            || resolvedField.getDeclaringClass() != binding.getTypeDeclaration()
                    && Modifier.isPrivate(resolvedField.getModifiers())) {

        // new fields
        addNewFieldProposals(cu, astRoot, binding, declaringTypeBinding, simpleName, isWriteAccess, proposals);

        // new parameters and local variables
        if (binding == null) {
            addNewVariableProposals(cu, node, simpleName, proposals);
        }
    }
}

From source file:org.eclipse.ajdt.internal.ui.editor.quickfix.UnresolvedElementsSubProcessor.java

License:Open Source License

private static void addQualifierToOuterProposal(IInvocationContext context, MethodInvocation invocationNode,
        IMethodBinding binding, Collection proposals) throws CoreException {
    ITypeBinding declaringType = binding.getDeclaringClass();
    ITypeBinding parentType = Bindings.getBindingOfParentType(invocationNode);
    ITypeBinding currType = parentType;//from  w ww  .ja  va2  s  . c  om

    boolean isInstanceMethod = !Modifier.isStatic(binding.getModifiers());

    while (currType != null && !Bindings.isSuperType(declaringType, currType)) {
        if (isInstanceMethod && Modifier.isStatic(currType.getModifiers())) {
            return;
        }
        currType = currType.getDeclaringClass();
    }
    if (currType == null || currType == parentType) {
        return;
    }

    ASTRewrite rewrite = ASTRewrite.create(invocationNode.getAST());

    String label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changetoouter_description,
            ASTResolving.getTypeSignature(currType));
    Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
    ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label,
            context.getCompilationUnit(), rewrite, 8, image);

    ImportRewrite imports = proposal.createImportRewrite(context.getASTRoot());
    AST ast = invocationNode.getAST();

    String qualifier = imports.addImport(currType);
    Name name = ASTNodeFactory.newName(ast, qualifier);

    Expression newExpression;
    if (isInstanceMethod) {
        ThisExpression expr = ast.newThisExpression();
        expr.setQualifier(name);
        newExpression = expr;
    } else {
        newExpression = name;
    }

    rewrite.set(invocationNode, MethodInvocation.EXPRESSION_PROPERTY, newExpression, null);

    proposals.add(proposal);
}

From source file:org.eclipse.wb.core.model.JavaInfo.java

License:Open Source License

/**
 * @return the {@link ASTNode} that should be used to display given related {@link ASTNode}.
 *//*from   w  ww.j a  v a  2 s . c  o  m*/
public static ASTNode getRelatedNodeForSource(ASTNode node) {
    ASTNode sourceNode = node;
    // part of invocation
    if (node.getLocationInParent() == MethodInvocation.EXPRESSION_PROPERTY) {
        sourceNode = node.getParent();
    }
    if (node.getLocationInParent() == MethodInvocation.ARGUMENTS_PROPERTY) {
        sourceNode = node.getParent();
    }
    if (node.getLocationInParent() == SuperConstructorInvocation.ARGUMENTS_PROPERTY) {
        sourceNode = node.getParent();
    }
    if (node.getLocationInParent() == SuperMethodInvocation.ARGUMENTS_PROPERTY) {
        sourceNode = node.getParent();
    }
    if (node.getLocationInParent() == ClassInstanceCreation.ARGUMENTS_PROPERTY) {
        sourceNode = node.getParent();
    }
    // javaInfo.foo = something
    if (node.getLocationInParent() == QualifiedName.QUALIFIER_PROPERTY) {
        QualifiedName qualifiedName = (QualifiedName) node.getParent();
        sourceNode = qualifiedName;
        if (qualifiedName.getLocationInParent() == Assignment.LEFT_HAND_SIDE_PROPERTY) {
            sourceNode = qualifiedName.getParent();
        }
    }
    // done
    return sourceNode;
}

From source file:org.eclipse.wb.core.model.JavaInfo.java

License:Open Source License

/**
 * @param relatedNode/* www . j av  a 2 s .com*/
 *          the {@link ASTNode} that represents this {@link JavaInfo}.
 * 
 * @return the {@link MethodInvocation} of this {@link JavaInfo} where given related
 *         {@link ASTNode} is expression of this {@link MethodInvocation}. May return
 *         <code>null</code>, if given related node is not part of {@link MethodInvocation}.
 */
public final MethodInvocation getMethodInvocation(ASTNode relatedNode) {
    if (relatedNode.getLocationInParent() == MethodInvocation.EXPRESSION_PROPERTY) {
        return (MethodInvocation) relatedNode.getParent();
    } else if (relatedNode instanceof MethodInvocation
            && ((MethodInvocation) relatedNode).getExpression() == null && isRepresentedBy(null)) {
        return (MethodInvocation) relatedNode;
    }
    // not a MethodInvocation part
    return null;
}

From source file:org.eclipse.wb.internal.core.model.util.factory.FactoryCreateAction.java

License:Open Source License

/**
 * Fills creation and configuration collections.
 *//*  w  w  w.  j ava 2 s.c  o m*/
private void fillCollections() {
    // creation
    if (m_component.getCreationSupport() instanceof ConstructorCreationSupport) {
        ConstructorCreationSupport creationSupport = (ConstructorCreationSupport) m_component
                .getCreationSupport();
        ClassInstanceCreation creation = creationSupport.getCreation();
        m_creationInfo.m_expression = creation;
        // fill arguments
        List<Expression> arguments = DomGenerics.arguments(creation);
        ConstructorDescription description = creationSupport.getDescription();
        fillArguments(m_creationInfo.m_arguments, arguments, description);
    }
    // invocations
    for (ASTNode relatedNode : m_component.getRelatedNodes()) {
        if (relatedNode.getLocationInParent() == MethodInvocation.EXPRESSION_PROPERTY) {
            MethodInvocation invocation = (MethodInvocation) relatedNode.getParent();
            String signature = AstNodeUtils.getMethodSignature(invocation);
            // prepare description
            MethodDescription description = m_component.getDescription().getMethod(signature);
            if (description == null) {
                continue;
            }
            // check, may be this method is disabled
            if (description.hasTrueTag("noFactory")) {
                continue;
            }
            // add invocation information
            InvocationInfo invocationInfo = new InvocationInfo();
            invocationInfo.m_expression = invocation;
            invocationInfo.m_invocation = invocation;
            invocationInfo.m_signature = signature;
            m_invocations.add(invocationInfo);
            // fill arguments
            List<Expression> arguments = DomGenerics.arguments(invocation);
            fillArguments(invocationInfo.m_arguments, arguments, description);
            // check that no arguments with variables
            for (ArgumentInfo argument : invocationInfo.m_arguments) {
                if (argument.m_hasVariables) {
                    invocationInfo.m_canExtract = false;
                }
            }
            // extract by default
            invocationInfo.m_extract = true;
        }
    }
}

From source file:org.eclipse.wb.internal.core.model.util.MorphingSupport.java

License:Open Source License

@Override
protected void morph_properties(T newComponent) throws Exception {
    ComponentDescription newComponentDescription = newComponent.getDescription();
    // move related nodes
    for (ASTNode node : m_component.getRelatedNodes()) {
        // check if method invocation can exist in new component
        if (node.getLocationInParent() == MethodInvocation.EXPRESSION_PROPERTY) {
            MethodInvocation invocation = (MethodInvocation) node.getParent();
            String signature = AstNodeUtils.getMethodSignature(invocation);
            if (newComponentDescription.getMethod(signature) == null) {
                m_editor.removeEnclosingStatement(invocation);
                continue;
            }//from ww w  . ja  v  a2s . co m
        }
        // check if assignment can exist in new component
        if (node.getLocationInParent() == QualifiedName.QUALIFIER_PROPERTY) {
            QualifiedName fieldAccess = (QualifiedName) node.getParent();
            if (fieldAccess.getLocationInParent() == Assignment.LEFT_HAND_SIDE_PROPERTY) {
                String fieldName = fieldAccess.getName().getIdentifier();
                if (ReflectionUtils.getFieldByName(newComponentDescription.getComponentClass(),
                        fieldName) == null) {
                    m_editor.removeEnclosingStatement(node);
                    continue;
                }
            }
        }
        // OK, we can add this related node
        newComponent.addRelatedNode(node);
    }
}

From source file:org.eclipse.wb.internal.core.utils.ast.AstEditor.java

License:Open Source License

/**
 * Examples:// w  w  w.  ja  v a  2s. c  o m
 * 
 * <pre>
  * SWT.NONE = org.eclipse.swt.SWT.NONE
  * new JButton() = new javax.swing.JButton()
  * </pre>
 * 
 * @param theNode
 *          the {@link ASTNode} to get the source.
 * @param transformer
 *          the {@link Function} that can participate in node to source transformation by
 *          providing alternative source for some nodes. Can be <code>null</code>, in not
 *          additional transformation required. If transformer returns not <code>null</code>, we
 *          use it instead of its original source; if <code>null</code> - we continue with
 *          original source.
 * 
 * @return the source of {@link ASTNode} in "external form", i.e. with fully qualified types.
 */
@SuppressWarnings("restriction")
public String getExternalSource(final ASTNode theNode, final Function<ASTNode, String> transformer) {
    final StringBuffer buffer = new StringBuffer(getSource(theNode));
    // remember positions for all nodes
    final Map<ASTNode, Integer> nodePositions = Maps.newHashMap();
    theNode.accept(new ASTVisitor() {
        @Override
        public void postVisit(ASTNode _node) {
            nodePositions.put(_node, _node.getStartPosition());
        }
    });
    // replace "name" with "qualified name"
    theNode.accept(new org.eclipse.jdt.internal.corext.dom.GenericVisitor() {
        @Override
        protected boolean visitNode(ASTNode node) {
            if (transformer != null) {
                String source = transformer.apply(node);
                if (source != null) {
                    replace(node, source);
                    return false;
                }
            }
            return true;
        }

        @Override
        public void endVisit(SimpleName name) {
            if (!AstNodeUtils.isVariable(name)) {
                StructuralPropertyDescriptor location = name.getLocationInParent();
                if (location == SimpleType.NAME_PROPERTY || location == QualifiedName.QUALIFIER_PROPERTY
                        || location == ClassInstanceCreation.NAME_PROPERTY
                        || location == MethodInvocation.EXPRESSION_PROPERTY) {
                    String fullyQualifiedName = AstNodeUtils.getFullyQualifiedName(name, false);
                    replace(name, fullyQualifiedName);
                }
            }
        }

        /**
         * Replace given ASTNode with different source, with updating positions for other nodes.
         */
        private void replace(ASTNode node, String newSource) {
            int nodePosition = nodePositions.get(node);
            // update source
            {
                int sourceStart = nodePosition - theNode.getStartPosition();
                int sourceEnd = sourceStart + node.getLength();
                buffer.replace(sourceStart, sourceEnd, newSource);
            }
            // update positions for nodes
            int lengthDelta = newSource.length() - node.getLength();
            for (Map.Entry<ASTNode, Integer> entry : nodePositions.entrySet()) {
                Integer position = entry.getValue();
                if (position > nodePosition) {
                    entry.setValue(position + lengthDelta);
                }
            }
        }
    });
    // OK, we have updated source
    return buffer.toString();
}