From 0ae9539298fcf91e5d8d9c3ff354b40cf88f49d7 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 26 Apr 2006 13:26:27 +0000 Subject: [PATCH] Patch from Anton Leherbauer for bug 39521, highlighting of number constants. --- .../eclipse/cdt/ui/tests/AutomatedSuite.java | 2 + .../cdt/ui/tests/text/NumberRuleTest.java | 140 ++++++++++++++++++ .../cdt/internal/ui/text/NumberRule.java | 87 ++++++----- 3 files changed, 193 insertions(+), 36 deletions(-) create mode 100644 core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/NumberRuleTest.java diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java index 7e2d3aa2bd8..f1136e7d2af 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.ui.tests; import junit.framework.Test; import junit.framework.TestSuite; +import org.eclipse.cdt.ui.tests.text.NumberRuleTest; import org.eclipse.cdt.ui.tests.text.contentassist.CompletionFailedTest_MemberReference_Arrow_Prefix2; import org.eclipse.cdt.ui.tests.text.contentassist.CompletionTest_ArgumentType_NoPrefix; import org.eclipse.cdt.ui.tests.text.contentassist.CompletionTest_ArgumentType_NoPrefix2; @@ -79,6 +80,7 @@ public class AutomatedSuite extends TestSuite { // Success Tests //addTest(PartitionTokenScannerTest.suite()); + addTest(NumberRuleTest.suite()); // completion tests addTest(CompletionTest_FieldType_Prefix.suite()); addTest(CompletionTest_FieldType_NoPrefix.suite()); diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/NumberRuleTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/NumberRuleTest.java new file mode 100644 index 00000000000..81d1bcffec4 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/NumberRuleTest.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems, Inc. 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: + * Anton Leherbauer - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.ui.tests.text; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.internal.ui.text.NumberRule; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.RuleBasedScanner; +import org.eclipse.jface.text.rules.Token; + +/** + * Testing the NumberRule matching integers and floats. + */ +public class NumberRuleTest extends TestCase { + + private static final Object NUMBER = "number"; + private RuleBasedScanner fScanner; + private Document fDocument; + + /** + * @param name + */ + public NumberRuleTest(String name) { + super(name); + } + + public static Test suite() { + return new TestSuite(NumberRuleTest.class); + } + + protected void setUp() throws Exception { + super.setUp(); + fScanner = new RuleBasedScanner() {}; + fScanner.setRules(new IRule[] { + new NumberRule(new Token(NUMBER)) + }); + fDocument = new Document(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + public void testIntegers() { + // decimal numbers + assertNumber("0"); + assertNumber("-1"); + assertNumber("+1"); + assertNumber("123456789"); + assertNumber("-123456789"); + assertNumber("+123456789"); + + // hex numbers + assertNumber("0xaffe"); + assertNumber("-0xaffe"); + assertNumber("+0xaffe"); + assertNumber("0Xaffe"); + assertNumber("+0XaFFe"); + assertNumber("0xabcdefABCDEF"); + assertNumber("0x0123456789"); + } + + public void testFloats() { + assertNumber("0."); + assertNumber(".0"); + assertNumber("-.0"); + assertNumber("+.0"); + assertNumber("-0."); + assertNumber("+0."); + assertNumber("0.123456789"); + assertNumber("-0.123456789"); + assertNumber("+12345.6789"); + assertNumber("1e5"); + assertNumber("1E5"); + assertNumber("1.e5"); + assertNumber("-1e5"); + assertNumber("-.1e5"); + assertNumber("1e-5"); + assertNumber("1e+55"); + } + + public void testNonNumbers() { + // test pathological cases + assertNoNumber("-"); + assertNoNumber("+"); + assertNoNumber("."); + assertNoNumber("-."); + assertNoNumber("+."); + assertNoNumber("x"); + assertNoNumber(".x"); + assertNoNumber("-x"); + assertNoNumber("e"); + assertNoNumber(".e"); + assertNoNumber("-e"); + assertNoNumber("+e"); + + // false positives: +// assertNoNumber("0x"); +// assertNoNumber("1e"); +// assertNoNumber("1e+"); + } + + /** + * Validate that given string is recognized as a number. + * @param string + */ + private void assertNumber(String string) { + fDocument.set(string); + fScanner.setRange(fDocument, 0, fDocument.getLength()); + IToken token = fScanner.nextToken(); + assertSame(NUMBER, token.getData()); + assertEquals(string.length(), fScanner.getTokenLength()); + } + + /** + * Validate that given string is not recognized as a number. + * @param string + */ + private void assertNoNumber(String string) { + fDocument.set(string); + fScanner.setRange(fDocument, 0, fDocument.getLength()); + IToken token = fScanner.nextToken(); + assertNotSame(NUMBER, token.getData()); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/NumberRule.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/NumberRule.java index 63c8e6d2d78..e6b87db22b5 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/NumberRule.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/NumberRule.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005 QNX Software Systems and others. + * Copyright (c) 2005, 2006 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 @@ -7,6 +7,7 @@ * * Contributors: * QNX Software Systems - initial API and implementation + * Wind River Systems, Inc. - bug fixes *******************************************************************************/ package org.eclipse.cdt.internal.ui.text; @@ -16,7 +17,7 @@ import org.eclipse.jface.text.rules.IToken; import org.eclipse.jface.text.rules.Token; /** - * Recognizes numbers; + * Recognizes integer and float numbers. * * @author P.Tomaszewski */ @@ -42,46 +43,60 @@ public class NumberRule implements IRule public IToken evaluate(ICharacterScanner scanner) { int startCh = scanner.read(); - int ch; - + int ch; + int unreadCount = 1; + if (isNumberStart(startCh)) { - ch = scanner.read(); - boolean hexNumber = ch == 'x'; - boolean decNumber = false; - if (!hexNumber) - { - decNumber = Character.isDigit((char)ch); + ch = startCh; + if (startCh == '-' || startCh == '+') { + ch = scanner.read(); + ++unreadCount; } - if (!hexNumber && !decNumber) - { - scanner.unread(); - // If minus only it should be qualified as operator. - if (startCh == '-') - { + if (ch == '0') { + int xCh = scanner.read(); + ++unreadCount; + if (xCh == 'x' || xCh == 'X') { + // hexnumber starting with [+-]?0[xX] + do { + ch = scanner.read(); + } while (isHexNumberPart((char)ch)); scanner.unread(); - return Token.UNDEFINED; - } - return token; + return token; + } + scanner.unread(); + // assert ch == '0'; + } else if (!Character.isDigit((char)ch)) { + ch = scanner.read(); + ++unreadCount; } - if (hexNumber) - { - do - { - ch = scanner.read(); - } while (isHexNumberPart((char)ch)); + if (Character.isDigit((char)ch)) { + // need at least one digit + do { + ch = scanner.read(); + } while (Character.isDigit((char)ch)); + if (ch == '.' && startCh != '.') { + // fraction + do { + ch = scanner.read(); + } while (Character.isDigit((char)ch)); + } + if (ch == 'e' || ch == 'E') { + // exponent + ch = scanner.read(); + if (ch == '-' || ch == '+' || Character.isDigit((char)ch)) { + do { + ch = scanner.read(); + } while (Character.isDigit((char)ch)); + } + } + scanner.unread(); + return token; } - else if (decNumber) - { - do - { - ch = scanner.read(); - } while (Character.isDigit((char)ch)); - } - scanner.unread(); - return token; } - scanner.unread(); + do { + scanner.unread(); + } while (--unreadCount > 0); return Token.UNDEFINED; } @@ -92,7 +107,7 @@ public class NumberRule implements IRule */ private boolean isNumberStart(int ch) { - return ch == '-' || Character.isDigit((char)ch); + return ch == '-' || ch == '+' || ch == '.' || Character.isDigit((char)ch); } /**