Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions rhino/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,5 @@ decycle {
// currently accepted cycles (may be resolved, when it is clear, how to separate the liveconnect stuff)
ignoring from: "org.mozilla.javascript.lc.type.*", to: "org.mozilla.javascript.(Scriptable|ScriptableObject)"
ignoring from: "org.mozilla.javascript.lc.type.TypeInfoFactory", to: "org.mozilla.javascript.lc.type.impl.factory.*"
ignoring from: "org.mozilla.javascript.lc.type.TypeInfo", to: "org.mozilla.javascript.lc.type.impl.*"
ignoring from: "org.mozilla.javascript.lc.type.TypeFormatContext", to: "org.mozilla.javascript.lc.type.impl.ClassSignatureFormatContext"

ignoring from: "org.mozilla.javascript.lc.type.*", to: "org.mozilla.javascript.lc.type.impl.*"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's worth taking a look at the overall recycle rules for our base package lc.type as we keep having to fix them during development. If the intention is that they reflect the future separation of the lc components from the main Rhino module then lc should have access to whatever is exported from the main module, and we really shouldn't care about anything more precise than that.

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ default TypeInfo param(int index) {
return index >= 0 && index < params.size() ? params.get(index) : TypeInfo.NONE;
}

/**
* @see ParameterizedType#getOwnerType()
*/
TypeInfo ownerType();

/**
* Extract consolidation mapping based on {@link #params()} and {@link
* Class#getTypeParameters()}
Expand All @@ -49,20 +54,26 @@ default Map<VariableTypeInfo, TypeInfo> extractConsolidationMapping(TypeInfoFact
String.format(
"Expecting %s type params for class '%s', but got %s",
len, this.asClass().getName(), actualParams.size()));
} else if (len == 0) {
throw new IllegalStateException(
String.format(
"Base class '%s' is not a generic class", this.asClass().getName()));
}

if (len == 1) {
Map<VariableTypeInfo, TypeInfo> ownerTypeMapping;
var ownerType = this.ownerType();
if (ownerType instanceof ParameterizedTypeInfo) {
ownerTypeMapping =
((ParameterizedTypeInfo) ownerType).extractConsolidationMapping(factory);
} else {
ownerTypeMapping = Map.of();
}

if (len == 1 && ownerTypeMapping.isEmpty()) {
return Map.of((VariableTypeInfo) factory.create(typeVariables[0]), actualParams.get(0));
}

var mapping = new HashMap<VariableTypeInfo, TypeInfo>();
for (int i = 0; i < len; i++) {
mapping.put((VariableTypeInfo) factory.create(typeVariables[i]), actualParams.get(i));
}
mapping.putAll(ownerTypeMapping);
return mapping;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,118 @@
package org.mozilla.javascript.lc.type;

import org.mozilla.javascript.lc.type.impl.ClassSignatureFormatContext;
import org.mozilla.javascript.lc.type.impl.ClassNameFormatContext;

/**
* @author ZZZank
*/
public interface TypeFormatContext {
/// Full feature formatting context
///
/// | Type | Full representation | Representation using this context |
/// | - | - | - |
/// | Class | java.lang.String | java.lang.String |
/// | Nested Class | Entry (in java.util.Map) | java.util.Map$Entry |
/// | Array | java.lang.String[] | java.lang.String[] |
/// | Parameterized | java.lang.List<java.lang.String> | java.util.List<java.lang.String> |
/// | Variable | T extends java.lang.String | T extends java.lang.String |
/// | [TypeInfo#NONE] | (No standard representation) | ? |
TypeFormatContext DEFAULT = Class::getName;
/// Full feature formatting context with class name simplified
///
/// | Type | Full representation | Representation using this context |
/// | - | - | - |
/// | Class | java.lang.String | String |
/// | Nested Class | Entry (in java.util.Map) | Entry |
/// | Array | java.lang.String[] | String[] |
/// | Parameterized | java.lang.List<java.lang.String> | List\<String> |
/// | Variable | T extends java.lang.String | T extends String |
/// | [TypeInfo#NONE] | (No standard representation) | ? |
///
/// @see Class#getSimpleName()
TypeFormatContext SIMPLE = Class::getSimpleName;
TypeFormatContext CLASS_SIG = new ClassSignatureFormatContext();
/// Formatting context that formats every type as the result of `type.asClass().getName()`
///
/// | Type | Full representation | Representation using this context |
/// | - | - | - |
/// | Class | java.lang.String | java.lang.String |
/// | Nested Class | Entry (in java.util.Map) | java.util.Map$Entry |
/// | Array | java.lang.String[] | [Ljava.lang.String; |
/// | Parameterized | java.lang.List<java.lang.String> | java.util.List |
/// | Variable | T extends java.lang.String | java.lang.String |
/// | [TypeInfo#NONE] | (No standard representation) | java.lang.Object |
///
/// @see Class#getName()
TypeFormatContext CLASS_NAME = new ClassNameFormatContext();

String getClassName(Class<?> c);

default void appendSpace(StringBuilder builder) {
builder.append(' ');
/**
* Format a type and push the result to a {@link StringBuilder}.
*
* @implNote Implementations are encouraged to override {@link #append(StringBuilder, TypeInfo,
* boolean)} , instead of this method
* @param builder Formatted string of {@code type} will be pushed to this builder
* @param type The type to be formatted
*/
default void append(StringBuilder builder, TypeInfo type) {
append(builder, type, false);
}

default void formatArray(StringBuilder builder, TypeInfo arrayType) {
arrayType.getComponentType().append(this, builder);
/**
* This method is for overriding. Users are encouraged to use {@link #append(StringBuilder,
* TypeInfo)} instead of this method.
*
* @param builder Formatted string of {@code type} will be pushed to this builder
* @param type The type to be formatted
* @param isComponent {@code true} if the {@code type} is a component of another type. For
* example, {@code T} in {@code T[]}, and {@code Number} in {@code Map<K, Number>}
*/
default void append(StringBuilder builder, TypeInfo type, boolean isComponent) {
if (type == TypeInfo.NONE) {
builder.append(getFormattedNone());
} else if (type.isArray()) {
appendArray(builder, type);
} else if (type instanceof VariableTypeInfo) {
if (isComponent) {
builder.append(((VariableTypeInfo) type).name());
} else {
appendVariable(builder, (VariableTypeInfo) type);
}
} else if (type instanceof ParameterizedTypeInfo) {
appendParameterized(builder, (ParameterizedTypeInfo) type);
} else {
builder.append(type.toString(this));
}
}

default void appendArray(StringBuilder builder, TypeInfo type) {
append(builder, type.getComponentType(), true);
builder.append('[').append(']');
}

default void formatParameterized(StringBuilder builder, ParameterizedTypeInfo type) {
type.rawType().append(this, builder);
default void appendParameterized(StringBuilder builder, ParameterizedTypeInfo type) {
append(builder, type.rawType(), true);

builder.append('<');
var iterator = type.params().iterator();
if (iterator.hasNext()) {
iterator.next().append(this, builder);
builder.append('<');
append(builder, iterator.next(), true);
while (iterator.hasNext()) {
builder.append(',');
appendSpace(builder);
iterator.next().append(this, builder);
builder.append(' ');
append(builder, iterator.next(), true);
}
builder.append('>');
}
}

default void appendVariable(StringBuilder builder, VariableTypeInfo type) {
builder.append(type.name());
var mainBound = type.mainBound();
if (!mainBound.isObjectExact()) {
builder.append(" extends ");
append(builder, mainBound, true);
}
builder.append('>');
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,12 @@ default boolean shouldReplace() {
}

/**
* @see #append(TypeFormatContext, StringBuilder)
* @see #toString(TypeFormatContext)
*/
@Override
String toString();

void append(TypeFormatContext ctx, StringBuilder builder);
String toString(TypeFormatContext ctx);

/**
* @see Class#getComponentType()
Expand Down Expand Up @@ -277,10 +277,6 @@ default boolean isObjectExact() {
return false;
}

default void collectComponentClass(Consumer<Class<?>> collector) {
collector.accept(asClass());
}

/**
* @see Class#isArray()
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import java.util.function.Supplier;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.lc.type.impl.factory.NoCacheFactory;
import org.mozilla.javascript.lc.type.impl.factory.WeakReferenceFactory;

/**
Expand Down Expand Up @@ -62,14 +61,6 @@ private Object readResolve() {
}
};

/**
* TypeInfoFactory used by very few actions with the intention of not caching any used types
*
* <p>This factory does not cache {@link TypeInfo}. If the same type is passed to this factory
* multiple times, the return result may or may not be the exact same object
*/
TypeInfoFactory NO_CACHE = NoCacheFactory.INSTANCE;

TypeInfo[] EMPTY_ARRAY = new TypeInfo[0];

/// creating types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import org.mozilla.javascript.FunctionObject;
import org.mozilla.javascript.lc.type.TypeFormatContext;
import org.mozilla.javascript.lc.type.TypeInfo;
import org.mozilla.javascript.lc.type.VariableTypeInfo;

Expand Down Expand Up @@ -43,21 +41,11 @@ public int hashCode() {
return component.hashCode() + 1;
}

@Override
public void append(TypeFormatContext ctx, StringBuilder builder) {
ctx.formatArray(builder, this);
}

@Override
public TypeInfo getComponentType() {
return component;
}

@Override
public void collectComponentClass(Consumer<Class<?>> collector) {
component.collectComponentClass(collector);
}

@Override
public boolean isArray() {
return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.mozilla.javascript.lc.type.impl;

import org.mozilla.javascript.lc.type.ParameterizedTypeInfo;
import org.mozilla.javascript.lc.type.TypeFormatContext;
import org.mozilla.javascript.lc.type.TypeInfo;
import org.mozilla.javascript.lc.type.VariableTypeInfo;

/**
* @author ZZZank
*/
public class ClassNameFormatContext implements TypeFormatContext {
@Override
public String getClassName(Class<?> c) {
return c.getName();
}

@Override
public void append(StringBuilder builder, TypeInfo type) {
builder.append(type.asClass().getName());
}

@Override
public void append(StringBuilder builder, TypeInfo type, boolean isComponent) {
builder.append(type.asClass().getName());
}

@Override
public void appendParameterized(StringBuilder builder, ParameterizedTypeInfo type) {
append(builder, type.rawType());
}

@Override
public void appendVariable(StringBuilder builder, VariableTypeInfo type) {
append(builder, type.mainBound());
}

@Override
public void appendArray(StringBuilder builder, TypeInfo type) {
builder.append(type.asClass().getName());
}

@Override
public String getFormattedNone() {
return Object.class.getName();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public boolean equals(Object o) {
}

@Override
public void append(TypeFormatContext ctx, StringBuilder builder) {
builder.append(ctx.getClassName(this.type));
public String toString(TypeFormatContext ctx) {
return ctx.getClassName(this.type);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.mozilla.javascript.lc.type.impl;

import java.util.function.Consumer;
import org.mozilla.javascript.lc.type.TypeFormatContext;
import org.mozilla.javascript.lc.type.TypeInfo;

Expand Down Expand Up @@ -28,13 +27,10 @@ public String toString() {
}

@Override
public void append(TypeFormatContext ctx, StringBuilder builder) {
builder.append(ctx.getFormattedNone());
public String toString(TypeFormatContext ctx) {
return ctx.getFormattedNone();
}

@Override
public void collectComponentClass(Consumer<Class<?>> collector) {}

/** {@link Object} class is assignable from any class */
@Override
public boolean isAssignableFrom(TypeInfo another) {
Expand Down
Loading