Permalink
Browse files

Add requiredExtensions directive, and implmnt compiler warning for name

  • Loading branch information...
LadyCailin committed Dec 20, 2018
1 parent b6ffd40 commit 16ec009935d08e62f5c5264d6b202adddb8b5df0
@@ -1,5 +1,6 @@
package com.laytonsmith.core;

import com.laytonsmith.PureUtilities.Common.StringUtils;
import com.laytonsmith.abstraction.Implementation;
import com.laytonsmith.annotations.breakable;
import com.laytonsmith.annotations.nolinking;
@@ -37,6 +38,8 @@
import com.laytonsmith.core.exceptions.ConfigCompileGroupException;
import com.laytonsmith.core.exceptions.ConfigRuntimeException;
import com.laytonsmith.core.exceptions.ProgramFlowManipulationException;
import com.laytonsmith.core.extensions.ExtensionManager;
import com.laytonsmith.core.extensions.ExtensionTracker;
import com.laytonsmith.core.functions.ArrayHandling;
import com.laytonsmith.core.functions.Compiler;
import com.laytonsmith.core.functions.DataHandling;
@@ -52,6 +55,7 @@
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.EmptyStackException;
import java.util.EnumSet;
import java.util.HashMap;
@@ -898,6 +902,42 @@ public static TokenStream lex(String script, File file, boolean inPureMScript, b
}
}

{
// Filename check
String fileName = tokenList.getFileOptions().getName();
if(!fileName.isEmpty()) {
if(!file.getAbsolutePath().replace("\\", "/").endsWith(fileName.replace("\\", "/"))) {
CHLog.GetLogger().w(CHLog.Tags.COMPILER, file + " has the wrong file name in the file options ("
+ fileName + ")",
new Target(0, file, 0));
}
}
}
{
// Required extension check
// TODO: Add support for specifying required versions
Collection<ExtensionTracker> exts = ExtensionManager.getTrackers().values();
Set<String> notFound = new HashSet<>();
for(String extension : tokenList.getFileOptions().getRequiredExtensions()) {
boolean found = false;
for(ExtensionTracker t : exts) {
if(t.getIdentifier().equalsIgnoreCase(extension)) {
found = true;
break;
}
}
if(!found) {
notFound.add(extension);
}
}
if(!notFound.isEmpty()) {
throw new ConfigCompileException("Could not compile file, because one or more required"
+ " extensions are not loaded: " + StringUtils.Join(notFound, ", ")
+ ". These extensions must be provided before compilation can continue.",
new Target(0, file, 0));
}
}

return tokenList;
}

@@ -7,7 +7,9 @@
import com.laytonsmith.core.Prefs;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -27,15 +29,17 @@
private final String author;
private final String created;
private final String description;
private final Set<String> requiredExtensions;
//TODO: Make this non-public once this is all finished.

public FileOptions(Map<String, String> parsedOptions) {
strict = parseBoolean(getDefault(parsedOptions, "strict", null));
suppressWarnings = parseEnumSet(getDefault(parsedOptions, "suppresswarnings", ""), SuppressWarnings.class);
name = getDefault(parsedOptions, "name", "");
author = getDefault(parsedOptions, "author", "");
created = getDefault(parsedOptions, "created", "");
description = getDefault(parsedOptions, "description", null);
name = getDefault(parsedOptions, "name", "").trim();
author = getDefault(parsedOptions, "author", "").trim();
created = getDefault(parsedOptions, "created", "").trim();
description = getDefault(parsedOptions, "description", "").trim();
requiredExtensions = Collections.unmodifiableSet(parseSet(getDefault(parsedOptions, "requiredextensions", "")));
}

private String getDefault(Map<String, String> map, String key, String defaultIfNone) {
@@ -63,6 +67,10 @@ private Boolean parseBoolean(String bool) {
return l;
}

private Set<String> parseSet(String list) {
return new HashSet<>(parseList(list));
}

private <T extends Enum<T>> Set<T> parseEnumSet(String list, Class<T> type) {
EnumSet<T> set = EnumSet.noneOf(type);
List<String> sList = parseList(list);
@@ -92,26 +100,65 @@ public boolean isStrict() {
}
}

/**
* Returns true if the specified warning has been suppressed.
* @param warning
* @return
*/
public boolean isWarningSuppressed(SuppressWarnings warning) {
return suppressWarnings.contains(warning);
}

/**
* Gets the file name. If the actual file name and this value do not match, this is a compiler warning. The default
* is an empty string, which should suppress the warning.
* @return
*/
public String getName() {
return name;
}

/**
* Gets the file author(s). This is not used programmatically, and is only for reference.
* @return
*/
public String getAuthor() {
return author;
}

/**
* Gets the file creation date. This is not used programmatically, and is only for reference.
* @return
*/
public String getCreated() {
return created;
}

/**
* Gets the file description. This is not used programmatically, and is only for reference.
* @return
*/
public String getDescription() {
return description;
}

/**
* Returns whether or not this file has required extensions.
* @return
*/
public boolean requiresExtensions() {
return !requiredExtensions.isEmpty();
}

/**
* Returns the list of required extensions for this file. It should be a compile error if the file requires an
* extension, but the extension is not present.
* @return
*/
public Set<String> getRequiredExtensions() {
return requiredExtensions;
}

@Override
public String toString() {
return (strict ? "Strict Mode on" : "") + "\n"
@@ -47,8 +47,11 @@ types.

== name ==

This should be the name of the file. If it exists, and the file name does not match this value, the compilation will
fail.
This should be the name of the file. If it exists, and the file name does not match this value, the a compiler warning
will be issued. The name must simply match the end of the actual file path, so providing a partial path, just the file
name, the path within the project, or the absolute path are all acceptable. It is recommended that you do not provide
the absolute path however, or the files cannot be easily moved. Both forward and backward slashes are accepted, and
spaces in file paths are allowed.

== author ==

@@ -63,4 +66,10 @@ readers of the script. This will eventually be available in the reflection infor
== description ==

A description of this file. This value is not used by the compiler, but is perhaps useful information for future
readers of the script. This will eventually be available in the reflection information.
readers of the script. This will eventually be available in the reflection information.

== requiredExtensions ==

A comma separated list of extensions that must be loaded in order to compile this file. While it is possible to be
more granular by using {{function|function_exists}} and {{function|event_exists}}, if the file cannot be useful without
a given extension, this directive is preferred.

0 comments on commit 16ec009

Please sign in to comment.