diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/text/makefile/FunctionReferenceRule.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/text/makefile/FunctionReferenceRule.java new file mode 100644 index 00000000000..c4a0cf73468 --- /dev/null +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/text/makefile/FunctionReferenceRule.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2013, 2013 Andrew Gvozdev 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: + * Andrew Gvozdev - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.make.internal.ui.text.makefile; + +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.IWordDetector; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.rules.WordRule; + +public class FunctionReferenceRule extends WordRule { + /** Buffer used for pattern detection. */ + private StringBuffer fBuffer= new StringBuffer(); + + @SuppressWarnings("nls") + private final static String[] functions = { + "subst", "patsubst", "strip", "findstring", + "filter", "filter-out", "sort", + "word", "words", "wordlist", "firstword", "lastword", + "dir", "notdir", + "suffix", "basename", "addsuffix", "addprefix", + "join", "wildcard", "realpath", "abspath", + "if", "or", "and", "foreach", + "call", "value", "eval", "origin", "flavor", + "shell", "error", "warning", "info", + }; + + static class TagDetector implements IWordDetector { + private boolean isClosedBracket = false; + private int bracketNesting = 0; + @Override + public boolean isWordStart(char c) { + isClosedBracket = c == ')'; + return isClosedBracket || c == '$'; + } + @Override + public boolean isWordPart(char c) { + return !isClosedBracket && (c == '(' || Character.isJavaIdentifierPart(c)); + } + } + + public FunctionReferenceRule(IToken token) { + super(new TagDetector()); + for (String f : functions) { + addWord("$(" + f, token); //$NON-NLS-1$ + } + addWord(")", token); //$NON-NLS-1$ + } + + @Override + public IToken evaluate(ICharacterScanner scanner) { + int c= scanner.read(); + if (c == ')') { + if (((TagDetector)fDetector).bracketNesting > 0) { + ((TagDetector)fDetector).bracketNesting--; + return (IToken)fWords.get(")"); //$NON-NLS-1$ + } + return fDefaultToken; + } + + if (c != ICharacterScanner.EOF && fDetector.isWordStart((char) c)) { + if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) { + + fBuffer.setLength(0); + do { + fBuffer.append((char) c); + c= scanner.read(); + } while (c != ICharacterScanner.EOF && fDetector.isWordPart((char) c)); + scanner.unread(); + + String buffer= fBuffer.toString(); + + IToken token= (IToken)fWords.get(buffer); + + if (token != null) { + ((TagDetector)fDetector).bracketNesting++; + return token; + } + + if (fDefaultToken.isUndefined()) + unreadBuffer(scanner); + + return fDefaultToken; + } + } + + scanner.unread(); + return Token.UNDEFINED; + } + + @Override + protected void unreadBuffer(ICharacterScanner scanner) { + for (int i= fBuffer.length() - 1; i >= 0; i--) + scanner.unread(); + } +} diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/text/makefile/MakefileCodeScanner.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/text/makefile/MakefileCodeScanner.java index bfd74f2fa5a..a11c29ab1c5 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/text/makefile/MakefileCodeScanner.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/text/makefile/MakefileCodeScanner.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 QNX Software Systems and others. + * Copyright (c) 2000, 2013 QNX Software Systems 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 @@ -31,14 +31,6 @@ public class MakefileCodeScanner extends AbstractMakefileCodeScanner { "export", "unexport", "vpath" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ }; - private final static String[] functions = { "subst", "patsubst", "strip", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - "findstring", "filter", "sort", "dir", "notdir", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ - "suffix", "basename", "addsuffix", "addprefix", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - "join", "word", "words", "wordlist", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - "firstword", "wildcard", "error", "warning", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - "shell", "origin", "foreach", "call" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - }; - public static final String[] fTokenProperties = new String[] { ColorManager.MAKE_KEYWORD_COLOR, ColorManager.MAKE_FUNCTION_COLOR, @@ -97,18 +89,7 @@ public class MakefileCodeScanner extends AbstractMakefileCodeScanner { keyWordRule.setColumnConstraint(0); rules.add(keyWordRule); - WordRule functionRule = new WordRule(new IWordDetector() { - @Override - public boolean isWordPart(char c) { - return Character.isLetterOrDigit(c) || c == '_'; - } - @Override - public boolean isWordStart(char c) { - return Character.isLetterOrDigit(c) || c == '_'; - }}, other); - for (int i = 0; i < functions.length; i++) - functionRule.addWord(functions[i], function); - rules.add(functionRule); + rules.add(new FunctionReferenceRule(function)); rules.add(new MacroReferenceRule(macroRef, "$(", ")")); //$NON-NLS-1$ //$NON-NLS-2$ rules.add(new MacroReferenceRule(macroRef, "${", "}")); //$NON-NLS-1$ //$NON-NLS-2$ @@ -118,9 +99,6 @@ public class MakefileCodeScanner extends AbstractMakefileCodeScanner { return rules; } - /* - * @see AbstractMakefileCodeScanner#getTokenProperties() - */ @Override protected String[] getTokenProperties() { return fTokenProperties;