Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
175 changes: 16 additions & 159 deletions runtime/src/main/java/dev/ionfusion/runtime/base/SourceName.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import static java.util.Objects.requireNonNull;

import dev.ionfusion.runtime.base.SourceNameImpl.ModuleSourceName;
import dev.ionfusion.runtime.base.SourceNameImpl.ResourceSourceName;
import java.io.File;
import java.net.URI;
import java.net.URL;
Expand All @@ -16,56 +18,23 @@
* The primary purpose of this class is to display a suitable message fragment
* for error reporting to users.
*/
public class SourceName
implements ResourceDescriptor
public interface SourceName
extends ResourceDescriptor
{
/**
* The standard extension for Fusion source code files.
*/
public static final String FUSION_SOURCE_EXTENSION = ".fusion";

private final String myDisplay;


private SourceName(String display)
{
myDisplay = display;
}
String FUSION_SOURCE_EXTENSION = ".fusion";


/**
* Returns the human-readable source name, for display in messages.
*
* @return the displayable name of this source
*/
@Override
public String display()
{
return myDisplay;
}

/**
* Returns the resource identifier for this source if one exists.
*
* @return can be null.
*/
@Override
public ResourceIdentifier getResourceId()
{
return null;
}

/**
* Returns the absolute path of the source file if one is known.
* This is the case for instances created by {@link #forFile(File)} or
* {@link #forFile(String)}.
*
* @return null if this source is not an actual file.
*/
public Path getPath()
{
return null;
}
Path getPath();

/**
* Returns a URI for the source. The protocol can vary; at least {@code file}
Expand All @@ -74,130 +43,18 @@ public Path getPath()
*
* @return null if this source cannot be identified as a URI.
*/
public URI getUri()
{
return null;
}
URI getUri();


/**
* It is not guaranteed that the module declaration is the only content of
* the file or URL.
* The resource could be a script with several modules inside, and modules
* The resource could be a script with several modules inside, and module
* declarations will eventually nest.
*
* @return the module associated with this source, if any.
*/
public ModuleIdentity getModuleIdentity()
{
return null;
}


/**
* Returns a view of this object suitable for debugging.
* For displaying messages to users, use {@link #display()} instead.
*/
@Override
public String toString()
{
return myDisplay;
}


public boolean equals(SourceName other)
{
return (other != null && myDisplay.equals(other.myDisplay));
}

@Override
public boolean equals(Object other)
{
return (other instanceof SourceName && equals((SourceName) other));
}

private static final int HASH_SEED = SourceName.class.hashCode();

@Override
public int hashCode()
{
int result = HASH_SEED + myDisplay.hashCode();
result ^= (result << 29) ^ (result >> 3);
return result;
}


/**
* Compares sources by their {@linkplain #display() display form}.
*
* @param o1 the first object to be compared.
* @param o2 the second object to be compared.
*
* @return a negative integer, zero, or a positive integer as the first argument is
* less than, equal to, or greater than the second.
*/
public static int compareByDisplay(SourceName o1, SourceName o2)
{
return o1.display().compareTo(o2.display());
}


//=========================================================================


private static class ResourceSourceName
extends SourceName
{
private final ResourceIdentifier myResource;

private ResourceSourceName(String display, ResourceIdentifier resource)
{
super(display);
myResource = resource;
}

private ResourceSourceName(ResourceIdentifier resource)
{
this(resource.toString(), resource);
}

@Override
public ResourceIdentifier getResourceId()
{
return myResource;
}

@Override
public Path getPath()
{
return myResource.getPath();
}

@Override
public URI getUri()
{
return myResource.getUri();
}
}


//=========================================================================


private static class ModuleSourceName
extends ResourceSourceName
{
private final ModuleIdentity myId;

ModuleSourceName(ResourceIdentifier rsrc, ModuleIdentity id)
{
super(id + " (at " + rsrc.toString() + ")", rsrc);
myId = id;
}

@Override
public ModuleIdentity getModuleIdentity() { return myId; }
}
ModuleIdentity getModuleIdentity();


//=========================================================================
Expand All @@ -210,12 +67,12 @@ private static class ModuleSourceName
*
* @return a new {@link SourceName} instance
*/
public static SourceName forDisplay(String display)
static SourceName forDisplay(String display)
{
if (display.isEmpty()) {
throw new IllegalArgumentException("display must not be empty");
}
return new SourceName(display);
return new SourceNameImpl(display);
}


Expand All @@ -228,7 +85,7 @@ public static SourceName forDisplay(String display)
*
* @see #forFile(File)
*/
public static SourceName forFile(String path)
static SourceName forFile(String path)
{
ResourceIdentifier rsrc = ResourceIdentifier.forFile(path);
return new ResourceSourceName(rsrc);
Expand All @@ -244,7 +101,7 @@ public static SourceName forFile(String path)
*
* @see #forFile(String)
*/
public static SourceName forFile(File path)
static SourceName forFile(File path)
{
ResourceIdentifier rsrc = ResourceIdentifier.forFile(path);
return new ResourceSourceName(rsrc);
Expand All @@ -256,7 +113,7 @@ public static SourceName forFile(File path)
* @param sourceFile must not be null.
* @return a new {@link SourceName}.
*/
public static SourceName forModule(ModuleIdentity id, File sourceFile)
static SourceName forModule(ModuleIdentity id, File sourceFile)
{
requireNonNull(id, "id must not be null");
ResourceIdentifier rsrc = ResourceIdentifier.forFile(sourceFile);
Expand All @@ -269,7 +126,7 @@ public static SourceName forModule(ModuleIdentity id, File sourceFile)
* @param url must not be null.
* @return a new {@link SourceName}.
*/
public static SourceName forUrl(ModuleIdentity id, URL url)
static SourceName forUrl(ModuleIdentity id, URL url)
{
requireNonNull(id, "id must not be null");
ResourceIdentifier rsrc = ResourceIdentifier.forUrl(url);
Expand All @@ -285,7 +142,7 @@ public static SourceName forUrl(ModuleIdentity id, URL url)
*
* @return a new {@link SourceName}.
*/
public static SourceName forResource(ResourceIdentifier resource, ModuleIdentity id)
static SourceName forResource(ResourceIdentifier resource, ModuleIdentity id)
{
requireNonNull(resource, "resource must not be null");
if (id == null) return new ResourceSourceName(resource);
Expand Down
135 changes: 135 additions & 0 deletions runtime/src/main/java/dev/ionfusion/runtime/base/SourceNameImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Copyright Ion Fusion contributors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package dev.ionfusion.runtime.base;

import java.net.URI;
import java.nio.file.Path;

class SourceNameImpl
implements SourceName
{
private final String myDisplay;


SourceNameImpl(String display)
{
myDisplay = display;
}


@Override
public String display()
{
return myDisplay;
}

@Override
public ResourceIdentifier getResourceId()
{
return null;
}

@Override
public Path getPath()
{
return null;
}

@Override
public URI getUri()
{
return null;
}

@Override
public ModuleIdentity getModuleIdentity()
{
return null;
}

@Override
public String toString()
{
return myDisplay;
}


public boolean equals(SourceName other)
{
return (other != null && myDisplay.equals(other.display()));
}

@Override
public boolean equals(Object other)
{
return (other instanceof SourceName && equals((SourceName) other));
}


private static final int HASH_SEED = SourceNameImpl.class.hashCode();

@Override
public int hashCode()
{
int result = HASH_SEED + myDisplay.hashCode();
result ^= (result << 29) ^ (result >> 3);
return result;
}


//=========================================================================
// Subclasses that add ResourceIdentifier and ModuleIdentity
// This complexity only serves to reduce memory use.

static class ResourceSourceName
extends SourceNameImpl
{
private final ResourceIdentifier myResource;

private ResourceSourceName(String display, ResourceIdentifier resource)
{
super(display);
myResource = resource;
}

ResourceSourceName(ResourceIdentifier resource)
{
this(resource.toString(), resource);
}

@Override
public ResourceIdentifier getResourceId()
{
return myResource;
}

@Override
public Path getPath()
{
return myResource.getPath();
}

@Override
public URI getUri()
{
return myResource.getUri();
}
}


static class ModuleSourceName
extends ResourceSourceName
{
private final ModuleIdentity myId;

ModuleSourceName(ResourceIdentifier rsrc, ModuleIdentity id)
{
super(id + " (at " + rsrc.toString() + ")", rsrc);
myId = id;
}

@Override
public ModuleIdentity getModuleIdentity() { return myId; }
}
}
Loading