/*
* The contents of this file are subject to the terms of the Common Development
* and Distribution License (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at http://www.netbeans.org/cddl.html
* or http://www.netbeans.org/cddl.txt.
*
* When distributing Covered Code, include this CDDL Header Notice in each file
* and include the License file at http://www.netbeans.org/cddl.txt.
* If applicable, add the following below the CDDL Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.modules.gwt4nb.hints;
import java.util.Collections;
import java.util.List;
import javax.lang.model.element.Element;
import com.sun.source.tree.Tree;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.VariableTree;
import com.sun.source.util.SourcePositions;
import org.netbeans.api.java.source.CompilationInfo;
import org.netbeans.spi.editor.hints.Fix;
import org.netbeans.spi.editor.hints.ErrorDescription;
import org.netbeans.spi.editor.hints.ErrorDescriptionFactory;
import org.netbeans.api.lexer.Token;
import org.netbeans.api.lexer.TokenSequence;
import org.netbeans.api.java.lexer.JavaTokenId;
import org.netbeans.spi.editor.hints.Severity;
/**
*
* @author Tomasz.Slota@Sun.COM
*/
public class HintsUtils {
public static ErrorDescription createProblem(Element subject, CompilationInfo cinfo,
String description){
return createProblem(subject, cinfo, description, Severity.ERROR, Collections.<Fix>emptyList());
}
public static ErrorDescription createProblem(Element subject, CompilationInfo cinfo,
String description, Severity severity){
return createProblem(subject, cinfo, description, severity, Collections.<Fix>emptyList());
}
public static ErrorDescription createProblem(Element subject, CompilationInfo cinfo, String description,
Severity severity, Fix fix){
return createProblem(subject, cinfo, description, severity, Collections.singletonList(fix));
}
public static ErrorDescription createProblem(Element subject, CompilationInfo cinfo, String description, Fix fix){
return createProblem(subject, cinfo, description, Severity.ERROR, Collections.singletonList(fix));
}
public static ErrorDescription createProblem(Element subject, CompilationInfo cinfo,
String description, Severity severity, List<Fix> fixes){
ErrorDescription err = null;
List<Fix> fixList = fixes == null ? Collections.<Fix>emptyList() : fixes;
// by default place error annotation on the element being checked
Tree elementTree = cinfo.getTrees().getTree(subject);
if (elementTree != null){
TextSpan underlineSpan = getUnderlineSpan(cinfo, elementTree);
err = ErrorDescriptionFactory.createErrorDescription(
severity, description, fixList, cinfo.getFileObject(),
underlineSpan.getStartOffset(), underlineSpan.getEndOffset());
} else{
// report problem
}
return err;
}
/**
* This method returns the part of the syntax tree to be highlighted.
* It will be usually the class/method/variable identifier.
*/
@SuppressWarnings("rawtypes")
public static TextSpan getUnderlineSpan(CompilationInfo info, Tree tree){
SourcePositions srcPos = info.getTrees().getSourcePositions();
int startOffset = (int) srcPos.getStartPosition(info.getCompilationUnit(), tree);
int endOffset = (int) srcPos.getEndPosition(info.getCompilationUnit(), tree);
Tree startSearchingForNameIndentifierBehindThisTree = null;
if (tree.getKind() == Tree.Kind.CLASS){
startSearchingForNameIndentifierBehindThisTree = ((ClassTree)tree).getModifiers();
} else if (tree.getKind() == Tree.Kind.METHOD){
startSearchingForNameIndentifierBehindThisTree = ((MethodTree)tree).getReturnType();
} else if (tree.getKind() == Tree.Kind.VARIABLE){
startSearchingForNameIndentifierBehindThisTree = ((VariableTree)tree).getType();
}
if (startSearchingForNameIndentifierBehindThisTree != null){
int searchStart = (int) srcPos.getEndPosition(info.getCompilationUnit(),
startSearchingForNameIndentifierBehindThisTree);
TokenSequence tokenSequence = info.getTreeUtilities().tokensFor(tree);
if (tokenSequence != null){
boolean eob = false;
tokenSequence.move(searchStart);
do{
eob = !tokenSequence.moveNext();
}
while (!eob && tokenSequence.token().id() != JavaTokenId.IDENTIFIER);
if (!eob){
Token<?> identifier = tokenSequence.token();
startOffset = identifier.offset(info.getTokenHierarchy());
endOffset = startOffset + identifier.length();
}
}
}
return new TextSpan(startOffset, endOffset);
}
/**
* Represents a span of text
*/
public static class TextSpan{
private int startOffset;
private int endOffset;
public TextSpan(int startOffset, int endOffset){
this.startOffset = startOffset;
this.endOffset = endOffset;
}
public int getStartOffset(){
return startOffset;
}
public int getEndOffset(){
return endOffset;
}
}
}