diff options
author | Ian Stewart-Binks | 2016-03-14 15:54:06 +0000 |
---|---|---|
committer | Ian Stewart-Binks | 2016-04-11 18:16:24 +0000 |
commit | aed4a9f28df286af0986b1da92fa77f2897157b7 (patch) | |
tree | d2cb4fb5f122eb5118293f0903015cf85dbf1c7c | |
parent | d5f4374b19ae1980cff2dd87f8222e64a621fb2d (diff) | |
download | webtools.jsdt-aed4a9f28df286af0986b1da92fa77f2897157b7.tar.gz webtools.jsdt-aed4a9f28df286af0986b1da92fa77f2897157b7.tar.xz webtools.jsdt-aed4a9f28df286af0986b1da92fa77f2897157b7.zip |
Bug 486776 - Refactor Keyword Completion
Change-Id: I8d9d6c5e3b122bae80152f263fc75b9fc94030a9
Signed-off-by: Ian Stewart-Binks <istewart@redhat.com>
20 files changed, 652 insertions, 729 deletions
diff --git a/bundles/org.eclipse.wst.jsdt.core/.classpath b/bundles/org.eclipse.wst.jsdt.core/.classpath index 1963e9526..28d9f2921 100644 --- a/bundles/org.eclipse.wst.jsdt.core/.classpath +++ b/bundles/org.eclipse.wst.jsdt.core/.classpath @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="src"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<accessrules>
<accessrule kind="accessible" pattern="**/nashorn/**"/>
</accessrules>
- </classpathentry>
+ </classpathentry> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/bundles/org.eclipse.wst.jsdt.core/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.wst.jsdt.core/.settings/org.eclipse.jdt.core.prefs index 1b20b4cdd..6e453a438 100644 --- a/bundles/org.eclipse.wst.jsdt.core/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.eclipse.wst.jsdt.core/.settings/org.eclipse.jdt.core.prefs @@ -26,7 +26,7 @@ org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -127,7 +127,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/CompletionEngine.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/CompletionEngine.java index af3f1a945..917c0760b 100644 --- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/CompletionEngine.java +++ b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/CompletionEngine.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2016 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 @@ -49,7 +49,6 @@ import org.eclipse.wst.jsdt.internal.codeassist.complete.CompletionOnJavadocPara import org.eclipse.wst.jsdt.internal.codeassist.complete.CompletionOnJavadocQualifiedTypeReference; import org.eclipse.wst.jsdt.internal.codeassist.complete.CompletionOnJavadocSingleTypeReference; import org.eclipse.wst.jsdt.internal.codeassist.complete.CompletionOnJavadocTag; -import org.eclipse.wst.jsdt.internal.codeassist.complete.CompletionOnKeyword; import org.eclipse.wst.jsdt.internal.codeassist.complete.CompletionOnLocalName; import org.eclipse.wst.jsdt.internal.codeassist.complete.CompletionOnMemberAccess; import org.eclipse.wst.jsdt.internal.codeassist.complete.CompletionOnMessageSend; @@ -117,7 +116,6 @@ import org.eclipse.wst.jsdt.internal.compiler.lookup.BlockScope; import org.eclipse.wst.jsdt.internal.compiler.lookup.ClassScope; import org.eclipse.wst.jsdt.internal.compiler.lookup.CompilationUnitBinding; import org.eclipse.wst.jsdt.internal.compiler.lookup.CompilationUnitScope; -import org.eclipse.wst.jsdt.internal.compiler.lookup.ExtraCompilerModifiers; import org.eclipse.wst.jsdt.internal.compiler.lookup.FieldBinding; import org.eclipse.wst.jsdt.internal.compiler.lookup.FunctionTypeBinding; import org.eclipse.wst.jsdt.internal.compiler.lookup.ImportBinding; @@ -882,9 +880,6 @@ public final class CompletionEngine setSourceRange(type.sourceStart, type.sourceEnd); findTypesAndPackages(this.completionToken, scope, new ObjectVector()); - if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { - findKeywordsForMember(this.completionToken, field.modifiers); - } if (!field.isLocalVariable && field.modifiers == ClassFileConstants.AccDefault) { SourceTypeBinding enclosingType = scope.enclosingSourceType(); @@ -910,13 +905,7 @@ public final class CompletionEngine singleNameReference.isInsideAnnotationAttribute); // can be the start of a qualified type name findTypesAndPackages(this.completionToken, scope, new ObjectVector()); - if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { - if (this.completionToken != null && this.completionToken.length != 0) { - findKeywords(this.completionToken, singleNameReference.possibleKeywords, false, false); - } else { - findTrueOrFalseKeywords(singleNameReference.possibleKeywords); - } - } + if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){ if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) { ReferenceBinding ref = scope.enclosingSourceType(); @@ -992,8 +981,7 @@ public final class CompletionEngine null, new ObjectVector()); } - } - else if (astNode instanceof CompletionOnQualifiedNameReference) { + } else if (astNode instanceof CompletionOnQualifiedNameReference) { this.insideQualifiedReference = true; CompletionOnQualifiedNameReference ref = @@ -1067,36 +1055,6 @@ public final class CompletionEngine findClassField(this.completionToken, (TypeBinding) qualifiedBinding, scope); } - MethodScope methodScope = null; - if (!isInsideAnnotationAttribute && - !this.requestor.isIgnored(CompletionProposal.KEYWORD) && - ((scope instanceof MethodScope && !((MethodScope)scope).isStatic) - || ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) { - if (this.completionToken.length > 0) { - findKeywords(this.completionToken, new char[][]{Keywords.THIS}, false, true); - } else { - int relevance = computeBaseRelevance(); - relevance += computeRelevanceForResolution(); - relevance += computeRelevanceForInterestingProposal(); - relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.THIS); - relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords - relevance += R_NON_INHERITED; - - this.noProposal = false; - if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { - CompletionProposal proposal = this.createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition); - proposal.setName(Keywords.THIS); - proposal.setCompletion(Keywords.THIS); - proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); - proposal.setRelevance(relevance); - this.requestor.accept(proposal); - if (DEBUG) { - this.printDebug(proposal); - } - } - } - } - if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { findFields( this.completionToken, @@ -1256,9 +1214,6 @@ public final class CompletionEngine } } else { if (!access.isInsideAnnotation) { - if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { - findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false); - } findFieldsAndMethods( this.completionToken, @@ -1447,11 +1402,6 @@ public final class CompletionEngine findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind, variable.modifiers); } - } else if (astNode instanceof CompletionOnKeyword) { - if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { - CompletionOnKeyword keyword = (CompletionOnKeyword)astNode; - findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), keyword.canCompleteEmptyToken(), false); - } } else if(astNode instanceof CompletionOnBrankStatementLabel) { if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) { CompletionOnBrankStatementLabel label = (CompletionOnBrankStatementLabel) astNode; @@ -1894,21 +1844,6 @@ public final class CompletionEngine } } return; - } else if(importReference instanceof CompletionOnKeyword) { - contextAccepted = true; - this.buildContext(importReference, null, null, null); - if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { - setSourceRange(importReference.sourceStart, importReference.sourceEnd); - CompletionOnKeyword keyword = (CompletionOnKeyword)importReference; - findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, false); - } - if(this.noProposal && this.problem != null) { - this.requestor.completionFailure(this.problem); - if(DEBUG) { - this.printDebug(this.problem); - } - } - return; } } } @@ -1966,17 +1901,6 @@ public final class CompletionEngine this.printDebug(this.problem); } } - /* Ignore package, import, class & interface keywords for now... - if (!completionNodeFound) { - if (parsedUnit == null || parsedUnit.types == null) { - // this is not good enough... can still be trying to define a second type - CompletionScanner scanner = (CompletionScanner) this.parser.scanner; - setSourceRange(scanner.completedIdentifierStart, scanner.completedIdentifierEnd); - findKeywords(scanner.completionIdentifier, mainDeclarations, null); - } - // currently have no way to know if extends/implements are possible keywords - } - */ } catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D if(DEBUG) { System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$ @@ -3272,156 +3196,6 @@ public final class CompletionEngine } } - // what about onDemand types? Ignore them since it does not happen! - // import p1.p2.A.*; - private void findKeywords(char[] keyword, char[][] choices, boolean canCompleteEmptyToken, boolean staticFieldsAndMethodOnly) { - if(choices == null || choices.length == 0) return; - - int length = keyword.length; - if (canCompleteEmptyToken || length > 0) - for (int i = 0; i < choices.length; i++) - if (length <= choices[i].length - && CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */ - )){ - int relevance = computeBaseRelevance(); - relevance += computeRelevanceForResolution(); - relevance += computeRelevanceForInterestingProposal(); - relevance += computeRelevanceForCaseMatching(keyword, choices[i]); - relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors - if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED; - - if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) { - relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN); - relevance += computeRelevanceForQualification(false); - } - this.noProposal = false; - if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { - CompletionProposal proposal = this.createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition); - proposal.setName(choices[i]); - proposal.setCompletion(choices[i]); - proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); - proposal.setRelevance(relevance); - this.requestor.accept(proposal); - if(DEBUG) { - this.printDebug(proposal); - } - } - } - } - private void findTrueOrFalseKeywords(char[][] choices) { - if(choices == null || choices.length == 0) return; - - if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != TypeBinding.BOOLEAN) return; - - for (int i = 0; i < choices.length; i++) { - if (CharOperation.equals(choices[i], Keywords.TRUE) || - CharOperation.equals(choices[i], Keywords.FALSE) - ){ - int relevance = computeBaseRelevance(); - relevance += computeRelevanceForResolution(); - relevance += computeRelevanceForInterestingProposal(); - relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]); - relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors - relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN); - relevance += computeRelevanceForQualification(false); - relevance += R_TRUE_OR_FALSE; - - this.noProposal = false; - if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { - CompletionProposal proposal = this.createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition); - proposal.setName(choices[i]); - proposal.setCompletion(choices[i]); - proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); - proposal.setRelevance(relevance); - this.requestor.accept(proposal); - if(DEBUG) { - this.printDebug(proposal); - } - } - } - } - } - - private void findKeywordsForMember(char[] token, int modifiers) { - char[][] keywords = new char[Keywords.COUNT][]; - int count = 0; - - // visibility - if((modifiers & ClassFileConstants.AccPrivate) == 0 - && (modifiers & ClassFileConstants.AccProtected) == 0 - && (modifiers & ClassFileConstants.AccPublic) == 0) { - keywords[count++] = Keywords.PROTECTED; - keywords[count++] = Keywords.PUBLIC; - if((modifiers & ClassFileConstants.AccAbstract) == 0) { - keywords[count++] = Keywords.PRIVATE; - } - } - - if((modifiers & ClassFileConstants.AccAbstract) == 0) { - // abtract - if((modifiers & ~(ExtraCompilerModifiers.AccVisibilityMASK | ClassFileConstants.AccStatic)) == 0) { - keywords[count++] = Keywords.ABSTRACT; - } - - // final - if((modifiers & ClassFileConstants.AccFinal) == 0) { - keywords[count++] = Keywords.FINAL; - } - - // static - if((modifiers & ClassFileConstants.AccStatic) == 0) { - keywords[count++] = Keywords.STATIC; - } - - boolean canBeField = true; - boolean canBeMethod = true; - boolean canBeType = true; - if((modifiers & ClassFileConstants.AccNative) != 0 - || (modifiers & ClassFileConstants.AccStrictfp) != 0) { - canBeField = false; - canBeType = false; - } - - - if(canBeField) { - // transient - keywords[count++] = Keywords.TRANSIENT; - - - // volatile - keywords[count++] = Keywords.VOLATILE; - } - - if(canBeMethod) { - // native - if((modifiers & ClassFileConstants.AccNative) == 0) { - keywords[count++] = Keywords.NATIVE; - } - - // strictfp - if((modifiers & ClassFileConstants.AccStrictfp) == 0) { - keywords[count++] = Keywords.STRICTFP; - } - - // synchronized - keywords[count++] = Keywords.SYNCHRONIZED; - - } - - if(canBeType) { - keywords[count++] = Keywords.CLASS; - keywords[count++] = Keywords.INTERFACE; - } - } else { - // class - keywords[count++] = Keywords.CLASS; - keywords[count++] = Keywords.INTERFACE; - } - System.arraycopy(keywords, 0, keywords = new char[count][], 0, count); - - findKeywords(token, keywords, false, false); - } - private void findMemberTypes( char[] typeName, ReferenceBinding receiverType, @@ -6288,9 +6062,6 @@ public final class CompletionEngine case CompletionProposal.FIELD_REF : buffer.append("FIELD_REF"); //$NON-NLS-1$ break; - case CompletionProposal.KEYWORD : - buffer.append("KEYWORD"); //$NON-NLS-1$ - break; case CompletionProposal.LABEL_REF : buffer.append("LABEL_REF"); //$NON-NLS-1$ break; @@ -6833,7 +6604,7 @@ public final class CompletionEngine * function() { * foo.bar = function() {}; * }*/ - if(method.declaringClass != null && + if (method.declaringClass != null && (!(method instanceof LocalFunctionBinding) || !(method.declaringClass instanceof CompilationUnitBinding)) ) { /* if declaring type is a compilation unit, then use global type diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionOnKeyword.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionOnKeyword.java deleted file mode 100644 index 0a9c3d9e7..000000000 --- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionOnKeyword.java +++ /dev/null @@ -1,18 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2007 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.wst.jsdt.internal.codeassist.complete; - -public interface CompletionOnKeyword { - - char[] getToken(); - char[][] getPossibleKeywords(); - boolean canCompleteEmptyToken(); -} diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionOnKeyword1.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionOnKeyword1.java deleted file mode 100644 index 634c08cff..000000000 --- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionOnKeyword1.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2007 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.wst.jsdt.internal.codeassist.complete; - -import org.eclipse.wst.jsdt.internal.compiler.ast.SingleTypeReference; -import org.eclipse.wst.jsdt.internal.compiler.lookup.Scope; -import org.eclipse.wst.jsdt.internal.compiler.lookup.TypeBinding; - -public class CompletionOnKeyword1 extends SingleTypeReference implements CompletionOnKeyword { - private char[][] possibleKeywords; - public boolean canCompleteEmptyToken; - - public CompletionOnKeyword1(char[] token, long pos, char[] possibleKeyword) { - this(token, pos, new char[][]{possibleKeyword}); - } - public CompletionOnKeyword1(char[] token, long pos, char[][] possibleKeywords) { - super(token, pos); - this.possibleKeywords = possibleKeywords; - } - public boolean canCompleteEmptyToken() { - return this.canCompleteEmptyToken; - } - public char[] getToken() { - return token; - } - public char[][] getPossibleKeywords() { - return possibleKeywords; - } - public void aboutToResolve(Scope scope) { - getTypeBinding(scope); - } - protected TypeBinding getTypeBinding(Scope scope) { - throw new CompletionNodeFound(this, scope); - } - public StringBuffer printExpression(int indent, StringBuffer output){ - - return output.append("<CompleteOnKeyword:").append(token).append('>'); //$NON-NLS-1$ - } -} diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionOnKeyword2.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionOnKeyword2.java deleted file mode 100644 index 0750b0207..000000000 --- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionOnKeyword2.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2009 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.wst.jsdt.internal.codeassist.complete; - -import org.eclipse.wst.jsdt.internal.compiler.ast.ImportReference; - -public class CompletionOnKeyword2 extends ImportReference implements CompletionOnKeyword { - private char[] token; - private char[][] possibleKeywords; - public CompletionOnKeyword2(char[] token, long pos, char[][] possibleKeywords) { - super(new char[][]{token}, new long[]{pos}, false); - this.token = token; - this.possibleKeywords = possibleKeywords; - } - public boolean canCompleteEmptyToken() { - return false; - } - public char[] getToken() { - return token; - } - public char[][] getPossibleKeywords() { - return possibleKeywords; - } - public StringBuffer print(int indent, StringBuffer output, boolean withOnDemand) { - - return printIndent(indent, output).append("<CompleteOnKeyword:").append(token).append('>'); //$NON-NLS-1$ - } -} diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionOnKeyword3.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionOnKeyword3.java deleted file mode 100644 index 2ffa89152..000000000 --- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionOnKeyword3.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2007 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.wst.jsdt.internal.codeassist.complete; - -import org.eclipse.wst.jsdt.internal.compiler.ast.SingleNameReference; -import org.eclipse.wst.jsdt.internal.compiler.lookup.BlockScope; -import org.eclipse.wst.jsdt.internal.compiler.lookup.TypeBinding; - -public class CompletionOnKeyword3 extends SingleNameReference implements CompletionOnKeyword{ - private char[][] possibleKeywords; - public CompletionOnKeyword3(char[] token, long pos, char[] possibleKeyword) { - this(token, pos, new char[][]{possibleKeyword}); - } - public CompletionOnKeyword3(char[] token, long pos, char[][] possibleKeywords) { - super(token, pos); - this.token = token; - this.possibleKeywords = possibleKeywords; - } - public boolean canCompleteEmptyToken() { - return false; - } - public char[] getToken() { - return token; - } - public char[][] getPossibleKeywords() { - return possibleKeywords; - } - public StringBuffer printExpression(int indent, StringBuffer output) { - - return output.append("<CompleteOnKeyword:").append(token).append('>'); //$NON-NLS-1$ - } - public TypeBinding resolveType(BlockScope scope) { - throw new CompletionNodeFound(this, scope); - } -} diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionParser.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionParser.java index 7b7f9efa6..4630d1e5c 100644 --- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionParser.java +++ b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/complete/CompletionParser.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2016 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 @@ -24,9 +24,7 @@ import org.eclipse.wst.jsdt.core.ast.IExpression; import org.eclipse.wst.jsdt.core.ast.IFieldReference; import org.eclipse.wst.jsdt.core.ast.ISingleNameReference; import org.eclipse.wst.jsdt.core.ast.IThisReference; -import org.eclipse.wst.jsdt.core.compiler.CharOperation; import org.eclipse.wst.jsdt.internal.codeassist.impl.AssistParser; -import org.eclipse.wst.jsdt.internal.codeassist.impl.Keywords; import org.eclipse.wst.jsdt.internal.compiler.CompilationResult; import org.eclipse.wst.jsdt.internal.compiler.ast.AND_AND_Expression; import org.eclipse.wst.jsdt.internal.compiler.ast.ASTNode; @@ -361,7 +359,6 @@ protected void attachOrphanCompletionNode(){ arrayInitializer.expressions = new Expression[]{expression}; } else if(this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN) { if (expression instanceof SingleNameReference) { - SingleNameReference nameReference = (SingleNameReference) expression; return; } else if (expression instanceof QualifiedNameReference) { } @@ -395,14 +392,9 @@ protected void attachOrphanCompletionNode(){ } if(this.currentElement instanceof RecoveredType || this.currentElement instanceof RecoveredMethod) { - if(this.currentElement instanceof RecoveredType) { - RecoveredType recoveredType = (RecoveredType)this.currentElement; - } if ((!isInsideMethod() && !isInsideFieldInitialization())) { if(this.genericsPtr > -1 && this.genericsLengthPtr > -1 && this.genericsIdentifiersLengthPtr > -1) { - int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER); - int info = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER); int numberOfIdentifiers = this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr]; int genPtr = this.genericsPtr; done : for(int i = 0; i <= this.identifierLengthPtr && numberOfIdentifiers > 0; i++){ @@ -1061,97 +1053,7 @@ private boolean checkClassLiteralAccess() { } return false; } -private boolean checkKeyword() { - if (currentElement instanceof RecoveredUnit) { -// RecoveredUnit unit = (RecoveredUnit) currentElement; - int index = -1; - if ((index = this.indexOfAssistIdentifier()) > -1) { - int ptr = this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + index + 1; - - char[] ident = identifierStack[ptr]; - long pos = identifierPositionStack[ptr]; - - char[][] keywords = new char[Keywords.COUNT][]; - int count = 0; -// if(unit.typeCount == 0 -// && lastModifiers == ClassFileConstants.AccDefault) { -// keywords[count++] = Keywords.IMPORT; -// } -// if(unit.typeCount == 0 -// && unit.importCount == 0 -// && lastModifiers == ClassFileConstants.AccDefault -// && compilationUnit.currentPackage == null) { -// keywords[count++] = Keywords.PACKAGE; -// } -// if((lastModifiers & ClassFileConstants.AccPublic) == 0) { -// boolean hasNoPublicType = true; -// for (int i = 0; i < unit.typeCount; i++) { -// if((unit.types[i].typeDeclaration.modifiers & ClassFileConstants.AccPublic) != 0) { -// hasNoPublicType = false; -// } -// } -// if(hasNoPublicType) { -// keywords[count++] = Keywords.PUBLIC; -// } -// } -// if((lastModifiers & ClassFileConstants.AccAbstract) == 0 -// && (lastModifiers & ClassFileConstants.AccFinal) == 0) { -// keywords[count++] = Keywords.ABSTRACT; -// } -// if((lastModifiers & ClassFileConstants.AccAbstract) == 0 -// && (lastModifiers & ClassFileConstants.AccFinal) == 0) { -// keywords[count++] = Keywords.FINAL; -// } -// -// keywords[count++] = Keywords.CLASS; -// -// if((lastModifiers & ClassFileConstants.AccFinal) == 0) { -// keywords[count++] = Keywords.INTERFACE; -// } - if(count != 0) { - System.arraycopy(keywords, 0, keywords = new char[count][], 0, count); - this.assistNode = new CompletionOnKeyword2(ident, pos, keywords); - this.lastCheckPoint = assistNode.sourceEnd + 1; - this.isOrphanCompletionNode = true; - return true; - } - } - } - return false; -} -private boolean checkInstanceofKeyword() { - if(isInsideMethod()) { - int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER); - int index; - if(kind != K_BLOCK_DELIMITER - && (index = indexOfAssistIdentifier()) > -1 - && expressionPtr > -1 - && expressionLengthStack[expressionPtr] == 1) { - - int ptr = this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + index + 1; - if(identifierStack[ptr].length > 0 && CharOperation.prefixEquals(identifierStack[ptr], Keywords.INSTANCEOF)) { - this.assistNode = new CompletionOnKeyword3( - identifierStack[ptr], - identifierPositionStack[ptr], - Keywords.INSTANCEOF); - this.lastCheckPoint = assistNode.sourceEnd + 1; - this.isOrphanCompletionNode = true; - return true; - } - if(identifierStack[ptr].length > 0 && CharOperation.prefixEquals(identifierStack[ptr], Keywords.TYPEOF)) { - this.assistNode = new CompletionOnKeyword3( - identifierStack[ptr], - identifierPositionStack[ptr], - Keywords.TYPEOF); - this.lastCheckPoint = assistNode.sourceEnd + 1; - this.isOrphanCompletionNode = true; - return true; - } - } - } - return false; -} /** * Checks if the completion is inside a method invocation or a constructor invocation. * Returns whether we found a completion node. @@ -1443,56 +1345,6 @@ private boolean checkRecoveredType() { } return false; } -private void classHeaderExtendsOrImplements(boolean isInterface) { - if (currentElement != null - && currentToken == TokenNameIdentifier - && this.cursorLocation+1 >= scanner.startPosition - && this.cursorLocation < scanner.currentPosition){ - this.pushIdentifier(); - int index = -1; - /* check if current awaiting identifier is the completion identifier */ - if ((index = this.indexOfAssistIdentifier()) > -1) { - int ptr = this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + index + 1; - RecoveredType recoveredType = (RecoveredType)currentElement; - /* filter out cases where scanner is still inside type header */ - if (!recoveredType.foundOpeningBrace) { - TypeDeclaration type = recoveredType.typeDeclaration; - if(!isInterface) { - char[][] keywords = new char[Keywords.COUNT][]; - int count = 0; - - - if(type.superclass == null) { - keywords[count++] = Keywords.EXTENDS; - } - keywords[count++] = Keywords.IMPLEMENTS; - - System.arraycopy(keywords, 0, keywords = new char[count][], 0, count); - - if(count > 0) { - CompletionOnKeyword1 completionOnKeyword = new CompletionOnKeyword1( - identifierStack[ptr], - identifierPositionStack[ptr], - keywords); - completionOnKeyword.canCompleteEmptyToken = true; - type.superclass = completionOnKeyword; - type.superclass.bits |= ASTNode.IsSuperType; - this.assistNode = completionOnKeyword; - this.lastCheckPoint = completionOnKeyword.sourceEnd + 1; - } - } else { - CompletionOnKeyword1 completionOnKeyword = new CompletionOnKeyword1( - identifierStack[ptr], - identifierPositionStack[ptr], - Keywords.EXTENDS); - completionOnKeyword.canCompleteEmptyToken = true; - this.assistNode = completionOnKeyword; - this.lastCheckPoint = completionOnKeyword.sourceEnd + 1; - } - } - } - } -} /* * Check whether about to shift beyond the completion token. * If so, depending on the context, a special node might need to be created @@ -1502,7 +1354,6 @@ private void classHeaderExtendsOrImplements(boolean isInterface) { public void completionIdentifierCheck(){ //if (assistNode != null) return; - if (checkKeyword()) return; if (checkRecoveredType()) return; if (checkRecoveredMethod()) return; @@ -1542,7 +1393,6 @@ public void completionIdentifierCheck(){ if (checkCatchClause()) return; if (checkMemberAccess()) return; if (checkClassLiteralAccess()) return; - if (checkInstanceofKeyword()) return; // if the completion was not on an empty name, it can still be inside an invocation (eg. this.fred("abc"[cursor]) // (NB: Put this check before checkNameCompletion() because the selector of the invocation can be on the identifier stack) @@ -1633,7 +1483,7 @@ protected void consumeEnterVariable() { // recovery if (currentElement != null) { - if(!checkKeyword() && !(currentElement instanceof RecoveredUnit && ((RecoveredUnit)currentElement).statementCount == 0)) { + if(!(currentElement instanceof RecoveredUnit && ((RecoveredUnit)currentElement).statementCount == 0)) { int nameSourceStart = (int)(identifierPositionStack[identifierPtr] >>> 32); intPtr--; // pushOnGenericsIdentifiersLengthStack(identifierLengthStack[identifierLengthPtr]); @@ -1914,26 +1764,19 @@ protected void consumeMethodHeaderRightParen() { && this.cursorLocation < scanner.currentPosition){ this.pushIdentifier(); - int index = -1; /* check if current awaiting identifier is the completion identifier */ - if ((index = this.indexOfAssistIdentifier()) > -1) { - int ptr = this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + index + 1; + if (this.indexOfAssistIdentifier() > -1) { if (currentElement instanceof RecoveredMethod){ RecoveredMethod recoveredMethod = (RecoveredMethod)currentElement; /* filter out cases where scanner is still inside type header */ if (!recoveredMethod.foundOpeningBrace) { - CompletionOnKeyword1 completionOnKeyword = new CompletionOnKeyword1( - identifierStack[ptr], - identifierPositionStack[ptr], - Keywords.THROWS); recoveredMethod.foundOpeningBrace = true; - this.assistNode = completionOnKeyword; - this.lastCheckPoint = completionOnKeyword.sourceEnd + 1; } } } } } + protected void consumeLabel() { super.consumeLabel(); this.pushOnLabelStack(this.identifierStack[this.identifierPtr]); @@ -2521,115 +2364,17 @@ public TypeReference createQualifiedAssistTypeReference(char[][] previousIdentif } public NameReference createSingleAssistNameReference(char[] assistName, long position) { int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER); - if(false){//!isInsideMethod()) { - if (isInsideFieldInitialization()) { - return new CompletionOnSingleNameReference( - assistName, - position, - new char[][]{Keywords.FALSE, Keywords.TRUE}, - false, - isInsideAttributeValue()); - } - return new CompletionOnSingleNameReference(assistName, position, isInsideAttributeValue()); - } else { - boolean canBeExplicitConstructorCall = false; - if(kind == K_BLOCK_DELIMITER - && previousKind == K_BLOCK_DELIMITER - && previousInfo == DO) { - return new CompletionOnKeyword3(assistName, position, Keywords.WHILE); - } else if(kind == K_BLOCK_DELIMITER - && previousKind == K_BLOCK_DELIMITER - && previousInfo == TRY) { - return new CompletionOnKeyword3(assistName, position, new char[][]{Keywords.CATCH, Keywords.FINALLY}); - } else if(kind == K_BLOCK_DELIMITER - && topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == SWITCH) { - return new CompletionOnKeyword3(assistName, position, new char[][]{Keywords.CASE, Keywords.DEFAULT}); - } else { - char[][] keywords = new char[Keywords.COUNT][]; - int count = 0; + boolean canBeExplicitConstructorCall = false; -// if((lastModifiers & ClassFileConstants.AccStatic) == 0) { -// keywords[count++]= Keywords.SUPER; - keywords[count++]= Keywords.THIS; -// } - keywords[count++]= Keywords.NEW; - - if(kind == K_BLOCK_DELIMITER || kind==0) { - if(canBeExplicitConstructor == YES) { - canBeExplicitConstructorCall = true; - } - -// keywords[count++]= Keywords.ASSERT; - keywords[count++]= Keywords.DO; - keywords[count++]= Keywords.FOR; - keywords[count++]= Keywords.IF; - keywords[count++]= Keywords.RETURN; - keywords[count++]= Keywords.SWITCH; -// keywords[count++]= Keywords.SYNCHRONIZED; - keywords[count++]= Keywords.THROW; - keywords[count++]= Keywords.TRY; - keywords[count++]= Keywords.WHILE; - keywords[count++]= Keywords.VAR; - keywords[count++]= Keywords.FUNCTION; - keywords[count++]= Keywords.DELETE; - keywords[count++]= Keywords.TYPEOF; - -// keywords[count++]= Keywords.FINAL; -// keywords[count++]= Keywords.CLASS; - - if(previousKind == K_BLOCK_DELIMITER) { - switch (previousInfo) { - case IF : - keywords[count++]= Keywords.ELSE; - break; - case CATCH : - keywords[count++]= Keywords.CATCH; - keywords[count++]= Keywords.FINALLY; - break; - } - } - if(isInsideLoop()) { - keywords[count++]= Keywords.CONTINUE; - } - if(isInsideBreakable()) { - keywords[count++]= Keywords.BREAK; - } - } else if(kind != K_BETWEEN_CASE_AND_COLON && kind != K_BETWEEN_DEFAULT_AND_COLON) { - keywords[count++]= Keywords.TRUE; - keywords[count++]= Keywords.FALSE; - keywords[count++]= Keywords.NULL; - keywords[count++]= Keywords.UNDEFINED; - keywords[count++]= Keywords.FUNCTION; - - if(kind == K_SWITCH_LABEL) { - if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) != DEFAULT) { - keywords[count++]= Keywords.DEFAULT; - } - keywords[count++]= Keywords.BREAK; - keywords[count++]= Keywords.CASE; - keywords[count++]= Keywords.DO; - keywords[count++]= Keywords.FOR; - keywords[count++]= Keywords.IF; - keywords[count++]= Keywords.RETURN; - keywords[count++]= Keywords.SWITCH; -// keywords[count++]= Keywords.SYNCHRONIZED; - keywords[count++]= Keywords.THROW; - keywords[count++]= Keywords.TRY; - keywords[count++]= Keywords.WHILE; - keywords[count++]= Keywords.VAR; - keywords[count++]= Keywords.FUNCTION; - keywords[count++]= Keywords.DELETE; - keywords[count++]= Keywords.TYPEOF; - if(isInsideLoop()) { - keywords[count++]= Keywords.CONTINUE; - } } - } - System.arraycopy(keywords, 0 , keywords = new char[count][], 0, count); - - return new CompletionOnSingleNameReference(assistName, position, keywords, canBeExplicitConstructorCall, isInsideAttributeValue()); + if (kind == K_BLOCK_DELIMITER || kind == 0) { + if(canBeExplicitConstructor == YES) { + canBeExplicitConstructorCall = true; } } + + return new CompletionOnSingleNameReference(assistName, position, null, canBeExplicitConstructorCall, isInsideAttributeValue()); } + public TypeReference createSingleAssistTypeReference(char[] assistName, long position) { switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) { case K_NEXT_TYPEREF_IS_EXCEPTION : @@ -2656,12 +2401,12 @@ protected StringLiteral createStringLiteral(char[] token, int start, int end, in int pos = contentStart; if(source[pos] == '\"') { contentStart = pos + 1; - } else if(source[pos] == '\\' && source[pos+1] == 'u') { + } else if (source[pos] == '\\' && source[pos+1] == 'u') { pos += 2; while (source[pos] == 'u') { pos++; } - if(source[pos] == 0 && source[pos + 1] == 0 && source[pos + 2] == 2 && source[pos + 3] == 2) { + if (source[pos] == 0 && source[pos + 1] == 0 && source[pos + 2] == 2 && source[pos + 3] == 2) { contentStart = pos + 4; } } @@ -2669,23 +2414,23 @@ protected StringLiteral createStringLiteral(char[] token, int start, int end, in pos = contentEnd; if(source[pos] == '\"') { contentEnd = pos - 1; - } else if(source.length > 5 && source[pos-4] == 'u') { - if(source[pos - 3] == 0 && source[pos - 2] == 0 && source[pos - 1] == 2 && source[pos] == 2) { + } else if (source.length > 5 && source[pos-4] == 'u') { + if (source[pos - 3] == 0 && source[pos - 2] == 0 && source[pos - 1] == 2 && source[pos] == 2) { pos -= 5; while (pos > -1 && source[pos] == 'u') { pos--; } - if(pos > -1 && source[pos] == '\\') { + if (pos > -1 && source[pos] == '\\') { contentEnd = pos - 1; } } } - if(contentEnd < start) { + if (contentEnd < start) { contentEnd = end; } - if(this.cursorLocation != end || end == contentEnd) { + if (this.cursorLocation != end || end == contentEnd) { CompletionOnStringLiteral stringLiteral = new CompletionOnStringLiteral( token, start, @@ -2714,7 +2459,6 @@ protected TypeReference copyDims(TypeReference typeRef, int dim) { return result; } public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult, int cursorLoc) { - this.cursorLocation = cursorLoc; CompletionScanner completionScanner = (CompletionScanner)this.scanner; completionScanner.completionIdentifier = null; @@ -3301,8 +3045,7 @@ protected JavadocParser createJavadocParser() { long position = (((long)snr.sourceStart)<<32)+snr.sourceEnd; expression.member= new CompletionOnSingleTypeReference(snr.token,position); ((CompletionOnSingleTypeReference)expression.member).isConstructorType = true; - } - else if(member instanceof CompletionOnMemberAccess) { + } else if(member instanceof CompletionOnMemberAccess) { CompletionOnMemberAccess memberAccess = (CompletionOnMemberAccess) member; //iterate over the receivers to build the token and find the start of the expression @@ -3313,15 +3056,14 @@ protected JavadocParser createJavadocParser() { start = receiver.sourceStart(); if(receiver instanceof IFieldReference) { IFieldReference ref = (IFieldReference)receiver; - token = new String(ref.getToken()) + "." + token; + token = new String(ref.getToken()) + "." + token; //$NON-NLS-1$ receiver = ref.getReceiver(); } else if(receiver instanceof ISingleNameReference) { ISingleNameReference ref = (ISingleNameReference)receiver; - token = new String(ref.getToken()) + "." + token; + token = new String(ref.getToken()) + "." + token; //$NON-NLS-1$ receiver = null; } else if(receiver instanceof IThisReference) { - IThisReference ref = (IThisReference)receiver; - token = "this." + token; + token = "this." + token; //$NON-NLS-1$ receiver = null; } } diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/impl/Keywords.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/impl/Keywords.java index 055312e56..5ead5cdb3 100644 --- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/impl/Keywords.java +++ b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/codeassist/impl/Keywords.java @@ -11,9 +11,8 @@ package org.eclipse.wst.jsdt.internal.codeassist.impl; public interface Keywords { - int COUNT = 48; + int COUNT = 38; - char[] ABSTRACT = "abstract".toCharArray(); //$NON-NLS-1$ char[] ASSERT = "assert".toCharArray(); //$NON-NLS-1$ char[] BREAK = "break".toCharArray(); //$NON-NLS-1$ char[] CASE = "case".toCharArray(); //$NON-NLS-1$ @@ -28,28 +27,19 @@ public interface Keywords { char[] FINALLY = "finally".toCharArray(); //$NON-NLS-1$ char[] FOR = "for".toCharArray(); //$NON-NLS-1$ char[] IF = "if".toCharArray(); //$NON-NLS-1$ - char[] IMPLEMENTS = "implements".toCharArray(); //$NON-NLS-1$ char[] IMPORT = "import".toCharArray(); //$NON-NLS-1$ char[] INSTANCEOF = "instanceof".toCharArray(); //$NON-NLS-1$ - char[] INTERFACE = "interface".toCharArray(); //$NON-NLS-1$ char[] NATIVE = "native".toCharArray(); //$NON-NLS-1$ char[] NEW = "new".toCharArray(); //$NON-NLS-1$ - char[] PACKAGE = "package".toCharArray(); //$NON-NLS-1$ - char[] PRIVATE = "private".toCharArray(); //$NON-NLS-1$ - char[] PROTECTED = "protected".toCharArray(); //$NON-NLS-1$ - char[] PUBLIC = "public".toCharArray(); //$NON-NLS-1$ char[] RETURN = "return".toCharArray(); //$NON-NLS-1$ char[] STATIC = "static".toCharArray(); //$NON-NLS-1$ char[] STRICTFP = "strictfp".toCharArray(); //$NON-NLS-1$ char[] SUPER = "super".toCharArray(); //$NON-NLS-1$ char[] SWITCH = "switch".toCharArray(); //$NON-NLS-1$ - char[] SYNCHRONIZED = "synchronized".toCharArray(); //$NON-NLS-1$ char[] THIS = "this".toCharArray(); //$NON-NLS-1$ char[] THROW = "throw".toCharArray(); //$NON-NLS-1$ char[] THROWS = "throws".toCharArray(); //$NON-NLS-1$ - char[] TRANSIENT = "transient".toCharArray(); //$NON-NLS-1$ char[] TRY = "try".toCharArray(); //$NON-NLS-1$ - char[] VOLATILE = "volatile".toCharArray(); //$NON-NLS-1$ char[] WHILE = "while".toCharArray(); //$NON-NLS-1$ char[] TRUE = "true".toCharArray(); //$NON-NLS-1$ char[] FALSE = "false".toCharArray(); //$NON-NLS-1$ diff --git a/bundles/org.eclipse.wst.jsdt.ui/.classpath b/bundles/org.eclipse.wst.jsdt.ui/.classpath index 01836c484..cdd968e4f 100644 --- a/bundles/org.eclipse.wst.jsdt.ui/.classpath +++ b/bundles/org.eclipse.wst.jsdt.ui/.classpath @@ -4,4 +4,4 @@ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="output" path="bin"/> -</classpath> +</classpath>
\ No newline at end of file diff --git a/bundles/org.eclipse.wst.jsdt.ui/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.wst.jsdt.ui/.settings/org.eclipse.jdt.core.prefs index b36056118..a31920a3f 100644 --- a/bundles/org.eclipse.wst.jsdt.ui/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.eclipse.wst.jsdt.ui/.settings/org.eclipse.jdt.core.prefs @@ -20,7 +20,7 @@ org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -108,7 +108,7 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disa org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
@@ -192,7 +192,6 @@ org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
diff --git a/bundles/org.eclipse.wst.jsdt.ui/plugin.xml b/bundles/org.eclipse.wst.jsdt.ui/plugin.xml index 9e0121034..796bb581c 100644 --- a/bundles/org.eclipse.wst.jsdt.ui/plugin.xml +++ b/bundles/org.eclipse.wst.jsdt.ui/plugin.xml @@ -264,7 +264,17 @@ <partition type="__java_javadoc"/> </javaCompletionProposalComputer> </extension> - + <!-- keyword proposals --> + <extension + point="org.eclipse.wst.jsdt.ui.javaCompletionProposalComputer" + id="KeywordCompletionProposalComputer"> + <javaCompletionProposalComputer + class="org.eclipse.wst.jsdt.internal.ui.text.java.KeywordCompletionProposalComputer" + categoryId="org.eclipse.wst.jsdt.ui.defaultProposalCategory"> + <partition type="__dftl_partition_content_type"/> + </javaCompletionProposalComputer> + </extension> + <!-- the parameterized content assist action and keybindings for our contributed computers --> <extension point="org.eclipse.ui.commands"> diff --git a/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/java/KeywordCompletionProposalComputer.java b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/java/KeywordCompletionProposalComputer.java new file mode 100644 index 000000000..4274bdee4 --- /dev/null +++ b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/java/KeywordCompletionProposalComputer.java @@ -0,0 +1,67 @@ +/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * 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:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.wst.jsdt.internal.ui.text.java;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
+import org.eclipse.wst.jsdt.internal.corext.template.java.CompilationUnitContextType;
+import org.eclipse.wst.jsdt.internal.corext.template.java.JavaContextType;
+import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin;
+import org.eclipse.wst.jsdt.internal.ui.text.keyword.contentassist.KeywordEngine;
+import org.eclipse.wst.jsdt.internal.ui.text.keyword.contentassist.KeywordProposal;
+import org.eclipse.wst.jsdt.ui.text.java.ContentAssistInvocationContext;
+import org.eclipse.wst.jsdt.ui.text.java.IJavaCompletionProposalComputer;
+import org.eclipse.wst.jsdt.ui.text.java.JavaContentAssistInvocationContext;
+
+public class KeywordCompletionProposalComputer implements IJavaCompletionProposalComputer {
+
+ private KeywordEngine engine;
+
+ public KeywordCompletionProposalComputer() {
+ // TODO: Is TemplateContextType the type we want?
+ CompilationUnitContextType contextType = (CompilationUnitContextType) JavaScriptPlugin.getDefault().getTemplateContextRegistry().getContextType(JavaContextType.NAME);
+ engine = new KeywordEngine(contextType);
+ }
+
+ public void sessionStarted() {
+ // do nothing
+ }
+
+ public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) {
+ JavaContentAssistInvocationContext javaContext = (JavaContentAssistInvocationContext) context;
+ IJavaScriptUnit unit = javaContext.getCompilationUnit();
+ engine.complete(javaContext.getViewer(), javaContext.getInvocationOffset(), unit);
+
+ KeywordProposal[] keywordProposals = engine.getResults();
+ List<KeywordProposal> result = new ArrayList<KeywordProposal>(Arrays.asList(keywordProposals));
+
+ return result;
+ }
+
+ public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) {
+ return Collections.emptyList();
+ }
+
+ public String getErrorMessage() {
+ return null;
+ }
+
+ public void sessionEnded() {
+ engine.reset();
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/java/TemplateCompletionProposalComputer.java b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/java/TemplateCompletionProposalComputer.java index fc9f3eff1..ab7f68910 100644 --- a/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/java/TemplateCompletionProposalComputer.java +++ b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/java/TemplateCompletionProposalComputer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2016 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 @@ -7,15 +7,14 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Red Hat, Inc. - refactoring *******************************************************************************/ package org.eclipse.wst.jsdt.internal.ui.text.java; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashSet; import java.util.List; -import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.text.BadLocationException; @@ -25,6 +24,7 @@ import org.eclipse.wst.jsdt.core.IJavaScriptUnit; import org.eclipse.wst.jsdt.internal.corext.template.java.JavaContextType; import org.eclipse.wst.jsdt.internal.corext.template.java.JavaDocContextType; import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin; +import org.eclipse.wst.jsdt.internal.ui.text.keyword.contentassist.KeywordUtilities; import org.eclipse.wst.jsdt.internal.ui.text.template.contentassist.TemplateEngine; import org.eclipse.wst.jsdt.internal.ui.text.template.contentassist.TemplateProposal; import org.eclipse.wst.jsdt.ui.text.IJavaScriptPartitions; @@ -132,57 +132,9 @@ public final class TemplateCompletionProposalComputer implements IJavaCompletion public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) { return Collections.EMPTY_LIST; } - - private static final Set KEYWORDS; - static { - Set keywords= new HashSet(42); - keywords.add("abstract"); //$NON-NLS-1$ - keywords.add("assert"); //$NON-NLS-1$ - keywords.add("break"); //$NON-NLS-1$ - keywords.add("case"); //$NON-NLS-1$ - keywords.add("catch"); //$NON-NLS-1$ - keywords.add("class"); //$NON-NLS-1$ - keywords.add("continue"); //$NON-NLS-1$ - keywords.add("default"); //$NON-NLS-1$ - keywords.add("do"); //$NON-NLS-1$ - keywords.add("else"); //$NON-NLS-1$ - keywords.add("elseif"); //$NON-NLS-1$ - keywords.add("extends"); //$NON-NLS-1$ - keywords.add("final"); //$NON-NLS-1$ - keywords.add("finally"); //$NON-NLS-1$ - keywords.add("for"); //$NON-NLS-1$ - keywords.add("if"); //$NON-NLS-1$ - keywords.add("implements"); //$NON-NLS-1$ - keywords.add("import"); //$NON-NLS-1$ - keywords.add("instanceof"); //$NON-NLS-1$ - keywords.add("interface"); //$NON-NLS-1$ - keywords.add("native"); //$NON-NLS-1$ - keywords.add("new"); //$NON-NLS-1$ - keywords.add("package"); //$NON-NLS-1$ - keywords.add("private"); //$NON-NLS-1$ - keywords.add("protected"); //$NON-NLS-1$ - keywords.add("public"); //$NON-NLS-1$ - keywords.add("return"); //$NON-NLS-1$ - keywords.add("static"); //$NON-NLS-1$ - keywords.add("strictfp"); //$NON-NLS-1$ - keywords.add("super"); //$NON-NLS-1$ - keywords.add("switch"); //$NON-NLS-1$ - keywords.add("synchronized"); //$NON-NLS-1$ - keywords.add("this"); //$NON-NLS-1$ - keywords.add("throw"); //$NON-NLS-1$ - keywords.add("throws"); //$NON-NLS-1$ - keywords.add("transient"); //$NON-NLS-1$ - keywords.add("try"); //$NON-NLS-1$ - keywords.add("volatile"); //$NON-NLS-1$ - keywords.add("while"); //$NON-NLS-1$ - keywords.add("true"); //$NON-NLS-1$ - keywords.add("false"); //$NON-NLS-1$ - keywords.add("null"); //$NON-NLS-1$ - KEYWORDS= Collections.unmodifiableSet(keywords); - } private boolean isKeyword(String name) { - return KEYWORDS.contains(name); + return KeywordUtilities.getInstance().isKeyword(name); } /* diff --git a/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/keyword/contentassist/KeywordEngine.java b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/keyword/contentassist/KeywordEngine.java new file mode 100644 index 000000000..20fa1b67e --- /dev/null +++ b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/keyword/contentassist/KeywordEngine.java @@ -0,0 +1,70 @@ +/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * 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:
+ * Red Hat, Inc. - initial API and implementation
+ ********************************************************************************/
+
+package org.eclipse.wst.jsdt.internal.ui.text.keyword.contentassist;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
+import org.eclipse.wst.jsdt.internal.corext.template.java.CompilationUnitContext;
+import org.eclipse.wst.jsdt.internal.corext.template.java.CompilationUnitContextType;
+
+public class KeywordEngine {
+
+ private CompilationUnitContextType fContextType;
+ private ArrayList<KeywordProposal> fProposals = new ArrayList<KeywordProposal>();
+
+ public KeywordEngine(CompilationUnitContextType contextType) {
+ Assert.isNotNull(contextType);
+ fContextType = contextType;
+ }
+
+ public void complete(ITextViewer viewer, int completionPosition, IJavaScriptUnit compilationUnit) {
+ reset();
+
+ IDocument document = viewer.getDocument();
+ Point selection = viewer.getSelectedRange();
+ Position position = new Position(completionPosition, selection.y);
+
+ CompilationUnitContext context = fContextType.createContext(document, position, compilationUnit);
+ int start = context.getStart();
+ int end = context.getEnd();
+ IRegion region = new Region(start, end - start);
+
+ KeywordUtilities keywordUtil = KeywordUtilities.getInstance();
+ List<String> matchingKeywords = keywordUtil.getMatchingKeywords(context.getKey());
+
+ for (String keywordName : matchingKeywords) {
+ KeywordProposal keywordProposal = new KeywordProposal(keywordName, region);
+ fProposals.add(keywordProposal);
+ }
+ }
+
+ public void reset() {
+ fProposals.clear();
+ }
+
+ /**
+ * Returns matching keywords.
+ */
+ public KeywordProposal[] getResults() {
+ return fProposals.toArray(new KeywordProposal[fProposals.size()]);
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/keyword/contentassist/KeywordProposal.java b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/keyword/contentassist/KeywordProposal.java new file mode 100644 index 000000000..ae7cb4b22 --- /dev/null +++ b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/keyword/contentassist/KeywordProposal.java @@ -0,0 +1,175 @@ +/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * 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:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.wst.jsdt.internal.ui.text.keyword.contentassist;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension3;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension4;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.wst.jsdt.ui.text.java.IJavaCompletionProposal;
+
+public class KeywordProposal implements ICompletionProposal, IJavaCompletionProposal, ICompletionProposalExtension2, ICompletionProposalExtension3, ICompletionProposalExtension4 {
+
+ private final String keywordName;
+ private IRegion fSelectedRegion;
+ private final IRegion fRegion;
+
+ public KeywordProposal(String keywordName, IRegion fRegion) {
+ this.keywordName = keywordName;
+ this.fRegion = fRegion;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @deprecated This method is no longer called by the framework and clients should overwrite
+ * {@link #apply(ITextViewer, char, int, int)} instead
+ */
+ public final void apply(IDocument document) {
+ // not called anymore
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getSelection(org.eclipse.jface.text.IDocument)
+ */
+ public Point getSelection(IDocument document) {
+ return new Point(fSelectedRegion.getOffset(), fSelectedRegion.getLength());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo()
+ */
+ public String getAdditionalProposalInfo() {
+ return null;
+ }
+
+ public String getDisplayString() {
+ return this.keywordName;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getImage()
+ */
+ public Image getImage() {
+ // TODO: Which image should we use?
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getContextInformation()
+ */
+ public IContextInformation getContextInformation() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension4#isAutoInsertable()
+ */
+ public boolean isAutoInsertable() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension3#getInformationControlCreator()
+ */
+ public IInformationControlCreator getInformationControlCreator() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension3#getPrefixCompletionText(org.eclipse.jface.text.IDocument, int)
+ */
+ public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) {
+ return this.keywordName;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension3#getPrefixCompletionStart(org.eclipse.jface.text.IDocument, int)
+ */
+ public int getPrefixCompletionStart(IDocument document, int completionOffset) {
+ return fRegion.getOffset();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#apply(org.eclipse.jface.text.ITextViewer, char, int, int)
+ */
+ public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
+ IDocument document = viewer.getDocument();
+
+ try {
+ document.replace(fRegion.getOffset(), offset - fRegion.getOffset(), this.keywordName);
+ }
+ catch (BadLocationException e) {
+ openErrorDialog(viewer.getTextWidget().getShell(), e);
+ this.fSelectedRegion = fRegion;
+ }
+
+ // Place the cursor at the end of the applied proposal.
+ this.fSelectedRegion = new Region(fRegion.getOffset() + this.keywordName.length(), 0);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#selected(org.eclipse.jface.text.ITextViewer, boolean)
+ */
+ public void selected(ITextViewer viewer, boolean smartToggle) {
+ // do nothing
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#unselected(org.eclipse.jface.text.ITextViewer)
+ */
+ public void unselected(ITextViewer viewer) {
+ // do nothing
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#validate(org.eclipse.jface.text.IDocument, int, org.eclipse.jface.text.DocumentEvent)
+ */
+ public boolean validate(IDocument document, int offset, DocumentEvent event) {
+ try {
+ int replaceOffset = fRegion.getOffset();
+ if (offset >= replaceOffset) {
+ String content = document.get(replaceOffset, offset - replaceOffset);
+ return this.keywordName.toLowerCase().startsWith(content.toLowerCase());
+ }
+ } catch (BadLocationException e) {
+ // concurrent modification - ignore
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.wst.jsdt.ui.text.java.IJavaCompletionProposal#getRelevance()
+ */
+ public int getRelevance() {
+ // TODO: Compute the relevance for the given keyword. Note that TemplateProposals are meant to have
+ // a higher relevance than keywords for a reason I'm unaware of.
+ return 0;
+ }
+
+ private void openErrorDialog(Shell shell, Exception e) {
+ MessageDialog.openError(shell, "Keyword Proposal Error", e.getMessage()); //$NON-NLS-1$
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/keyword/contentassist/KeywordUtilities.java b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/keyword/contentassist/KeywordUtilities.java new file mode 100644 index 000000000..0ac475039 --- /dev/null +++ b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/keyword/contentassist/KeywordUtilities.java @@ -0,0 +1,92 @@ +/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * 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:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.internal.ui.text.keyword.contentassist;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class KeywordUtilities {
+
+ private static KeywordUtilities instance;
+ private final Set<String> keywords;
+
+ private KeywordUtilities() {
+ keywords = new HashSet<String>(27);
+ keywords.add("break"); //$NON-NLS-1$
+ keywords.add("case"); //$NON-NLS-1$
+ keywords.add("catch"); //$NON-NLS-1$
+ keywords.add("class"); //$NON-NLS-1$
+ keywords.add("const"); //$NON-NLS-1$
+ keywords.add("continue"); //$NON-NLS-1$
+ keywords.add("debugger"); //$NON-NLS-1$
+ keywords.add("default"); //$NON-NLS-1$
+ keywords.add("delete"); //$NON-NLS-1$
+ keywords.add("do"); //$NON-NLS-1$
+ keywords.add("else"); //$NON-NLS-1$
+ keywords.add("elseif"); //$NON-NLS-1$
+ keywords.add("export"); //$NON-NLS-1$
+ keywords.add("extends"); //$NON-NLS-1$
+ keywords.add("finally"); //$NON-NLS-1$
+ keywords.add("for"); //$NON-NLS-1$
+ keywords.add("function"); //$NON-NLS-1$
+ keywords.add("if"); //$NON-NLS-1$
+ keywords.add("import"); //$NON-NLS-1$
+ keywords.add("in"); //$NON-NLS-1$
+ keywords.add("instanceof"); //$NON-NLS-1$
+ keywords.add("let"); //$NON-NLS-1$
+ keywords.add("new"); //$NON-NLS-1$
+ keywords.add("return"); //$NON-NLS-1$
+ keywords.add("super"); //$NON-NLS-1$
+ keywords.add("static"); //$NON-NLS-1$
+ keywords.add("switch"); //$NON-NLS-1$
+ keywords.add("this"); //$NON-NLS-1$
+ keywords.add("throw"); //$NON-NLS-1$
+ keywords.add("try"); //$NON-NLS-1$
+ keywords.add("typeof"); //$NON-NLS-1$
+ keywords.add("var"); //$NON-NLS-1$
+ keywords.add("void"); //$NON-NLS-1$
+ keywords.add("while"); //$NON-NLS-1$
+ keywords.add("with"); //$NON-NLS-1$
+ keywords.add("yield"); //$NON-NLS-1$
+ }
+
+ public static KeywordUtilities getInstance() {
+ if (instance == null) {
+ instance = new KeywordUtilities();
+ }
+ return instance;
+ }
+
+ /**
+ * Returns whether string should be recognized as a keyword, regardless of case.
+ * @param string The string being tested.
+ * @return Whether string is a keyword.
+ */
+ public boolean isKeyword(String string) {
+ return keywords.contains(string.toLowerCase());
+ }
+
+ /**
+ * Returns the keywords whose prefix is string, regardless of case.
+ * @param string The string being tested.
+ * @return The keywords whose prefix is string.
+ */
+ public List<String> getMatchingKeywords(String string) {
+ return keywords.stream().filter(k -> k.startsWith(string.toLowerCase())).collect(Collectors.toList());
+ }
+
+ public Set<String> getKeywords() {
+ return keywords;
+ }
+
+}
diff --git a/tests/org.eclipse.wst.jsdt.ui.tests/src/org/eclipse/wst/jsdt/ui/tests/contentassist/KeywordTests.java b/tests/org.eclipse.wst.jsdt.ui.tests/src/org/eclipse/wst/jsdt/ui/tests/contentassist/KeywordTests.java new file mode 100644 index 000000000..7d2d9df2d --- /dev/null +++ b/tests/org.eclipse.wst.jsdt.ui.tests/src/org/eclipse/wst/jsdt/ui/tests/contentassist/KeywordTests.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + + * 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: + * Red Hat, Inc. - initial API and implementation + * + *******************************************************************************/ +package org.eclipse.wst.jsdt.ui.tests.contentassist; + +import junit.extensions.TestSetup; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +import org.eclipse.wst.jsdt.ui.tests.utils.TestProjectSetup; + +public class KeywordTests extends TestCase { + private static final Set<String> keywords = new HashSet<String>(27); + + /** + * <p> + * This tests name + * </p> + */ + private static final String TEST_NAME = "Test Keywords JavaScript Content Assist"; + + /** + * <p> + * Test project setup for this test. + * </p> + */ + private static TestProjectSetup fTestProjectSetup; + + /** + * <p> + * Default constructor + * <p> + * <p> + * Use {@link #suite()} + * </p> + * + * @see #suite() + */ + public KeywordTests() { + super(TEST_NAME); + } + + /** + * <p> + * Constructor that takes a test name. + * </p> + * <p> + * Use {@link #suite()} + * </p> + * + * @param name + * The name this test run should have. + * + * @see #suite() + */ + public KeywordTests(String name) { + super(name); + } + + /** + * <p> + * Use this method to add these tests to a larger test suite so set up and tear down can be + * performed + * </p> + * + * @return a {@link TestSetup} that will run all of the tests in this class + * with set up and tear down. + */ + + public static Test suite() { + TestSuite ts = new TestSuite(GlobalFunctionTests.class, TEST_NAME); + + fTestProjectSetup = new TestProjectSetup(ts, "ContentAssist", "root", false); + + keywords.add("break"); //$NON-NLS-1$ + keywords.add("case"); //$NON-NLS-1$ + keywords.add("catch"); //$NON-NLS-1$ + keywords.add("class"); //$NON-NLS-1$ + keywords.add("const"); //$NON-NLS-1$ + keywords.add("continue"); //$NON-NLS-1$ + keywords.add("debugger"); //$NON-NLS-1$ + keywords.add("default"); //$NON-NLS-1$ + keywords.add("delete"); //$NON-NLS-1$ + keywords.add("do"); //$NON-NLS-1$ + keywords.add("else"); //$NON-NLS-1$ + keywords.add("elseif"); //$NON-NLS-1$ + keywords.add("export"); //$NON-NLS-1$ + keywords.add("extends"); //$NON-NLS-1$ + keywords.add("finally"); //$NON-NLS-1$ + keywords.add("for"); //$NON-NLS-1$ + keywords.add("function"); //$NON-NLS-1$ + keywords.add("if"); //$NON-NLS-1$ + keywords.add("import"); //$NON-NLS-1$ + keywords.add("in"); //$NON-NLS-1$ + keywords.add("instanceof"); //$NON-NLS-1$ + keywords.add("let"); //$NON-NLS-1$ + keywords.add("new"); //$NON-NLS-1$ + keywords.add("return"); //$NON-NLS-1$ + keywords.add("super"); //$NON-NLS-1$ + keywords.add("static"); //$NON-NLS-1$ + keywords.add("switch"); //$NON-NLS-1$ + keywords.add("this"); //$NON-NLS-1$ + keywords.add("throw"); //$NON-NLS-1$ + keywords.add("try"); //$NON-NLS-1$ + keywords.add("typeof"); //$NON-NLS-1$ + keywords.add("var"); //$NON-NLS-1$ + keywords.add("void"); //$NON-NLS-1$ + keywords.add("while"); //$NON-NLS-1$ + keywords.add("with"); //$NON-NLS-1$ + keywords.add("yield"); //$NON-NLS-1$ + + return fTestProjectSetup; + } + + public void testSingleLetterKeywordCompletionLowercase() throws Exception { + for (int i = 0; i < 26; i++) { + char ch = (char) ('a' + i); + String[][] expectedKeywords = { (String[]) keywords.stream().filter(k -> k.charAt(0) == ch).collect(Collectors.toList()).toArray() }; + ContentAssistTestUtilities.runProposalTest(fTestProjectSetup, "TestKeywordsSingleLetterLowerCase.js", i, 1, expectedKeywords); + } + + } + + public void testSingleLetterKeywordCompletionUppercase() throws Exception { + for (int i = 0; i < 26; i++) { + char ch = (char) ('a' + i); + String[][] expectedKeywords = { (String[]) keywords.stream().filter(k -> k.charAt(0) == ch).collect(Collectors.toList()).toArray() }; + ContentAssistTestUtilities.runProposalTest(fTestProjectSetup, "TestKeywordsSingleLetterUpperCase.js", i, 1, expectedKeywords); + } + + } + +} diff --git a/tests/org.eclipse.wst.jsdt.ui.tests/testresources/ContentAssist/root/TestKeywordsSingleLetterLowerCase.js b/tests/org.eclipse.wst.jsdt.ui.tests/testresources/ContentAssist/root/TestKeywordsSingleLetterLowerCase.js new file mode 100644 index 000000000..0edb85647 --- /dev/null +++ b/tests/org.eclipse.wst.jsdt.ui.tests/testresources/ContentAssist/root/TestKeywordsSingleLetterLowerCase.js @@ -0,0 +1,26 @@ +a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t +u +v +w +x +y +z diff --git a/tests/org.eclipse.wst.jsdt.ui.tests/testresources/ContentAssist/root/TestKeywordsSingleLetterUpperCase.js b/tests/org.eclipse.wst.jsdt.ui.tests/testresources/ContentAssist/root/TestKeywordsSingleLetterUpperCase.js new file mode 100644 index 000000000..a6f1d23fc --- /dev/null +++ b/tests/org.eclipse.wst.jsdt.ui.tests/testresources/ContentAssist/root/TestKeywordsSingleLetterUpperCase.js @@ -0,0 +1,26 @@ +A +B +C +D +E +F +G +H +I +J +K +L +M +N +O +P +Q +R +S +T +U +V +W +X +Y +Z |