| /******************************************************************************* |
| * Copyright (c) 2000, 2011 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.codeassist.select; |
| |
| import java.util.List; |
| |
| import org.eclipse.jdt.core.compiler.InvalidInputException; |
| import org.eclipse.jdt.internal.codeassist.SelectionEngine; |
| import org.eclipse.jdt.internal.compiler.ast.*; |
| import org.eclipse.jdt.internal.compiler.parser.JavadocParser; |
| |
| /** |
| * Parser specialized for decoding javadoc comments which includes code selection. |
| */ |
| public class SelectionJavadocParser extends JavadocParser { |
| |
| int selectionStart; |
| int selectionEnd; |
| ASTNode selectedNode; |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=171019 |
| public boolean inheritDocTagSelected; |
| |
| public SelectionJavadocParser(SelectionParser sourceParser) { |
| super(sourceParser); |
| this.shouldReportProblems = false; |
| this.reportProblems = false; |
| this.kind = SELECTION_PARSER | TEXT_PARSE; |
| this.inheritDocTagSelected = false; |
| } |
| |
| /* |
| * Do not parse comment if selection is not included. |
| */ |
| public boolean checkDeprecation(int commentPtr) { |
| this.selectionStart = ((SelectionParser)this.sourceParser).selectionStart; |
| this.selectionEnd = ((SelectionParser)this.sourceParser).selectionEnd; |
| this.javadocStart = this.sourceParser.scanner.commentStarts[commentPtr]; |
| this.javadocEnd = this.sourceParser.scanner.commentStops[commentPtr]; |
| if (this.javadocStart <= this.selectionStart && this.selectionEnd <= this.javadocEnd) { |
| if (SelectionEngine.DEBUG) { |
| System.out.println("SELECTION in Javadoc:"); //$NON-NLS-1$ |
| } |
| super.checkDeprecation(commentPtr); |
| } else { |
| this.docComment = null; |
| } |
| return false; |
| } |
| |
| /* |
| * Replace stored Javadoc node with specific selection one. |
| */ |
| protected boolean commentParse() { |
| this.docComment = new SelectionJavadoc(this.javadocStart, this.javadocEnd); |
| return super.commentParse(); |
| } |
| |
| /* |
| * Create argument expression and store it if it includes selection. |
| */ |
| protected Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object typeRef, long[] dimPositions, long argNamePos) throws InvalidInputException { |
| // Create argument as we may need it after |
| Expression expression = (Expression) super.createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos); |
| // See if selection is in argument |
| int start = ((TypeReference)typeRef).sourceStart; |
| int end = ((TypeReference)typeRef).sourceEnd; |
| if (start <= this.selectionStart && this.selectionEnd <= end) { |
| this.selectedNode = expression; |
| this.abort = true; |
| if (SelectionEngine.DEBUG) { |
| System.out.println(" selected argument="+this.selectedNode); //$NON-NLS-1$ |
| } |
| } |
| return expression; |
| } |
| |
| /* |
| * Verify if field identifier positions include selection. |
| * If so, create field reference, store it and abort comment parse. |
| * Otherwise return null as we do not need this reference. |
| */ |
| protected Object createFieldReference(Object receiver) throws InvalidInputException { |
| int start = (int) (this.identifierPositionStack[0] >>> 32); |
| int end = (int) this.identifierPositionStack[0]; |
| if (start <= this.selectionStart && this.selectionEnd <= end) { |
| this.selectedNode = (ASTNode) super.createFieldReference(receiver); |
| this.abort = true; |
| if (SelectionEngine.DEBUG) { |
| System.out.println(" selected field="+this.selectedNode); //$NON-NLS-1$ |
| } |
| } |
| return null; |
| } |
| |
| /* |
| * Verify if method identifier positions include selection. |
| * If so, create field reference, store it and abort comment parse. |
| * Otherwise return null as we do not need this reference. |
| */ |
| protected Object createMethodReference(Object receiver, List arguments) throws InvalidInputException { |
| int memberPtr = this.identifierLengthStack[0] - 1; // may be > 0 for inner class constructor reference |
| int start = (int) (this.identifierPositionStack[memberPtr] >>> 32); |
| int end = (int) this.identifierPositionStack[memberPtr]; |
| if (start <= this.selectionStart && this.selectionEnd <= end) { |
| this.selectedNode = (ASTNode) super.createMethodReference(receiver, arguments); |
| this.abort = true; |
| if (SelectionEngine.DEBUG) { |
| System.out.println(" selected method="+this.selectedNode); //$NON-NLS-1$ |
| } |
| } |
| return null; |
| } |
| |
| /* |
| * Create type reference and verify if it includes selection. |
| * If so, store it and abort comment parse. |
| * Otherwise return null as we do not need this reference. |
| */ |
| protected Object createTypeReference(int primitiveToken) { |
| // Need to create type ref in case it was needed by members |
| TypeReference typeRef = (TypeReference) super.createTypeReference(primitiveToken); |
| |
| // See if node is concerned by selection |
| if (typeRef.sourceStart <= this.selectionStart && this.selectionEnd <= typeRef.sourceEnd) { |
| // See if selection is in one of tokens of qualification |
| if (typeRef instanceof JavadocQualifiedTypeReference) { |
| JavadocQualifiedTypeReference qualifiedTypeRef = (JavadocQualifiedTypeReference) typeRef; |
| int size = qualifiedTypeRef.tokens.length - 1; |
| for (int i=0; i<size; i++) { |
| int start = (int) (qualifiedTypeRef.sourcePositions[i] >>> 32); |
| int end = (int) qualifiedTypeRef.sourcePositions[i]; |
| if (start <= this.selectionStart && this.selectionEnd <= end) { |
| int pos = i + 1; |
| char[][] tokens = new char[pos][]; |
| int ptr = this.identifierPtr - size; |
| System.arraycopy(this.identifierStack, ptr, tokens, 0, pos); |
| long[] positions = new long[pos]; |
| System.arraycopy(this.identifierPositionStack, ptr, positions, 0, pos); |
| this.selectedNode = new JavadocQualifiedTypeReference(tokens, positions, this.tagSourceStart, this.tagSourceEnd); |
| this.abort = true; // we got selected node => cancel parse |
| if (SelectionEngine.DEBUG) { |
| System.out.println(" selected partial qualified type="+this.selectedNode); //$NON-NLS-1$ |
| } |
| return typeRef; |
| } |
| } |
| // Selection is in last token => we'll store type ref as this |
| } |
| // Store type ref as selected node |
| this.selectedNode = typeRef; |
| this.abort = true; // we got selected node => cancel parse |
| if (SelectionEngine.DEBUG) { |
| System.out.println(" selected type="+this.selectedNode); //$NON-NLS-1$ |
| } |
| } |
| return typeRef; |
| } |
| |
| /* |
| * Push param reference and verify if it includes selection. |
| * If so, store it and abort comment parse. |
| */ |
| protected boolean pushParamName(boolean isTypeParam) { |
| if (super.pushParamName(isTypeParam)) { |
| Expression expression = (Expression) this.astStack[this.astPtr--]; |
| // See if expression is concerned by selection |
| if (expression.sourceStart <= this.selectionStart && this.selectionEnd <= expression.sourceEnd) { |
| this.selectedNode = expression; |
| this.abort = true; // we got selected node => cancel parse |
| if (SelectionEngine.DEBUG) { |
| System.out.println(" selected param="+this.selectedNode); //$NON-NLS-1$ |
| } |
| } |
| } |
| return false; |
| } |
| |
| /* |
| * Store selected node into doc comment. |
| */ |
| protected void updateDocComment() { |
| if (this.selectedNode instanceof Expression) { |
| ((SelectionJavadoc) this.docComment).selectedNode = (Expression) this.selectedNode; |
| } else if (this.inheritDocTagSelected) { |
| ((SelectionJavadoc) this.docComment).inheritDocSelected = true; |
| } |
| } |
| |
| /* |
| * Sets a flag to denote that selection has taken place on an inheritDoc tag |
| */ |
| protected void parseInheritDocTag() { |
| if (this.tagSourceStart == this.selectionStart && this.tagSourceEnd == this.selectionEnd) |
| this.inheritDocTagSelected = true; |
| } |
| } |