wudsn-ide/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserTreeObject.java
2019-01-12 23:07:17 +01:00

412 lines
12 KiB
Java

/**
* Copyright (C) 2009 - 2019 <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.asm.compiler.parser;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.viewers.StyledString;
import com.wudsn.ide.asm.compiler.syntax.CompilerSyntax;
import com.wudsn.ide.base.common.StringUtility;
/**
* The object representing a node in the content outline tree.
*
* @author Peter Dell
* @author Andy Reek
*/
public final class CompilerSourceParserTreeObject {
private final CompilerSourceFile compilerSourceFile;
private final int startOffset;
private final int type;
private final String name;
private final String displayName;
private final String description;
private final StyledString styledString;
private final List<CompilerSourceParserTreeObject> children;
private CompilerSourceParserTreeObject parent;
private String treePath;
private String compoundName;
private CompilerSourceFile includedCompilerSourceFile;
/**
* Create a new instance.
*
* @param compilerSourceFile
* The source file to which this parser tree object belongs.
*
* @param startOffset
* The start offset of the instance, a non-negative integer.
* @param type
* The type of a instance, see
* {@link CompilerSourceParserTreeObjectType}.
* @param name
* The name of the tree object, not <code>null</code>. It is used
* to build the full tree path,
* @param displayName
* The display name of the tree object, not <code>null</code>. It
* is used in the tree view.
* @param description
* The description of the tree object, not <code>null</code>.
*/
CompilerSourceParserTreeObject(CompilerSourceFile compilerSourceFile,
int startOffset, int type, String name, String displayName,
String description) {
if (compilerSourceFile == null) {
throw new IllegalArgumentException(
"Parameter 'compilerSourceFile' must not be null.");
}
if (startOffset < 0) {
throw new IllegalArgumentException(
"Parameter 'startOffset' must not be negative. Specified value is "
+ startOffset + ".");
}
this.compilerSourceFile = compilerSourceFile;
this.startOffset = startOffset;
switch (type) {
case CompilerSourceParserTreeObjectType.DEFAULT:
case CompilerSourceParserTreeObjectType.DEFINITION_SECTION:
case CompilerSourceParserTreeObjectType.IMPLEMENTATION_SECTION:
case CompilerSourceParserTreeObjectType.EQUATE_DEFINITION:
case CompilerSourceParserTreeObjectType.LABEL_DEFINITION:
case CompilerSourceParserTreeObjectType.ENUM_DEFINITION_SECTION:
case CompilerSourceParserTreeObjectType.STRUCTURE_DEFINITION_SECTION:
case CompilerSourceParserTreeObjectType.LOCAL_SECTION:
case CompilerSourceParserTreeObjectType.MACRO_DEFINITION_SECTION:
case CompilerSourceParserTreeObjectType.PAGES_SECTION:
case CompilerSourceParserTreeObjectType.PROCEDURE_DEFINITION_SECTION:
case CompilerSourceParserTreeObjectType.REPEAT_SECTION:
case CompilerSourceParserTreeObjectType.SOURCE_INCLUDE:
case CompilerSourceParserTreeObjectType.BINARY_INCLUDE:
case CompilerSourceParserTreeObjectType.BINARY_OUTPUT:
break;
default:
throw new IllegalArgumentException("Unknown type " + type + ".");
}
if (name == null) {
throw new IllegalArgumentException(
"Parameter 'name' must not be null.");
}
if (displayName == null) {
throw new IllegalArgumentException(
"Parameter 'displayName' must not be null.");
}
if (description == null) {
throw new IllegalArgumentException(
"Parameter 'description' must not be null.");
}
this.type = type;
this.name = name;
this.displayName = displayName;
this.description = description;
styledString = new StyledString(displayName);
if (description.length() > 0) {
styledString.append(" ");
styledString.append(description, StyledString.QUALIFIER_STYLER);
}
this.children = new ArrayList<CompilerSourceParserTreeObject>();
}
/**
* Gets the compiler source file, this parser tree object belongs to.
*
* @return The compiler source file, this parser tree object belongs to, not
* <code>null</code>.
*/
public CompilerSourceFile getCompilerSourceFile() {
return compilerSourceFile;
}
/**
* Gets the start offset of this parser tree object in the compiler source
* file.
*
* @return The start offset of this parser tree object in the compiler
* source file, a non-negative integer.
*/
public int getStartOffset() {
return startOffset;
}
/**
* Gets the type of the object.
*
* @return The type, see {@link CompilerSourceParserTreeObjectType}.
*/
public int getType() {
return type;
}
/**
* Gets the name of the object.
*
* @return The name, not <code>null</code>.
*/
public String getName() {
return name;
}
/**
* Gets the compound name of the object.
*
* @return The compound name, not <code>null</code>.
*/
public String getCompoundName() {
if (compoundName == null) {
char identifierSeparatorCharacter = compilerSourceFile
.getCompilerSyntax().getIdentifierSeparatorCharacter();
switch (type) {
case CompilerSourceParserTreeObjectType.DEFINITION_SECTION:
case CompilerSourceParserTreeObjectType.IMPLEMENTATION_SECTION:
case CompilerSourceParserTreeObjectType.REPEAT_SECTION:
case CompilerSourceParserTreeObjectType.SOURCE_INCLUDE:
case CompilerSourceParserTreeObjectType.BINARY_INCLUDE:
case CompilerSourceParserTreeObjectType.BINARY_OUTPUT:
if (parent != null) {
compoundName = parent.getCompoundName();
} else {
compoundName = "";
}
return compoundName;
}
compoundName = name;
// Compound identifiers supported?
if (identifierSeparatorCharacter != CompilerSyntax.NO_CHARACTER) {
// Find next named parent.
CompilerSourceParserTreeObject namedParent = parent;
while (namedParent != null
// && namedParent.getType() !=
// CompilerSourceParserTreeObjectType.DEFINITION_SECTION
// && namedParent.getType() !=
// CompilerSourceParserTreeObjectType.IMPLEMENTATION_SECTION
// && namedParent.getType() !=
// CompilerSourceParserTreeObjectType.REPEAT_SECTION
// && namedParent.getType() !=
// CompilerSourceParserTreeObjectType.SOURCE_INCLUDE
// && namedParent.getType() !=
// CompilerSourceParserTreeObjectType.BINARY_INCLUDE
// && namedParent.getType() !=
// CompilerSourceParserTreeObjectType.BINARY_OUTPUT
&& namedParent.getType() != CompilerSourceParserTreeObjectType.ENUM_DEFINITION_SECTION
&& namedParent.getType() != CompilerSourceParserTreeObjectType.STRUCTURE_DEFINITION_SECTION
&& namedParent.getType() != CompilerSourceParserTreeObjectType.LOCAL_SECTION
&& namedParent.getType() != CompilerSourceParserTreeObjectType.MACRO_DEFINITION_SECTION
&& namedParent.getType() != CompilerSourceParserTreeObjectType.PROCEDURE_DEFINITION_SECTION) {
namedParent = namedParent.getParent();
}
if (namedParent != null
&& StringUtility.isSpecified(compoundName)) {
String parentCompoundName;
parentCompoundName = parent.getCompoundName();
if (StringUtility.isSpecified(parentCompoundName)) {
compoundName = parentCompoundName
+ identifierSeparatorCharacter + compoundName;
}
}
}
}
return compoundName;
}
/**
* Gets the display name of the object.
*
* @return The display name, not <code>null</code>.
*/
public String getDisplayName() {
return displayName;
}
/**
* Gets the unique tree path of this tree object within the tree.
*
* @return The unique tree path, not empty and not <code>null</code>.
*/
public String getTreePath() {
if (treePath == null) {
treePath = "\"" + type + "/" + name + "\"";
if (parent != null) {
treePath = parent.getTreePath() + "/" + treePath;
}
}
return treePath;
}
/**
* Gets the description of the object.
*
* @return The description, not <code>null</code>.
*/
public String getDescription() {
return description;
}
/**
* Gets the styled string of the object.
*
* @return The styled string, not <code>null</code>.
*/
public StyledString getStyledString() {
return styledString;
}
/**
* Gets the parent object of the tree object.
*
* @return The parent, may be <code>null</code>.
*/
public CompilerSourceParserTreeObject getParent() {
return parent;
}
/**
* Sets a new parent.
*
* @param parent
* The new parent, may be <code>null</code>.
*/
final void setParent(CompilerSourceParserTreeObject parent) {
this.parent = parent;
this.treePath = null;
}
/**
* Determines if this tree object has children.
*
* @return <code>true</code> if this tree object has children,
* <code>false</code> otherwise.
*/
public boolean hasChildren() {
return !children.isEmpty();
}
/**
* Gets all children of the tree object.
*
* @return The array of children, not <code>null</code>..
*/
public Object[] getChildrenAsArray() {
return children.toArray(new Object[0]);
}
/**
* Gets all children of the tree object.
*
* @return The array of children, not <code>null</code>. Do not modify.
*/
public List<CompilerSourceParserTreeObject> getChildren() {
return children;
}
/**
* Adds a new Child.
*
* @param child
* The new child, not <code>null</code>.
*/
final void addChild(CompilerSourceParserTreeObject child) {
if (child == null) {
throw new IllegalArgumentException(
"Parameter 'child' must not be null.");
}
if (child == this) {
throw new IllegalArgumentException(
"Parameter 'child' must not be this: " + toString());
}
children.add(child);
child.setParent(this);
}
/**
* Gets the included compiler source file for a SOURCE_INCLUDE tree object.
*
* @return The included compiler source file or <code>null</code>.
*/
final CompilerSourceFile setIncludedCompilerSourceFile() {
return includedCompilerSourceFile;
}
/**
* Sets the included compiler source file for a SOURCE_INCLUDE tree object.
*
* @param includedCompilerSourceFile
* The included compiler source file, may be <code>null</code>.
*/
final void setIncludedCompilerSourceFile(
CompilerSourceFile includedCompilerSourceFile) {
if (type != CompilerSourceParserTreeObjectType.SOURCE_INCLUDE) {
throw new IllegalStateException("The type of this tree object is "
+ type + " and not SOURCE_INCLUDE");
}
this.includedCompilerSourceFile = includedCompilerSourceFile;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof CompilerSourceParserTreeObject)) {
return false;
}
CompilerSourceParserTreeObject other;
other = (CompilerSourceParserTreeObject) object;
return getTreePath().equals(other.getTreePath());
}
@Override
public int hashCode() {
return getTreePath().hashCode();
}
@Override
public String toString() {
return getTreePath();
}
}