mirror of
https://github.com/peterdell/wudsn-ide.git
synced 2025-08-09 00:25:12 +00:00
Rework LanguageAnnotationValues and add test
This commit is contained in:
@@ -20,11 +20,27 @@
|
|||||||
package com.wudsn.ide.base.common;
|
package com.wudsn.ide.base.common;
|
||||||
|
|
||||||
public class Assertions {
|
public class Assertions {
|
||||||
|
|
||||||
public static void assertFalse(boolean actual) {
|
public static void assertFalse(boolean actual) {
|
||||||
throw new RuntimeException("Actual values is not false");
|
throw new RuntimeException("Actual values is not false");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void assertEquals(Object actual, Object expected) {
|
||||||
|
if (actual == expected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (actual == null && expected != null) {
|
||||||
|
fail("Actual value is null");
|
||||||
|
}
|
||||||
|
if (actual != null && expected == null) {
|
||||||
|
fail("Actual value " + actual + " is not null");
|
||||||
|
}
|
||||||
|
if (!actual.equals(expected)) {
|
||||||
|
fail("Actual value " + actual + " is not equal to expected value " + expected + "");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void fail(String message) {
|
public static void fail(String message) {
|
||||||
throw new RuntimeException(message);
|
throw new RuntimeException(message);
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,8 @@ import java.util.TreeMap;
|
|||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import org.eclipse.core.resources.IMarker;
|
import org.eclipse.core.resources.IMarker;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
|
||||||
import com.wudsn.ide.base.common.StringUtility;
|
import com.wudsn.ide.base.common.StringUtility;
|
||||||
|
|
||||||
@@ -46,6 +48,23 @@ public final class LanguageAnnotationValues {
|
|||||||
this.lineNumber = lineNumber;
|
this.lineNumber = lineNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (other instanceof LanguageAnnotationValue) {
|
||||||
|
LanguageAnnotationValue otherObject = (LanguageAnnotationValue) other;
|
||||||
|
if (!this.key.equals(otherObject.key)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!this.value.equals(otherObject.value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.lineNumber != (otherObject.lineNumber)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return key + "=" + value + " in line " + lineNumber;
|
return key + "=" + value + " in line " + lineNumber;
|
||||||
@@ -132,4 +151,58 @@ public final class LanguageAnnotationValues {
|
|||||||
return properties.toString();
|
return properties.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static LanguageAnnotationValues parseDocument(IDocument document) {
|
||||||
|
if (document == null) {
|
||||||
|
throw new IllegalArgumentException("Parameter 'document' must not be null.");
|
||||||
|
}
|
||||||
|
String content = document.get();
|
||||||
|
LanguageAnnotationValues result = new LanguageAnnotationValues();
|
||||||
|
|
||||||
|
int index = getMinIndex(content.indexOf(LanguageAnnotation.PREFIX),
|
||||||
|
content.indexOf(LanguageAnnotation.OLD_PREFIX));
|
||||||
|
while (index >= 0) {
|
||||||
|
|
||||||
|
int indexEqualSign = content.indexOf('=', index);
|
||||||
|
int indexNewLine = content.indexOf('\n', index);
|
||||||
|
if (indexNewLine < 0) {
|
||||||
|
indexNewLine = content.indexOf('\r', index);
|
||||||
|
}
|
||||||
|
if (indexNewLine < 0) {
|
||||||
|
indexNewLine = content.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indexEqualSign >= 0 && indexEqualSign < indexNewLine) {
|
||||||
|
String key = content.substring(index, indexEqualSign).trim();
|
||||||
|
String value = content.substring(indexEqualSign + 1, indexNewLine).trim();
|
||||||
|
int lineNumber;
|
||||||
|
try {
|
||||||
|
lineNumber = document.getLineOfOffset(index) + 1;
|
||||||
|
} catch (BadLocationException ex) {
|
||||||
|
lineNumber = 0;
|
||||||
|
}
|
||||||
|
result.put(key, value, lineNumber);
|
||||||
|
}
|
||||||
|
index = getMinIndex(content.indexOf(LanguageAnnotation.PREFIX, indexNewLine),
|
||||||
|
content.indexOf(LanguageAnnotation.OLD_PREFIX, indexNewLine));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the smaller of two string indexes. Values less than 0 indicate "not
|
||||||
|
* found" and are ignored.
|
||||||
|
*
|
||||||
|
* @param index1 The first index
|
||||||
|
* @param index2 The second index
|
||||||
|
* @return The smaller index or a value less than 0 if no index is valid.
|
||||||
|
*/
|
||||||
|
private static int getMinIndex(int index1, int index2) {
|
||||||
|
if (index1 < 0) {
|
||||||
|
return index2;
|
||||||
|
}
|
||||||
|
if (index2 < 0) {
|
||||||
|
return index1;
|
||||||
|
}
|
||||||
|
return Math.min(index1, index2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (C) 2009 - 2021 <a href="https://www.wudsn.com" target="_top">Peter Dell</a>
|
||||||
|
*
|
||||||
|
* This file is part of WUDSN IDE.
|
||||||
|
*
|
||||||
|
* WUDSN IDE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* WUDSN IDE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.wudsn.ide.lng;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
import org.eclipse.jface.text.Document;
|
||||||
|
|
||||||
|
import com.wudsn.ide.base.common.Assertions;
|
||||||
|
import com.wudsn.ide.base.common.TestMethod;
|
||||||
|
import com.wudsn.ide.lng.LanguageAnnotationValues.LanguageAnnotationValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to test dynamic variables.
|
||||||
|
*
|
||||||
|
* @author Peter Dell
|
||||||
|
*/
|
||||||
|
public final class LanguageAnnotationValuesTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creation is private.
|
||||||
|
*/
|
||||||
|
private LanguageAnnotationValuesTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMethod
|
||||||
|
public static void main(String[] args) {
|
||||||
|
var documment = new Document("; @com.wudsn.ide.asm.test=1");
|
||||||
|
var values = LanguageAnnotationValues.parseDocument(documment);
|
||||||
|
Set<String> expectedKeySet = new TreeSet<String>();
|
||||||
|
expectedKeySet.add("@com.wudsn.ide.asm.test");
|
||||||
|
values.keySet().equals(expectedKeySet);
|
||||||
|
Assertions.assertEquals(values.get("@com.wudsn.ide.asm.test"),
|
||||||
|
new LanguageAnnotationValue("@com.wudsn.ide.asm.test", "1", 1));
|
||||||
|
System.out.println(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -183,6 +183,7 @@ public final class LanguagePlugin extends AbstractIDEPlugin {
|
|||||||
// TODO: Call unit tests
|
// TODO: Call unit tests
|
||||||
CompilerPathsTest.main(new String[0]);
|
CompilerPathsTest.main(new String[0]);
|
||||||
RunnerPathsTest.main(new String[0]);
|
RunnerPathsTest.main(new String[0]);
|
||||||
|
LanguageAnnotationValuesTest.main(new String[0]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -87,59 +87,13 @@ public abstract class CompilerSourceParser {
|
|||||||
* @param document The document, not <code>null</code>.
|
* @param document The document, not <code>null</code>.
|
||||||
* @return The properties, may be empty, not <code>null</code>.
|
* @return The properties, may be empty, not <code>null</code>.
|
||||||
*/
|
*/
|
||||||
public static LanguageAnnotationValues getDocumentProperties(IDocument document) {
|
public static LanguageAnnotationValues getAnnotationValues(IDocument document) {
|
||||||
if (document == null) {
|
if (document == null) {
|
||||||
throw new IllegalArgumentException("Parameter 'document' must not be null.");
|
throw new IllegalArgumentException("Parameter 'document' must not be null.");
|
||||||
}
|
}
|
||||||
String content = document.get();
|
var result = LanguageAnnotationValues.parseDocument(document);
|
||||||
LanguageAnnotationValues properties = new LanguageAnnotationValues();
|
System.out.println("TEST:" + result);
|
||||||
|
return result;
|
||||||
int index = getMinIndex(content.indexOf(LanguageAnnotation.PREFIX),
|
|
||||||
content.indexOf(LanguageAnnotation.OLD_PREFIX));
|
|
||||||
while (index >= 0) {
|
|
||||||
|
|
||||||
int indexEqualSign = content.indexOf('=', index);
|
|
||||||
int indexNewLine = content.indexOf('\n', index);
|
|
||||||
if (indexNewLine < 0) {
|
|
||||||
indexNewLine = content.indexOf('\r', index);
|
|
||||||
}
|
|
||||||
if (indexNewLine < 0) {
|
|
||||||
indexNewLine = content.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indexEqualSign >= 0 && indexEqualSign < indexNewLine) {
|
|
||||||
String key = content.substring(index, indexEqualSign).trim();
|
|
||||||
String value = content.substring(indexEqualSign + 1, indexNewLine).trim();
|
|
||||||
int lineNumber;
|
|
||||||
try {
|
|
||||||
lineNumber = document.getLineOfOffset(index) + 1;
|
|
||||||
} catch (BadLocationException ex) {
|
|
||||||
lineNumber = 0;
|
|
||||||
}
|
|
||||||
properties.put(key, value, lineNumber);
|
|
||||||
}
|
|
||||||
index = getMinIndex(content.indexOf(LanguageAnnotation.PREFIX, indexNewLine),
|
|
||||||
content.indexOf(LanguageAnnotation.OLD_PREFIX, indexNewLine));
|
|
||||||
}
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the smaller of two string indexes. Values less than 0 indicate "not
|
|
||||||
* found" and are ignored.
|
|
||||||
*
|
|
||||||
* @param index1 The first index
|
|
||||||
* @param index2 The second index
|
|
||||||
* @return The smaller index or a value less than 0 if no index is valid.
|
|
||||||
*/
|
|
||||||
private static int getMinIndex(int index1, int index2) {
|
|
||||||
if (index1 < 0) {
|
|
||||||
return index2;
|
|
||||||
}
|
|
||||||
if (index2 < 0) {
|
|
||||||
return index1;
|
|
||||||
}
|
|
||||||
return Math.min(index1, index2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -244,12 +244,11 @@ public abstract class LanguageEditor extends TextEditor {
|
|||||||
compiler.getDefinition().getSyntax());
|
compiler.getDefinition().getSyntax());
|
||||||
partitionScanner.createDocumentPartitioner(document);
|
partitionScanner.createDocumentPartitioner(document);
|
||||||
|
|
||||||
LanguageAnnotationValues properties = CompilerSourceParser.getDocumentProperties(document);
|
var iFile = getCurrentIFile();
|
||||||
|
|
||||||
IFile iFile = getCurrentIFile();
|
|
||||||
if (iFile != null) {
|
if (iFile != null) {
|
||||||
try {
|
try {
|
||||||
hardware = filesLogic.getHardware(iFile, properties);
|
var annotationValues = CompilerSourceParser.getAnnotationValues(document);
|
||||||
|
hardware = filesLogic.getHardware(iFile, annotationValues);
|
||||||
} catch (InvalidLanguageAnnotationException ex) {
|
} catch (InvalidLanguageAnnotationException ex) {
|
||||||
// Do not use MarkerUtility.gotoMarker to make sure this
|
// Do not use MarkerUtility.gotoMarker to make sure this
|
||||||
// editor instance is used.
|
// editor instance is used.
|
||||||
|
@@ -88,19 +88,19 @@ public final class LanguageEditorFilesLogic {
|
|||||||
if (sourceIFile != null) {
|
if (sourceIFile != null) {
|
||||||
|
|
||||||
IDocument document = languageEditor.getDocumentProvider().getDocument(languageEditor.getEditorInput());
|
IDocument document = languageEditor.getDocumentProvider().getDocument(languageEditor.getEditorInput());
|
||||||
LanguageAnnotationValues sourceFileProperties = CompilerSourceParser.getDocumentProperties(document);
|
LanguageAnnotationValues annotationValues = CompilerSourceParser.getAnnotationValues(document);
|
||||||
|
|
||||||
IFile mainSourceIFile;
|
IFile mainSourceIFile;
|
||||||
LanguageAnnotationValues mainSourceFileProperties;
|
LanguageAnnotationValues mainSourceFileProperties;
|
||||||
|
|
||||||
mainSourceIFile = sourceIFile;
|
mainSourceIFile = sourceIFile;
|
||||||
mainSourceFileProperties = sourceFileProperties;
|
mainSourceFileProperties = annotationValues;
|
||||||
|
|
||||||
LanguageAnnotationValue property = sourceFileProperties.get(LanguageAnnotation.MAIN_SOURCE_FILE);
|
LanguageAnnotationValue annotationValue = annotationValues.get(LanguageAnnotation.MAIN_SOURCE_FILE);
|
||||||
if (property != null) {
|
if (annotationValue != null) {
|
||||||
if (StringUtility.isSpecified(property.value)) {
|
if (StringUtility.isSpecified(annotationValue.value)) {
|
||||||
IPath mainSourceFileIPath;
|
IPath mainSourceFileIPath;
|
||||||
mainSourceFileIPath = sourceIFile.getFullPath().removeLastSegments(1).append(property.value);
|
mainSourceFileIPath = sourceIFile.getFullPath().removeLastSegments(1).append(annotationValue.value);
|
||||||
mainSourceIFile = ResourcesPlugin.getWorkspace().getRoot().getFile(mainSourceFileIPath);
|
mainSourceIFile = ResourcesPlugin.getWorkspace().getRoot().getFile(mainSourceFileIPath);
|
||||||
File mainSourceFile = new File(mainSourceIFile.getLocation().toOSString());
|
File mainSourceFile = new File(mainSourceIFile.getLocation().toOSString());
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ public final class LanguageEditorFilesLogic {
|
|||||||
|
|
||||||
mainSource = FileUtility.readString(mainSourceFile, FileUtility.MAX_SIZE_UNLIMITED);
|
mainSource = FileUtility.readString(mainSourceFile, FileUtility.MAX_SIZE_UNLIMITED);
|
||||||
document = new Document(mainSource);
|
document = new Document(mainSource);
|
||||||
mainSourceFileProperties = CompilerSourceParser.getDocumentProperties(document);
|
mainSourceFileProperties = CompilerSourceParser.getAnnotationValues(document);
|
||||||
} catch (CoreException ex) {
|
} catch (CoreException ex) {
|
||||||
LanguagePlugin plugin = LanguagePlugin.getInstance();
|
LanguagePlugin plugin = LanguagePlugin.getInstance();
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ public final class LanguageEditorFilesLogic {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = new CompilerFiles(mainSourceIFile, mainSourceFileProperties, sourceIFile, sourceFileProperties,
|
result = new CompilerFiles(mainSourceIFile, mainSourceFileProperties, sourceIFile, annotationValues,
|
||||||
languageEditor.getLanguageHardwareCompilerPreferences());
|
languageEditor.getLanguageHardwareCompilerPreferences());
|
||||||
} else {
|
} else {
|
||||||
result = null;
|
result = null;
|
||||||
@@ -169,7 +169,7 @@ public final class LanguageEditorFilesLogic {
|
|||||||
*
|
*
|
||||||
* @param iFile The IFile to which error message will be associated, not
|
* @param iFile The IFile to which error message will be associated, not
|
||||||
* <code>null</code>.
|
* <code>null</code>.
|
||||||
* @param properties The language properties, not <code>null</code>.
|
* @param annotationValues The annotation values, not <code>null</code>.
|
||||||
*
|
*
|
||||||
* @return The hardware or <code>null</code> if is the not defined in the
|
* @return The hardware or <code>null</code> if is the not defined in the
|
||||||
* properties.
|
* properties.
|
||||||
@@ -179,13 +179,13 @@ public final class LanguageEditorFilesLogic {
|
|||||||
*
|
*
|
||||||
* @since 1.6.1
|
* @since 1.6.1
|
||||||
*/
|
*/
|
||||||
Hardware getHardware(IFile iFile, LanguageAnnotationValues properties) throws InvalidLanguageAnnotationException {
|
Hardware getHardware(IFile iFile, LanguageAnnotationValues annotationValues) throws InvalidLanguageAnnotationException {
|
||||||
if (iFile == null) {
|
if (iFile == null) {
|
||||||
throw new IllegalArgumentException("Parameter 'iFile' must not be null.");
|
throw new IllegalArgumentException("Parameter 'iFile' must not be null.");
|
||||||
}
|
}
|
||||||
Hardware hardware = null;
|
Hardware hardware = null;
|
||||||
LanguageAnnotationValue hardwareProperty = properties.get(LanguageAnnotation.HARDWARE);
|
LanguageAnnotationValue hardwareAnnotationValue = annotationValues.get(LanguageAnnotation.HARDWARE);
|
||||||
if (hardwareProperty != null) {
|
if (hardwareAnnotationValue != null) {
|
||||||
Map<String, Hardware> allowedValues = new TreeMap<String, Hardware>();
|
Map<String, Hardware> allowedValues = new TreeMap<String, Hardware>();
|
||||||
StringBuilder allowedValuesBuilder = new StringBuilder();
|
StringBuilder allowedValuesBuilder = new StringBuilder();
|
||||||
for (Hardware value : Hardware.values()) {
|
for (Hardware value : Hardware.values()) {
|
||||||
@@ -199,8 +199,8 @@ public final class LanguageEditorFilesLogic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String hardwarePropertyValue = hardwareProperty.value.toUpperCase();
|
String hardwareValue = hardwareAnnotationValue.value.toUpperCase();
|
||||||
if (StringUtility.isEmpty(hardwarePropertyValue)) {
|
if (StringUtility.isEmpty(hardwareValue)) {
|
||||||
try {
|
try {
|
||||||
iFile.deleteMarkers(IMarker.PROBLEM, true, IResource.DEPTH_ZERO);
|
iFile.deleteMarkers(IMarker.PROBLEM, true, IResource.DEPTH_ZERO);
|
||||||
} catch (CoreException ex) {
|
} catch (CoreException ex) {
|
||||||
@@ -208,11 +208,11 @@ public final class LanguageEditorFilesLogic {
|
|||||||
}
|
}
|
||||||
// ERROR: Hardware not specified. Specify one of the
|
// ERROR: Hardware not specified. Specify one of the
|
||||||
// following valid values '{0}'.
|
// following valid values '{0}'.
|
||||||
IMarker marker = MarkerUtility.createMarker(iFile, hardwareProperty.lineNumber, IMarker.SEVERITY_ERROR,
|
IMarker marker = MarkerUtility.createMarker(iFile, hardwareAnnotationValue.lineNumber, IMarker.SEVERITY_ERROR,
|
||||||
Texts.MESSAGE_E128, new String[] { allowedValuesBuilder.toString() });
|
Texts.MESSAGE_E128, new String[] { allowedValuesBuilder.toString() });
|
||||||
throw new InvalidLanguageAnnotationException(hardwareProperty, marker);
|
throw new InvalidLanguageAnnotationException(hardwareAnnotationValue, marker);
|
||||||
}
|
}
|
||||||
hardware = allowedValues.get(hardwarePropertyValue);
|
hardware = allowedValues.get(hardwareValue);
|
||||||
|
|
||||||
if (hardware == null) {
|
if (hardware == null) {
|
||||||
try {
|
try {
|
||||||
@@ -222,9 +222,9 @@ public final class LanguageEditorFilesLogic {
|
|||||||
}
|
}
|
||||||
// ERROR: Unknown hardware {0}. Specify one of the
|
// ERROR: Unknown hardware {0}. Specify one of the
|
||||||
// following valid values '{1}'.
|
// following valid values '{1}'.
|
||||||
IMarker marker = MarkerUtility.createMarker(iFile, hardwareProperty.lineNumber, IMarker.SEVERITY_ERROR,
|
IMarker marker = MarkerUtility.createMarker(iFile, hardwareAnnotationValue.lineNumber, IMarker.SEVERITY_ERROR,
|
||||||
Texts.MESSAGE_E124, new String[] { hardwarePropertyValue, allowedValuesBuilder.toString() });
|
Texts.MESSAGE_E124, new String[] { hardwareValue, allowedValuesBuilder.toString() });
|
||||||
throw new InvalidLanguageAnnotationException(hardwareProperty, marker);
|
throw new InvalidLanguageAnnotationException(hardwareAnnotationValue, marker);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user