Selector.java
package Hoot.Runtime.Names;
import java.util.*;
import Hoot.Runtime.Maps.Library;
import Hoot.Runtime.Emissions.NamedItem;
import Hoot.Runtime.Emissions.Emission;
import Hoot.Runtime.Emissions.EmissionSource;
import static Hoot.Runtime.Names.Keyword.*;
import static Hoot.Runtime.Emissions.Emission.*;
import static Hoot.Runtime.Faces.Logging.*;
import static Hoot.Runtime.Functions.Utils.*;
/**
* A method name (Smalltalk selector).
*
* @author nik <nikboyd@sonic.net>
* @see "Copyright 1999,2021 Nikolas S Boyd."
* @see "Permission is granted to copy this work provided this copyright statement is retained in all copies."
*/
public class Selector extends NamedItem implements Hoot.Runtime.Faces.Selector, EmissionSource {
public Selector() { super(null); contents = new StringBuffer(); }
public static Selector named(String name) { return from(name); }
/**
* @return a new selector created from the supplied name
* @param name a selector name.
*/
public static Selector from(String name) {
Selector selector = new Selector();
selector.append(name);
return selector;
}
/**
* @return the number of operands in a message involving the selector.
* @param selector a selector
*/
public static int operandCountFrom(String selector) {
if (Name.BinaryOperators.containsKey(selector)) {
return 2;
}
return countMatches(selector, Colon) + 1;
}
StringBuffer contents;
public String contents() { return contents.toString(); }
public String methodName() { return Name.from(contents()); }
public String asPrimitiveOperator() { return (String) PrimitiveOperators.get(contents()); }
public void append(String aString) { contents.append(aString); }
public boolean isAssign() { return contents().equals(Assign); }
public boolean isKeyword() { return contents().endsWith(Colon); }
public boolean isBasicNew() { return contents().startsWith("basicNew"); }
public boolean isNew() { return contents().startsWith("new"); }
@Override public String toString() { return contents(); }
@Override public String name() { return methodName(); }
@Override public boolean isEmpty() { return contents.length() == 0; }
@Override public boolean isSelfish() {
return contents().startsWith(Super) || contents().startsWith(Self); }
public boolean isOperator() { return Name.BinaryOperators.containsKey(contents()); }
@Override public boolean isPrimitive() { return PrimitiveOperators.containsKey(contents()); }
@Override public boolean isOptimized() { return ObjectSelectors.contains(contents()); }
public boolean isReturn() { return contents().equals(Exit); }
public int operandCount() { return operandCountFrom(contents()); }
public Emission emitQuotedMethodName() { return emitQuoted(methodName()); }
@Override public Class<?> toClass() {
return Name.isQualified(fullName()) ?
Hoot.Runtime.Faces.Selector.super.toClass() :
nullOr(f -> f.primitiveClass(), Library.findFace(fullName())); }
@Override public int hashCode() { return contents().hashCode(); }
@Override public boolean equals(Object selector) {
return hasAny(selector) &&
Hoot.Runtime.Faces.Selector.class.isAssignableFrom(selector.getClass()) &&
falseOr(s -> contents().equals(s.toString()), (Hoot.Runtime.Faces.Selector)selector); }
public static final Selector empty = Selector.from(Empty);
public static final String Assign = ":=";
public static final Selector forAssignment = Selector.from(Assign);
public static final String Exit = "^";
public static final Selector forExit = Selector.from(Exit);
public static final char COLON = ':';
static final String Colon = ":";
static final char UNDER = '_';
static final String Under = "_";
static final char DOLLAR = '$';
static final String Dollar = "$";
static final Properties PrimitiveOperators = new Properties();
static final List<String> ObjectSelectors = emptyList(String.class);
/**
* Initializes (reservedWords), (binaryOperators), (controlClasses).
*/
static {
PrimitiveOperators.put("&", " & ");
PrimitiveOperators.put("|", " | ");
PrimitiveOperators.put("+", " + ");
PrimitiveOperators.put("+=", " += ");
PrimitiveOperators.put("-", " - ");
PrimitiveOperators.put("-=", " -= ");
PrimitiveOperators.put("*", " * ");
PrimitiveOperators.put("*=", " *= ");
PrimitiveOperators.put("/", " / ");
PrimitiveOperators.put("%", " % ");
PrimitiveOperators.put("/=", " /= ");
PrimitiveOperators.put("//", " / ");
PrimitiveOperators.put("\\\\", " % ");
PrimitiveOperators.put("==", " == ");
PrimitiveOperators.put("<", " < ");
PrimitiveOperators.put("<=", " <= ");
PrimitiveOperators.put(">", " > ");
PrimitiveOperators.put(">=", " >= ");
PrimitiveOperators.put("~~", " != ");
PrimitiveOperators.put(Assign, " = "); // ??
ObjectSelectors.add("class");
ObjectSelectors.add("new");
ObjectSelectors.add("new:");
ObjectSelectors.add("==");
ObjectSelectors.add("~~");
ObjectSelectors.add("=");
ObjectSelectors.add("~=");
ObjectSelectors.add("do:");
ObjectSelectors.add("hash");
ObjectSelectors.add("hashCode");
ObjectSelectors.add("value");
ObjectSelectors.add("yourself");
ObjectSelectors.add("species");
ObjectSelectors.add("isNil");
ObjectSelectors.add("notNil");
ObjectSelectors.add(Assign);
}
} // Selector