Rework LanguageAnnotationValues and add test

This commit is contained in:
Peter Dell 2023-02-13 00:22:46 +01:00
parent e2989f03c1
commit c013951d56
7 changed files with 174 additions and 75 deletions

View File

@ -20,11 +20,27 @@
package com.wudsn.ide.base.common;
public class Assertions {
public static void assertFalse(boolean actual) {
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) {
throw new RuntimeException(message);
}

View File

@ -25,6 +25,8 @@ import java.util.TreeMap;
import java.util.TreeSet;
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;
@ -46,6 +48,23 @@ public final class LanguageAnnotationValues {
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
public String toString() {
return key + "=" + value + " in line " + lineNumber;
@ -132,4 +151,58 @@ public final class LanguageAnnotationValues {
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);
}
}

View File

@ -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);
}
}

View File

@ -183,6 +183,7 @@ public final class LanguagePlugin extends AbstractIDEPlugin {
// TODO: Call unit tests
CompilerPathsTest.main(new String[0]);
RunnerPathsTest.main(new String[0]);
LanguageAnnotationValuesTest.main(new String[0]);
}

View File

@ -87,59 +87,13 @@ public abstract class CompilerSourceParser {
* @param document The document, 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) {
throw new IllegalArgumentException("Parameter 'document' must not be null.");
}
String content = document.get();
LanguageAnnotationValues properties = 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;
}
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);
var result = LanguageAnnotationValues.parseDocument(document);
System.out.println("TEST:" + result);
return result;
}
/**

View File

@ -244,12 +244,11 @@ public abstract class LanguageEditor extends TextEditor {
compiler.getDefinition().getSyntax());
partitionScanner.createDocumentPartitioner(document);
LanguageAnnotationValues properties = CompilerSourceParser.getDocumentProperties(document);
IFile iFile = getCurrentIFile();
var iFile = getCurrentIFile();
if (iFile != null) {
try {
hardware = filesLogic.getHardware(iFile, properties);
var annotationValues = CompilerSourceParser.getAnnotationValues(document);
hardware = filesLogic.getHardware(iFile, annotationValues);
} catch (InvalidLanguageAnnotationException ex) {
// Do not use MarkerUtility.gotoMarker to make sure this
// editor instance is used.

View File

@ -88,19 +88,19 @@ public final class LanguageEditorFilesLogic {
if (sourceIFile != null) {
IDocument document = languageEditor.getDocumentProvider().getDocument(languageEditor.getEditorInput());
LanguageAnnotationValues sourceFileProperties = CompilerSourceParser.getDocumentProperties(document);
LanguageAnnotationValues annotationValues = CompilerSourceParser.getAnnotationValues(document);
IFile mainSourceIFile;
LanguageAnnotationValues mainSourceFileProperties;
mainSourceIFile = sourceIFile;
mainSourceFileProperties = sourceFileProperties;
mainSourceFileProperties = annotationValues;
LanguageAnnotationValue property = sourceFileProperties.get(LanguageAnnotation.MAIN_SOURCE_FILE);
if (property != null) {
if (StringUtility.isSpecified(property.value)) {
LanguageAnnotationValue annotationValue = annotationValues.get(LanguageAnnotation.MAIN_SOURCE_FILE);
if (annotationValue != null) {
if (StringUtility.isSpecified(annotationValue.value)) {
IPath mainSourceFileIPath;
mainSourceFileIPath = sourceIFile.getFullPath().removeLastSegments(1).append(property.value);
mainSourceFileIPath = sourceIFile.getFullPath().removeLastSegments(1).append(annotationValue.value);
mainSourceIFile = ResourcesPlugin.getWorkspace().getRoot().getFile(mainSourceFileIPath);
File mainSourceFile = new File(mainSourceIFile.getLocation().toOSString());
@ -109,7 +109,7 @@ public final class LanguageEditorFilesLogic {
mainSource = FileUtility.readString(mainSourceFile, FileUtility.MAX_SIZE_UNLIMITED);
document = new Document(mainSource);
mainSourceFileProperties = CompilerSourceParser.getDocumentProperties(document);
mainSourceFileProperties = CompilerSourceParser.getAnnotationValues(document);
} catch (CoreException ex) {
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());
} else {
result = null;
@ -169,7 +169,7 @@ public final class LanguageEditorFilesLogic {
*
* @param iFile The IFile to which error message will be associated, not
* <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
* properties.
@ -179,13 +179,13 @@ public final class LanguageEditorFilesLogic {
*
* @since 1.6.1
*/
Hardware getHardware(IFile iFile, LanguageAnnotationValues properties) throws InvalidLanguageAnnotationException {
Hardware getHardware(IFile iFile, LanguageAnnotationValues annotationValues) throws InvalidLanguageAnnotationException {
if (iFile == null) {
throw new IllegalArgumentException("Parameter 'iFile' must not be null.");
}
Hardware hardware = null;
LanguageAnnotationValue hardwareProperty = properties.get(LanguageAnnotation.HARDWARE);
if (hardwareProperty != null) {
LanguageAnnotationValue hardwareAnnotationValue = annotationValues.get(LanguageAnnotation.HARDWARE);
if (hardwareAnnotationValue != null) {
Map<String, Hardware> allowedValues = new TreeMap<String, Hardware>();
StringBuilder allowedValuesBuilder = new StringBuilder();
for (Hardware value : Hardware.values()) {
@ -199,8 +199,8 @@ public final class LanguageEditorFilesLogic {
}
}
String hardwarePropertyValue = hardwareProperty.value.toUpperCase();
if (StringUtility.isEmpty(hardwarePropertyValue)) {
String hardwareValue = hardwareAnnotationValue.value.toUpperCase();
if (StringUtility.isEmpty(hardwareValue)) {
try {
iFile.deleteMarkers(IMarker.PROBLEM, true, IResource.DEPTH_ZERO);
} catch (CoreException ex) {
@ -208,11 +208,11 @@ public final class LanguageEditorFilesLogic {
}
// ERROR: Hardware not specified. Specify one of the
// 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() });
throw new InvalidLanguageAnnotationException(hardwareProperty, marker);
throw new InvalidLanguageAnnotationException(hardwareAnnotationValue, marker);
}
hardware = allowedValues.get(hardwarePropertyValue);
hardware = allowedValues.get(hardwareValue);
if (hardware == null) {
try {
@ -222,9 +222,9 @@ public final class LanguageEditorFilesLogic {
}
// ERROR: Unknown hardware {0}. Specify one of the
// following valid values '{1}'.
IMarker marker = MarkerUtility.createMarker(iFile, hardwareProperty.lineNumber, IMarker.SEVERITY_ERROR,
Texts.MESSAGE_E124, new String[] { hardwarePropertyValue, allowedValuesBuilder.toString() });
throw new InvalidLanguageAnnotationException(hardwareProperty, marker);
IMarker marker = MarkerUtility.createMarker(iFile, hardwareAnnotationValue.lineNumber, IMarker.SEVERITY_ERROR,
Texts.MESSAGE_E124, new String[] { hardwareValue, allowedValuesBuilder.toString() });
throw new InvalidLanguageAnnotationException(hardwareAnnotationValue, marker);
}
}