mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
Bug 326418 - Ctrl+Click navigation is broken.
This commit is contained in:
parent
3c2fe616f7
commit
c69832ea82
2 changed files with 190 additions and 83 deletions
|
@ -48,7 +48,8 @@ import org.eclipse.cdt.internal.ui.editor.CElementHyperlinkDetector;
|
||||||
* @author Mike Kucera
|
* @author Mike Kucera
|
||||||
*/
|
*/
|
||||||
public class HyperlinkTest extends TestCase {
|
public class HyperlinkTest extends TestCase {
|
||||||
private static final String CPP_FILE_NAME = "hyperlink_test_cpp.cpp";
|
private static final String CPP_FILE_NAME_1 = "hyperlink_test_cpp.cpp";
|
||||||
|
private static final String CPP_FILE_NAME_2 = "hyperlink_test_cpp_without_ast.cpp";
|
||||||
private static final String CPP_CODE =
|
private static final String CPP_CODE =
|
||||||
"#include <stdio.h> \n" +
|
"#include <stdio.h> \n" +
|
||||||
"#define SOMEMACRO macro_token1 macro_token2 \n" +
|
"#define SOMEMACRO macro_token1 macro_token2 \n" +
|
||||||
|
@ -91,6 +92,10 @@ public class HyperlinkTest extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpEditor(String fileName, String code) throws Exception {
|
private void setUpEditor(String fileName, String code) throws Exception {
|
||||||
|
setUpEditor(fileName, code, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpEditor(String fileName, String code, boolean buildAST) throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
project= CProjectHelper.createCCProject(super.getName(), "unused", IPDOMManager.ID_NO_INDEXER);
|
project= CProjectHelper.createCCProject(super.getName(), "unused", IPDOMManager.ID_NO_INDEXER);
|
||||||
ICContainer cContainer= CProjectHelper.addCContainer(project, "src");
|
ICContainer cContainer= CProjectHelper.addCContainer(project, "src");
|
||||||
|
@ -100,15 +105,17 @@ public class HyperlinkTest extends TestCase {
|
||||||
assertTrue(file.exists());
|
assertTrue(file.exists());
|
||||||
editor = (CEditor) EditorTestHelper.openInEditor(file, true);
|
editor = (CEditor) EditorTestHelper.openInEditor(file, true);
|
||||||
EditorTestHelper.joinReconciler(EditorTestHelper.getSourceViewer(editor), 10, 1000, 10);
|
EditorTestHelper.joinReconciler(EditorTestHelper.getSourceViewer(editor), 10, 1000, 10);
|
||||||
// Since CElementHyperlinkDetector doesn't wait for an AST to be created,
|
if (buildAST) {
|
||||||
// we trigger AST creation ahead of time.
|
// Since CElementHyperlinkDetector doesn't wait for an AST to be created,
|
||||||
IWorkingCopyManager manager = CUIPlugin.getDefault().getWorkingCopyManager();
|
// we trigger AST creation ahead of time.
|
||||||
IWorkingCopy workingCopy = manager.getWorkingCopy(editor.getEditorInput());
|
IWorkingCopyManager manager = CUIPlugin.getDefault().getWorkingCopyManager();
|
||||||
IStatus status= ASTProvider.getASTProvider().runOnAST(workingCopy, ASTProvider.WAIT_IF_OPEN, null, new ASTRunnable() {
|
IWorkingCopy workingCopy = manager.getWorkingCopy(editor.getEditorInput());
|
||||||
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) {
|
IStatus status= ASTProvider.getASTProvider().runOnAST(workingCopy, ASTProvider.WAIT_IF_OPEN, null, new ASTRunnable() {
|
||||||
return Status.OK_STATUS;
|
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) {
|
||||||
}
|
return Status.OK_STATUS;
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -140,7 +147,7 @@ public class HyperlinkTest extends TestCase {
|
||||||
|
|
||||||
public void testHyperlinksCpp() throws Exception {
|
public void testHyperlinksCpp() throws Exception {
|
||||||
// entire include highlighted
|
// entire include highlighted
|
||||||
setUpEditor(CPP_FILE_NAME, CPP_CODE);
|
setUpEditor(CPP_FILE_NAME_1, CPP_CODE, true);
|
||||||
|
|
||||||
assertHyperlink(CPP_CODE.indexOf("#include") + 2, 0, "#include <stdio.h>".length());
|
assertHyperlink(CPP_CODE.indexOf("#include") + 2, 0, "#include <stdio.h>".length());
|
||||||
assertHyperlink(CPP_CODE.indexOf("<stdio.h>") + 2, 0, "#include <stdio.h>".length());
|
assertHyperlink(CPP_CODE.indexOf("<stdio.h>") + 2, 0, "#include <stdio.h>".length());
|
||||||
|
@ -192,8 +199,63 @@ public class HyperlinkTest extends TestCase {
|
||||||
assertHyperlink(CPP_CODE.indexOf("+ p"), CPP_CODE.indexOf("+ p"), 1);
|
assertHyperlink(CPP_CODE.indexOf("+ p"), CPP_CODE.indexOf("+ p"), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testHyperlinksCppWithoutAST() throws Exception {
|
||||||
|
// entire include highlighted
|
||||||
|
setUpEditor(CPP_FILE_NAME_2, CPP_CODE, false);
|
||||||
|
|
||||||
|
assertHyperlink(CPP_CODE.indexOf("#include") + 2, 0, "#include <stdio.h>".length());
|
||||||
|
assertHyperlink(CPP_CODE.indexOf("<stdio.h>") + 2, 0, "#include <stdio.h>".length());
|
||||||
|
assertHyperlink(CPP_CODE.indexOf("<stdio.h>") + "<stdio.h".length(), 0, "#include <stdio.h>".length());
|
||||||
|
|
||||||
|
// hovering over the whitespace inside an include still results in a hyperlink
|
||||||
|
assertHyperlink(CPP_CODE.indexOf("<stdio.h>") - 1, 0, "#include <stdio.h>".length());
|
||||||
|
|
||||||
|
// no hyperlinks in macro bodies
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("#define") + 1);
|
||||||
|
assertHyperlink(CPP_CODE.indexOf("SOMEMACRO"), CPP_CODE.indexOf("SOMEMACRO"), "SOMEMACRO".length());
|
||||||
|
// see bug 259015
|
||||||
|
// assertNotHyperlink(CPP_CODE.indexOf("macro_token1") + 1);
|
||||||
|
// assertNotHyperlink(CPP_CODE.indexOf("macro_token2") + 1);
|
||||||
|
|
||||||
|
// no hyperlinks for comments
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("//") + 1);
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("COMMENT") + 1);
|
||||||
|
|
||||||
|
// no hyperlinks for keywords
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("class") + 1);
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("public") + 1);
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("private") + 1);
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("int x") + 1);
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("char") + 1);
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("void") + 1);
|
||||||
|
|
||||||
|
// no hyperlinks for punctuation
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("{"));
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("}"));
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("(" + 1));
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf(")"));
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf(":"));
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf(";"));
|
||||||
|
|
||||||
|
// no hyperlinks inside strings
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("STRING") + 1);
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("STRING") + 6);
|
||||||
|
assertNotHyperlink(CPP_CODE.indexOf("LITERAL") + 1);
|
||||||
|
|
||||||
|
assertHyperlink(CPP_CODE.indexOf("Point {") + 1, CPP_CODE.indexOf("Point {"), "Point".length());
|
||||||
|
assertHyperlink(CPP_CODE.indexOf("Point()") + 1, CPP_CODE.indexOf("Point()"), "Point".length());
|
||||||
|
// No-AST hyperlink detection doesn't know that tilde is part of the destructor name.
|
||||||
|
assertHyperlink(CPP_CODE.indexOf("~Point()") + 1, CPP_CODE.indexOf("~Point()") + 1, "Point".length());
|
||||||
|
assertHyperlink(CPP_CODE.indexOf("set(") + 1, CPP_CODE.indexOf("set("), "set".length());
|
||||||
|
assertHyperlink(CPP_CODE.indexOf("getX()") + 1, CPP_CODE.indexOf("getX()"), "getX".length());
|
||||||
|
assertHyperlink(CPP_CODE.indexOf("getY()") + 1, CPP_CODE.indexOf("getY()"), "getY".length());
|
||||||
|
|
||||||
|
// Overloaded operators are not hyperlinked when AST is not available.
|
||||||
|
//assertHyperlink(CPP_CODE.indexOf("+ p"), CPP_CODE.indexOf("+ p"), 1);
|
||||||
|
}
|
||||||
|
|
||||||
public void testHyperlinksCKeywords() throws Exception {
|
public void testHyperlinksCKeywords() throws Exception {
|
||||||
setUpEditor(C_FILE_NAME_1, C_CODE_1);
|
setUpEditor(C_FILE_NAME_1, C_CODE_1, true);
|
||||||
|
|
||||||
// 'class' is not a keyword in C, it should be hyperlinked
|
// 'class' is not a keyword in C, it should be hyperlinked
|
||||||
assertHyperlink(C_CODE_1.indexOf("class") + 1, C_CODE_1.indexOf("class"), "class".length());
|
assertHyperlink(C_CODE_1.indexOf("class") + 1, C_CODE_1.indexOf("class"), "class".length());
|
||||||
|
@ -203,7 +265,7 @@ public class HyperlinkTest extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testHyperlinksInactiveCode() throws Exception {
|
public void testHyperlinksInactiveCode() throws Exception {
|
||||||
setUpEditor(C_FILE_NAME_2, C_CODE_2);
|
setUpEditor(C_FILE_NAME_2, C_CODE_2, true);
|
||||||
|
|
||||||
assertNotHyperlink(C_CODE_2.indexOf("#ifdef") + 2);
|
assertNotHyperlink(C_CODE_2.indexOf("#ifdef") + 2);
|
||||||
assertNotHyperlink(C_CODE_2.indexOf("#else") + 2);
|
assertNotHyperlink(C_CODE_2.indexOf("#else") + 2);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2009 QNX Software Systems and others.
|
* Copyright (c) 2000, 2010 QNX Software Systems and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -9,11 +9,11 @@
|
||||||
* QNX Software Systems - Initial API and implementation
|
* QNX Software Systems - Initial API and implementation
|
||||||
* IBM Corporation
|
* IBM Corporation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.editor;
|
package org.eclipse.cdt.internal.ui.editor;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
import org.eclipse.jface.action.IAction;
|
import org.eclipse.jface.action.IAction;
|
||||||
|
@ -40,6 +40,8 @@ import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
import org.eclipse.cdt.ui.text.ICPartitions;
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
|
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
|
||||||
|
import org.eclipse.cdt.internal.formatter.scanner.Scanner;
|
||||||
|
import org.eclipse.cdt.internal.formatter.scanner.Token;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.text.CWordFinder;
|
import org.eclipse.cdt.internal.ui.text.CWordFinder;
|
||||||
|
|
||||||
|
@ -47,9 +49,9 @@ public class CElementHyperlinkDetector extends AbstractHyperlinkDetector {
|
||||||
|
|
||||||
public CElementHyperlinkDetector() {
|
public CElementHyperlinkDetector() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHyperlink[] detectHyperlinks(final ITextViewer textViewer, final IRegion region, boolean canShowMultipleHyperlinks) {
|
public IHyperlink[] detectHyperlinks(final ITextViewer textViewer, final IRegion region, boolean canShowMultipleHyperlinks) {
|
||||||
ITextEditor textEditor= (ITextEditor)getAdapter(ITextEditor.class);
|
ITextEditor textEditor= (ITextEditor) getAdapter(ITextEditor.class);
|
||||||
if (region == null || !(textEditor instanceof CEditor))
|
if (region == null || !(textEditor instanceof CEditor))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -57,97 +59,140 @@ public class CElementHyperlinkDetector extends AbstractHyperlinkDetector {
|
||||||
if (openAction == null)
|
if (openAction == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// check partition type
|
IDocument document = textViewer.getDocument();
|
||||||
try {
|
|
||||||
String partitionType= TextUtilities.getContentType(textViewer.getDocument(), ICPartitions.C_PARTITIONING, region.getOffset(), false);
|
|
||||||
if (!IDocument.DEFAULT_CONTENT_TYPE.equals(partitionType) && !ICPartitions.C_PREPROCESSOR.equals(partitionType)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} catch (BadLocationException exc) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(textEditor.getEditorInput());
|
final IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(textEditor.getEditorInput());
|
||||||
if (workingCopy == null) {
|
if (workingCopy == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final IHyperlink[] result= {null};
|
final IRegion[] hyperlinkRegion = { null };
|
||||||
// Do not wait for AST if it's not available yet. Waiting for AST would block the UI thread
|
// Do not wait for AST if it's not available yet. Waiting for AST would block the UI thread
|
||||||
// for the duration of the parsing.
|
// for the duration of the parsing.
|
||||||
IStatus status= ASTProvider.getASTProvider().runOnAST(workingCopy, ASTProvider.WAIT_NO, null, new ASTRunnable() {
|
IStatus status= ASTProvider.getASTProvider().runOnAST(workingCopy, ASTProvider.WAIT_NO, null, new ASTRunnable() {
|
||||||
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) {
|
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) {
|
||||||
if (ast != null) {
|
if (ast == null)
|
||||||
final int offset= region.getOffset();
|
return Status.CANCEL_STATUS;
|
||||||
final int length= Math.max(1, region.getLength());
|
final int offset= region.getOffset();
|
||||||
final IASTNodeSelector nodeSelector= ast.getNodeSelector(null);
|
final int length= Math.max(1, region.getLength());
|
||||||
IASTName selectedName= nodeSelector.findEnclosingName(offset, length);
|
final IASTNodeSelector nodeSelector= ast.getNodeSelector(null);
|
||||||
IASTFileLocation linkLocation= null;
|
IASTName selectedName= nodeSelector.findEnclosingName(offset, length);
|
||||||
if (selectedName != null) { // found a name
|
IASTFileLocation linkLocation= null;
|
||||||
// prefer include statement over the include name
|
if (selectedName != null) { // found a name
|
||||||
if (selectedName.getParent() instanceof IASTPreprocessorIncludeStatement) {
|
// Prefer include statement over the include name
|
||||||
linkLocation= selectedName.getParent().getFileLocation();
|
if (selectedName.getParent() instanceof IASTPreprocessorIncludeStatement) {
|
||||||
}
|
linkLocation= selectedName.getParent().getFileLocation();
|
||||||
else {
|
|
||||||
linkLocation= selectedName.getFileLocation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
final IASTNode implicit = nodeSelector.findEnclosingImplicitName(offset, length);
|
|
||||||
if(implicit != null) {
|
|
||||||
linkLocation = implicit.getFileLocation();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// search for include statement
|
|
||||||
final IASTNode cand= nodeSelector.findEnclosingNode(offset, length);
|
|
||||||
if (cand instanceof IASTPreprocessorIncludeStatement) {
|
|
||||||
linkLocation= cand.getFileLocation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (linkLocation != null) {
|
|
||||||
result[0]= new CElementHyperlink(
|
|
||||||
new Region(linkLocation.getNodeOffset(), linkLocation.getNodeLength()), openAction);
|
|
||||||
} else {
|
} else {
|
||||||
// consider fallback navigation
|
linkLocation= selectedName.getFileLocation();
|
||||||
final IDocument document= textViewer.getDocument();
|
}
|
||||||
IRegion wordRegion= CWordFinder.findWord(document, offset);
|
} else {
|
||||||
if (wordRegion != null) {
|
final IASTNode implicit = nodeSelector.findEnclosingImplicitName(offset, length);
|
||||||
try {
|
if (implicit != null) {
|
||||||
String word = document.get(wordRegion.getOffset(), wordRegion.getLength());
|
linkLocation = implicit.getFileLocation();
|
||||||
if(word.length() > 0 && !Character.isDigit(word.charAt(0)) && !isLanguageKeyword(lang, word)) {
|
} else {
|
||||||
result[0]= new CElementHyperlink(
|
// Search for include statement
|
||||||
new Region(wordRegion.getOffset(), wordRegion.getLength()), openAction);
|
final IASTNode cand= nodeSelector.findEnclosingNode(offset, length);
|
||||||
}
|
if (cand instanceof IASTPreprocessorIncludeStatement) {
|
||||||
} catch (BadLocationException exc) {
|
linkLocation= cand.getFileLocation();
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (linkLocation != null) {
|
||||||
|
hyperlinkRegion[0] = new Region(linkLocation.getNodeOffset(), linkLocation.getNodeLength());
|
||||||
|
}
|
||||||
return Status.OK_STATUS;
|
return Status.OK_STATUS;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!status.isOK()) {
|
|
||||||
CUIPlugin.log(status);
|
if (status == Status.CANCEL_STATUS) {
|
||||||
|
// AST is not available yet, try to compute the hyperlink without it.
|
||||||
|
try {
|
||||||
|
// Check partition type.
|
||||||
|
String partitionType= TextUtilities.getContentType(document, ICPartitions.C_PARTITIONING, region.getOffset(), false);
|
||||||
|
if (IDocument.DEFAULT_CONTENT_TYPE.equals(partitionType)) {
|
||||||
|
// Regular code.
|
||||||
|
hyperlinkRegion[0] = getIdentifier(document, region.getOffset(), workingCopy.getLanguage());
|
||||||
|
} else if (ICPartitions.C_PREPROCESSOR.equals(partitionType)) {
|
||||||
|
// Preprocessor directive.
|
||||||
|
Scanner scanner= new Scanner();
|
||||||
|
scanner.setSplitPreprocessor(true);
|
||||||
|
scanner.setSource(document.get().toCharArray());
|
||||||
|
scanner.setCurrentPosition(findPreprocessorDirectiveStart(document, region.getOffset()));
|
||||||
|
Token token = scanner.nextToken();
|
||||||
|
if (token.getType() == Token.tPREPROCESSOR_INCLUDE) {
|
||||||
|
int endPos = token.getOffset() + token.getLength();
|
||||||
|
// Trim trailing whitespace.
|
||||||
|
while (Character.isWhitespace(document.getChar(--endPos))) {
|
||||||
|
}
|
||||||
|
endPos++;
|
||||||
|
if (region.getOffset() <= endPos) {
|
||||||
|
hyperlinkRegion[0] = new Region(token.getOffset(), endPos - token.getOffset());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hyperlinkRegion[0] = getIdentifier(document, region.getOffset(), workingCopy.getLanguage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
// Ignore to return null.
|
||||||
|
} catch (CoreException e) {
|
||||||
|
// Ignore to return null.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (hyperlinkRegion[0] == null)
|
||||||
return result[0] == null ? null : result;
|
return null;
|
||||||
|
return new IHyperlink[] { new CElementHyperlink(hyperlinkRegion[0], openAction) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the identifier at the given offset, or {@code null} if the there is no identifier
|
||||||
|
* at the offset.
|
||||||
|
*/
|
||||||
|
private static IRegion getIdentifier(IDocument document, int offset, ILanguage language) throws BadLocationException {
|
||||||
|
IRegion wordRegion= CWordFinder.findWord(document, offset);
|
||||||
|
if (wordRegion != null && wordRegion.getLength() > 0) {
|
||||||
|
String word = document.get(wordRegion.getOffset(), wordRegion.getLength());
|
||||||
|
if (!Character.isDigit(word.charAt(0)) && !isLanguageKeyword(language, word)) {
|
||||||
|
return wordRegion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isLanguageKeyword(ILanguage lang, String word) {
|
private static boolean isLanguageKeyword(ILanguage lang, String word) {
|
||||||
ICLanguageKeywords keywords= (ICLanguageKeywords) lang.getAdapter(ICLanguageKeywords.class);
|
ICLanguageKeywords keywords= (ICLanguageKeywords) lang.getAdapter(ICLanguageKeywords.class);
|
||||||
if (keywords != null) {
|
if (keywords != null) {
|
||||||
if (Arrays.asList(keywords.getKeywords()).contains(word)) {
|
for (String keyword : keywords.getKeywords()) {
|
||||||
return true;
|
if (keyword.equals(word))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (Arrays.asList(keywords.getBuiltinTypes()).contains(word)) {
|
for (String type : keywords.getBuiltinTypes()) {
|
||||||
return true;
|
if (type.equals(word))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (Arrays.asList(keywords.getPreprocessorKeywords()).contains('#'+word)) {
|
for (String keyword : keywords.getPreprocessorKeywords()) {
|
||||||
return true;
|
if (keyword.charAt(0) == '#' && keyword.regionMatches(1, word, 0, word.length()))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds beginning of a preprocessor directive.
|
||||||
|
*/
|
||||||
|
private static int findPreprocessorDirectiveStart(IDocument document, int offset) throws BadLocationException {
|
||||||
|
while (true) {
|
||||||
|
IRegion lineRegion = document.getLineInformationOfOffset(offset);
|
||||||
|
int lineOffset = lineRegion.getOffset();
|
||||||
|
if (lineOffset == 0)
|
||||||
|
return lineOffset;
|
||||||
|
int lineEnd = lineOffset + lineRegion.getLength();
|
||||||
|
for (offset = lineOffset; offset < lineEnd && Character.isWhitespace(document.getChar(offset)); offset++) {
|
||||||
|
}
|
||||||
|
if (offset < document.getLength() && document.getChar(offset) == '#') {
|
||||||
|
return lineOffset;
|
||||||
|
}
|
||||||
|
// The line doesn't start with #, try previous line.
|
||||||
|
offset = lineOffset - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue