Index: codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java,v retrieving revision 1.105 diff -u -r1.105 SelectionEngine.java --- codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java 18 Mar 2005 09:17:27 -0000 1.105 +++ codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java 18 Mar 2005 10:01:42 -0000 @@ -367,7 +367,7 @@ int nextCharacterPosition = selectionStart; char currentCharacter = ' '; try { - while(currentPosition > 0){ + lineLoop: while(currentPosition > 0){ if(source[currentPosition] == '\\' && source[currentPosition+1] == 'u') { int pos = currentPosition + 2; @@ -393,8 +393,11 @@ nextCharacterPosition = currentPosition+1; } - if(currentCharacter == '\r' || currentCharacter == '\n') { - break; + switch(currentCharacter) { + case '\r': + case '\n': + case '/': + break lineLoop; } currentPosition--; } @@ -410,14 +413,16 @@ } catch (InvalidInputException e) { return false; } - if((token == TerminalTokens.TokenNamethis || - token == TerminalTokens.TokenNamesuper || - token == TerminalTokens.TokenNameIdentifier) && - scanner.startPosition <= selectionStart && - selectionStart <= scanner.currentPosition) { - lastIdentifierStart = scanner.startPosition; - lastIdentifierEnd = scanner.currentPosition - 1; - lastIdentifier = scanner.getCurrentTokenSource(); + switch (token) { + case TerminalTokens.TokenNamethis: + case TerminalTokens.TokenNamesuper: + case TerminalTokens.TokenNameIdentifier: + if (scanner.startPosition <= selectionStart && selectionStart <= scanner.currentPosition) { + lastIdentifierStart = scanner.startPosition; + lastIdentifierEnd = scanner.currentPosition - 1; + lastIdentifier = scanner.getCurrentTokenSource(); + } + break; } } while (token != TerminalTokens.TokenNameEOF); } else { @@ -642,8 +647,14 @@ System.out.println("SELECTION - Source :"); //$NON-NLS-1$ System.out.println(source); } - if (!checkSelection(source, selectionSourceStart, selectionSourceEnd)) + if (!checkSelection(source, selectionSourceStart, selectionSourceEnd)) { return; + } + if (DEBUG) { + System.out.print("SELECTION - Checked : \""); //$NON-NLS-1$ + System.out.print(new String(source, actualSelectionStart, actualSelectionEnd-actualSelectionStart+1)); + System.out.println('"'); + } try { this.acceptedAnswer = false; CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit); Index: codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java,v retrieving revision 1.70 diff -u -r1.70 SelectionParser.java --- codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java 28 Feb 2005 19:45:56 -0000 1.70 +++ codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java 18 Mar 2005 10:01:43 -0000 @@ -42,6 +42,8 @@ public SelectionParser(ProblemReporter problemReporter) { super(problemReporter); + this.javadocParser = new SelectionJavadocParser(this); + this.javadocParser.checkDocComment = true; } public char[] assistIdentifier(){ return ((SelectionScanner)scanner).selectionIdentifier; Index: compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java,v retrieving revision 1.77 diff -u -r1.77 AbstractMethodDeclaration.java --- compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java 23 Feb 2005 02:47:28 -0000 1.77 +++ compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java 18 Mar 2005 10:01:43 -0000 @@ -318,6 +318,9 @@ public StringBuffer print(int tab, StringBuffer output) { + if (this.javadoc != null) { + this.javadoc.print(tab, output); + } printIndent(tab, output); printModifiers(this.modifiers, output); if (this.annotations != null) printAnnotations(this.annotations, output); Index: compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java,v retrieving revision 1.60 diff -u -r1.60 FieldDeclaration.java --- compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java 23 Feb 2005 02:47:27 -0000 1.60 +++ compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java 18 Mar 2005 10:01:43 -0000 @@ -141,7 +141,14 @@ return this.binding.isStatic(); return (this.modifiers & AccStatic) != 0; } - + + public StringBuffer printStatement(int indent, StringBuffer output) { + if (this.javadoc != null) { + this.javadoc.print(indent, output); + } + return super.printStatement(indent, output); + } + public void resolve(MethodScope initializationScope) { // the two could be regrouped into Index: compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java,v retrieving revision 1.99 diff -u -r1.99 TypeDeclaration.java --- compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java 15 Mar 2005 10:43:16 -0000 1.99 +++ compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java 18 Mar 2005 10:01:44 -0000 @@ -848,6 +848,9 @@ public StringBuffer print(int indent, StringBuffer output) { + if (this.javadoc != null) { + this.javadoc.print(indent, output); + } if ((this.bits & IsAnonymousTypeMASK) == 0) { printIndent(indent, output); printHeader(0, output); Index: compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java,v retrieving revision 1.36 diff -u -r1.36 AbstractCommentParser.java --- compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java 7 Mar 2005 14:11:42 -0000 1.36 +++ compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java 18 Mar 2005 10:01:45 -0000 @@ -58,6 +58,7 @@ // Kind of comment parser public final static int COMPIL_PARSER = 0x00000001; public final static int DOM_PARSER = 0x00000002; + public final static int SELECTION_PARSER = 0x00000003; // Parse infos public Scanner scanner; @@ -83,7 +84,9 @@ protected int[] lineEnds; // Flags - protected boolean lineStarted = false, inlineTagStarted = false; + protected boolean lineStarted = false; + protected boolean inlineTagStarted = false; + protected boolean abort = false; protected int kind; // Line pointers @@ -95,6 +98,7 @@ protected int identifierLengthPtr; protected int[] identifierLengthStack; protected long[] identifierPositionStack; + // Ast stack protected static int AstStackIncrement = 10; protected int astPtr; @@ -151,7 +155,7 @@ int invalidInlineTagLineEnd = -1; // Loop on each comment character - while (this.index < this.endComment) { + while (!abort && this.index < this.endComment) { previousPosition = this.index; previousChar = nextCharacter; @@ -394,6 +398,7 @@ Object typeRef; try { typeRef = parseQualifiedName(false); + if (this.abort) return null; // May be aborted by specialized parser } catch (InvalidInputException e) { break nextArg; } @@ -480,6 +485,7 @@ if (token == TerminalTokens.TokenNameCOMMA) { // Create new argument Object argument = createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos); + if (this.abort) return null; // May be aborted by specialized parser arguments.add(argument); consumeToken(); iToken++; @@ -493,6 +499,7 @@ } // Create new argument Object argument = createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos); + if (this.abort) return null; // May be aborted by specialized parser arguments.add(argument); consumeToken(); return createMethodReference(receiver, arguments); @@ -988,6 +995,7 @@ if (typeRef == null) { typeRefStartPosition = this.scanner.getCurrentTokenStartPosition(); typeRef = parseQualifiedName(true); + if (this.abort) return false; // May be aborted by specialized parser break; } default : @@ -1066,6 +1074,7 @@ int start = this.scanner.currentPosition; try { Object typeRef = parseQualifiedName(true); + if (this.abort) return false; // May be aborted by specialized parser if (typeRef == null) { if (this.reportProblems) this.sourceParser.problemReporter().javadocMissingThrowsClassName(this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers); Index: compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java,v retrieving revision 1.34 diff -u -r1.34 JavadocParser.java --- compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java 8 Mar 2005 16:34:48 -0000 1.34 +++ compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java 18 Mar 2005 10:01:46 -0000 @@ -250,7 +250,7 @@ } } catch (ClassCastException ex) { - throw new InvalidInputException(); + throw new InvalidInputException(); } } /* (non-Javadoc) Index: codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadoc.java =================================================================== RCS file: codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadoc.java diff -N codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadoc.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadoc.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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 org.eclipse.jdt.internal.compiler.ast.*; +import org.eclipse.jdt.internal.compiler.lookup.*; + +/** + * Node representing a Javadoc comment including code selection. + */ +public class SelectionJavadoc extends Javadoc { + + Expression selectedNode; + + public SelectionJavadoc(int sourceStart, int sourceEnd) { + super(sourceStart, sourceEnd); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.compiler.ast.Javadoc#print(int, java.lang.StringBuffer) + */ + public StringBuffer print(int indent, StringBuffer output) { + super.print(indent, output); + if (this.selectedNode != null) { + String selectedString = null; + if (this.selectedNode instanceof JavadocFieldReference) { + JavadocFieldReference fieldRef = (JavadocFieldReference) this.selectedNode; + if (fieldRef.methodBinding != null) { + selectedString = "'); + } + return output; + } + + /** + * Resolve selected node if not null and throw exception to let clients know + * that it has been found. + * + * @throws SelectionNodeFound + */ + public void resolve(ClassScope scope) { + if (this.selectedNode != null) { + this.selectedNode.resolveType(scope); + Binding binding = null; + if (this.selectedNode instanceof JavadocFieldReference) { + JavadocFieldReference fieldRef = (JavadocFieldReference) this.selectedNode; + binding = fieldRef.binding; + if (binding == null && fieldRef.methodBinding != null) { + binding = fieldRef.methodBinding; + } + } else if (this.selectedNode instanceof JavadocMessageSend) { + binding = ((JavadocMessageSend) this.selectedNode).binding; + } else if (this.selectedNode instanceof JavadocAllocationExpression) { + binding = ((JavadocAllocationExpression) this.selectedNode).binding; + } else if (this.selectedNode instanceof JavadocSingleNameReference) { + binding = ((JavadocSingleNameReference) this.selectedNode).binding; + } else if (this.selectedNode instanceof JavadocSingleTypeReference) { + JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) this.selectedNode; + if (typeRef.packageBinding == null) { + binding = typeRef.resolvedType; + } + } else if (this.selectedNode instanceof JavadocQualifiedTypeReference) { + JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) this.selectedNode; + if (typeRef.packageBinding == null) { + binding = typeRef.resolvedType; + } + } else { + binding = this.selectedNode.resolvedType; + } + throw new SelectionNodeFound(binding); + } + } + + /** + * Resolve selected node if not null and throw exception to let clients know + * that it has been found. + * + * @throws SelectionNodeFound + */ + public void resolve(MethodScope scope) { + if (this.selectedNode != null) { + this.selectedNode.resolveType(scope); + Binding binding = null; + if (this.selectedNode instanceof JavadocFieldReference) { + JavadocFieldReference fieldRef = (JavadocFieldReference) this.selectedNode; + binding = fieldRef.binding; + if (binding == null && fieldRef.methodBinding != null) { + binding = fieldRef.methodBinding; + } + } else if (this.selectedNode instanceof JavadocMessageSend) { + binding = ((JavadocMessageSend) this.selectedNode).binding; + } else if (this.selectedNode instanceof JavadocAllocationExpression) { + binding = ((JavadocAllocationExpression) this.selectedNode).binding; + } else if (this.selectedNode instanceof JavadocSingleNameReference) { + binding = ((JavadocSingleNameReference) this.selectedNode).binding; + } else if (this.selectedNode instanceof JavadocSingleTypeReference) { + JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) this.selectedNode; + if (typeRef.packageBinding == null) { + binding = typeRef.resolvedType; + } + } else if (this.selectedNode instanceof JavadocQualifiedTypeReference) { + JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) this.selectedNode; + if (typeRef.packageBinding == null) { + binding = typeRef.resolvedType; + } + } else { + binding = this.selectedNode.resolvedType; + } + throw new SelectionNodeFound(binding); + } + } + +} Index: codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadocParser.java =================================================================== RCS file: codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadocParser.java diff -N codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadocParser.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadocParser.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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; + + public SelectionJavadocParser(SelectionParser sourceParser) { + super(sourceParser); + this.kind = SELECTION_PARSER; + } + + /* + * Do not parse comment if selection is not included. + */ + public boolean checkDeprecation(int javadocStart, int javadocEnd) { + this.selectionStart = ((SelectionParser)sourceParser).selectionStart; + this.selectionEnd = ((SelectionParser)sourceParser).selectionEnd; + if (javadocStart <= this.selectionStart && this.selectionEnd <= javadocEnd) { + if (SelectionEngine.DEBUG) { + System.out.println("SELECTION in Javadoc:"); //$NON-NLS-1$ + } + super.checkDeprecation(javadocStart, javadocEnd); + } else { + this.docComment = null; + } + return false; + } + + /* + * Replace stored Javadoc node with specific selection one. + */ + protected boolean commentParse(int javadocStart, int javadocEnd) { + this.docComment = new SelectionJavadoc(javadocStart, javadocEnd); + return super.commentParse(javadocStart, javadocEnd); + } + + /* + * 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) { + selectedNode = expression; + this.abort = true; + if (SelectionEngine.DEBUG) { + System.out.println(" selected argument="+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) { + selectedNode = (ASTNode) super.createFieldReference(receiver); + this.abort = true; + if (SelectionEngine.DEBUG) { + System.out.println(" selected field="+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 start = (int) (this.identifierPositionStack[0] >>> 32); + int end = (int) this.identifierPositionStack[0]; + if (start <= this.selectionStart && this.selectionEnd <= end) { + selectedNode = (ASTNode) super.createMethodReference(receiver, arguments); + this.abort = true; + if (SelectionEngine.DEBUG) { + System.out.println(" selected method="+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>> 32); + int end = (int) qualifiedTypeRef.sourcePositions[i]; + if (start <= this.selectionStart && this.selectionEnd <= end) { + int pos = i + 1; + char[][] tokens = new char[pos][]; + System.arraycopy(this.identifierStack, this.identifierPtr+1, tokens, 0, pos); + long[] positions = new long[pos]; + System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, pos); + 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="+selectedNode); //$NON-NLS-1$ + } + return typeRef; + } + } + // Selection is in last token => we'll store type ref as this + } + // Store type ref as selected node + selectedNode = typeRef; + this.abort = true; // we got selected node => cancel parse + if (SelectionEngine.DEBUG) { + System.out.println(" selected type="+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) astStack[astPtr--]; + // See if expression is concerned by selection + if (expression.sourceStart <= this.selectionStart && this.selectionEnd <= expression.sourceEnd) { + selectedNode = expression; + this.abort = true; // we got selected node => cancel parse + if (SelectionEngine.DEBUG) { + System.out.println(" selected param="+selectedNode); //$NON-NLS-1$ + } + } + } + return false; + } + + /* + * Store selected node into doc comment. + */ + protected void updateDocComment() { + if (selectedNode instanceof Expression) { + ((SelectionJavadoc) this.docComment).selectedNode = (Expression) selectedNode; + } + } +}