Skip to content

Commit

Permalink
Add requiredExtensions directive, and implmnt compiler warning for name
Browse files Browse the repository at this point in the history
  • Loading branch information
LadyCailin committed Dec 20, 2018
1 parent b6ffd40 commit 16ec009
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 7 deletions.
40 changes: 40 additions & 0 deletions src/main/java/com/laytonsmith/core/MethodScriptCompiler.java
@@ -1,5 +1,6 @@
package com.laytonsmith.core; package com.laytonsmith.core;


import com.laytonsmith.PureUtilities.Common.StringUtils;
import com.laytonsmith.abstraction.Implementation; import com.laytonsmith.abstraction.Implementation;
import com.laytonsmith.annotations.breakable; import com.laytonsmith.annotations.breakable;
import com.laytonsmith.annotations.nolinking; import com.laytonsmith.annotations.nolinking;
Expand Down Expand Up @@ -37,6 +38,8 @@
import com.laytonsmith.core.exceptions.ConfigCompileGroupException; import com.laytonsmith.core.exceptions.ConfigCompileGroupException;
import com.laytonsmith.core.exceptions.ConfigRuntimeException; import com.laytonsmith.core.exceptions.ConfigRuntimeException;
import com.laytonsmith.core.exceptions.ProgramFlowManipulationException; 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.ArrayHandling;
import com.laytonsmith.core.functions.Compiler; import com.laytonsmith.core.functions.Compiler;
import com.laytonsmith.core.functions.DataHandling; import com.laytonsmith.core.functions.DataHandling;
Expand All @@ -52,6 +55,7 @@
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.EmptyStackException; import java.util.EmptyStackException;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
Expand Down Expand Up @@ -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; return tokenList;
} }


Expand Down
55 changes: 51 additions & 4 deletions src/main/java/com/laytonsmith/core/compiler/FileOptions.java
Expand Up @@ -7,7 +7,9 @@
import com.laytonsmith.core.Prefs; import com.laytonsmith.core.Prefs;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
Expand All @@ -27,15 +29,17 @@ public class FileOptions {
private final String author; private final String author;
private final String created; private final String created;
private final String description; private final String description;
private final Set<String> requiredExtensions;
//TODO: Make this non-public once this is all finished. //TODO: Make this non-public once this is all finished.


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


private String getDefault(Map<String, String> map, String key, String defaultIfNone) { private String getDefault(Map<String, String> map, String key, String defaultIfNone) {
Expand Down Expand Up @@ -63,6 +67,10 @@ private List<String> parseList(String list) {
return l; 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) { private <T extends Enum<T>> Set<T> parseEnumSet(String list, Class<T> type) {
EnumSet<T> set = EnumSet.noneOf(type); EnumSet<T> set = EnumSet.noneOf(type);
List<String> sList = parseList(list); List<String> sList = parseList(list);
Expand Down Expand Up @@ -92,26 +100,65 @@ public boolean isStrict() {
} }
} }


/**
* Returns true if the specified warning has been suppressed.
* @param warning
* @return
*/
public boolean isWarningSuppressed(SuppressWarnings warning) { public boolean isWarningSuppressed(SuppressWarnings warning) {
return suppressWarnings.contains(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() { public String getName() {
return name; return name;
} }


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


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


/**
* Gets the file description. This is not used programmatically, and is only for reference.
* @return
*/
public String getDescription() { public String getDescription() {
return description; 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 @Override
public String toString() { public String toString() {
return (strict ? "Strict Mode on" : "") + "\n" return (strict ? "Strict Mode on" : "") + "\n"
Expand Down
15 changes: 12 additions & 3 deletions src/main/resources/docs/File_Options
Expand Up @@ -47,8 +47,11 @@ types.


== name == == name ==


This should be the name of the file. If it exists, and the file name does not match this value, the compilation will This should be the name of the file. If it exists, and the file name does not match this value, the a compiler warning
fail. 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 == == author ==


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


A description of this file. This value is not used by the compiler, but is perhaps useful information for future 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.