org.codehaus.groovy.eclipse.dsl.inferencing.suggestions.SuggestionsRequestor.java Source code

Java tutorial

Introduction

Here is the source code for org.codehaus.groovy.eclipse.dsl.inferencing.suggestions.SuggestionsRequestor.java

Source

/*
 * Copyright 2011 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.codehaus.groovy.eclipse.dsl.inferencing.suggestions;

import java.util.List;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.ImportNode;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.FieldExpression;
import org.codehaus.groovy.ast.expr.StaticMethodCallExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.groovy.search.ITypeRequestor;
import org.eclipse.jdt.groovy.search.TypeLookupResult;
import org.eclipse.jdt.groovy.search.VariableScope;
import org.eclipse.jdt.internal.core.NamedMember;
import org.eclipse.jdt.internal.core.util.Util;

/**
 * 
 * 
 * @author Nieraj Singh
 * @created 2011-09-13
 */
public class SuggestionsRequestor implements ITypeRequestor {

    private final ASTNode nodeToLookFor;

    private SuggestionDescriptor descriptor;

    public SuggestionsRequestor(ASTNode nodeToLookFor) {
        this.nodeToLookFor = nodeToLookFor;
    }

    public VisitStatus acceptASTNode(ASTNode node, TypeLookupResult result, IJavaElement enclosingElement) {

        // check to see if the enclosing element does not enclose the
        // nodeToLookFor
        if (!interestingElement(enclosingElement)) {
            return VisitStatus.CANCEL_MEMBER;
        }

        if (node instanceof ImportNode) {
            node = ((ImportNode) node).getType();
            if (node == null) {
                return VisitStatus.CONTINUE;
            }

        }

        if (isValidNode(node) && doTest(node)) {
            Expression expression = (Expression) node;

            descriptor = createDescriptor(expression, result);
            return VisitStatus.STOP_VISIT;

        }

        return VisitStatus.CONTINUE;
    }

    public SuggestionDescriptor getSuggestionDescriptor() {
        return descriptor;
    }

    protected SuggestionDescriptor createDescriptor(Expression suggestionNode, TypeLookupResult result) {

        // get the declaring type and type of the member
        ClassNode declaringTypeNode = result.declaringType;
        ClassNode suggestionTypeNode = result.type;
        VariableScope scope = result.scope;

        String declaringTypeName = declaringTypeNode.getName();
        String suggestionType = suggestionTypeNode.getName();
        Object suggestionName = suggestionNode instanceof ConstantExpression
                ? ((ConstantExpression) suggestionNode).getValue()
                : suggestionNode.getText();
        String name = suggestionName instanceof String ? (String) suggestionName : null;
        // TODO: must figure out a way to determine if this is static. For now,
        // user has to remember
        // to set this correctly in the UI
        boolean isStatic = false;
        String javaDoc = null;
        boolean useNamedArguments = false;
        List<MethodParameter> parameters = null;
        boolean isMethod = isMethod(scope);

        boolean isActive = true;

        return isMethod
                ? new SuggestionDescriptor(declaringTypeName, isStatic, name, javaDoc, suggestionType,
                        useNamedArguments, parameters, isActive)
                : new SuggestionDescriptor(declaringTypeName, isStatic, name, javaDoc, suggestionType, isActive);
    }

    protected boolean isMethod(VariableScope scope) {
        if (scope != null) {
            return scope.isMethodCall();
        }
        return false;
    }

    protected boolean interestingElement(IJavaElement enclosingElement) {
        // the clinit is always interesting since the clinit contains static
        // initializers
        if (enclosingElement.getElementName().equals("<clinit>")) {
            return true;
        }

        if (enclosingElement instanceof NamedMember) {
            try {
                ISourceRange range = ((ISourceReference) enclosingElement).getSourceRange();
                return range.getOffset() <= nodeToLookFor.getStart()
                        && range.getOffset() + range.getLength() >= nodeToLookFor.getEnd();
            } catch (JavaModelException e) {
                Util.log(e);
            }
        }
        return false;
    }

    private boolean doTest(ASTNode node) {
        return node.getClass() == nodeToLookFor.getClass() && nodeToLookFor.getStart() == node.getStart()
                && nodeToLookFor.getEnd() == node.getEnd();
    }

    public static boolean isValidNode(ASTNode node) {
        return node instanceof VariableExpression || node instanceof StaticMethodCallExpression
                || node instanceof FieldExpression || node instanceof ConstantExpression;
    }
}