Skip to content

Commit

Permalink
Implement package system.
Browse files Browse the repository at this point in the history
  • Loading branch information
dim-s committed Feb 5, 2017
1 parent 8b437e0 commit 45f6ce8
Show file tree
Hide file tree
Showing 26 changed files with 458 additions and 9 deletions.
Expand Up @@ -24,6 +24,11 @@ public Status getStatus() {
return Status.EXPERIMENTAL;
}

@Override
public String[] getPackageNames() {
return new String[] { "compress" };
}

@Override
public void onRegister(CompileScope scope) {
registerWrapperClass(scope, ArchiveEntry.class, PArchiveEntry.class);
Expand Down
Expand Up @@ -11,9 +11,12 @@
import org.develnext.jphp.core.tokenizer.token.expr.operator.AssignExprToken;
import org.develnext.jphp.core.tokenizer.token.expr.value.*;
import org.develnext.jphp.core.tokenizer.token.stmt.*;
import php.runtime.common.LangMode;
import php.runtime.common.Messages;
import php.runtime.common.Modifier;
import org.develnext.jphp.core.common.Separator;
import php.runtime.common.StringUtils;
import php.runtime.env.Package;
import php.runtime.exceptions.ParseException;
import php.runtime.exceptions.support.ErrorType;
import php.runtime.reflection.ClassEntity;
Expand Down Expand Up @@ -382,6 +385,28 @@ protected void processBody(ClassStmtToken result, ListIterator<Token> iterator){
one.setClazz(result);
one.setDocComment(lastComment);

if (analyzer.getEnvironment() != null && analyzer.getEnvironment().scope.getLangMode() == LangMode.MODERN) {
for (ConstStmtToken.Item item : one.items) {
if (item.getFulledName().equals("__PACKAGE__")) {
if (item.value == null || !item.value.isConstantly() || !item.value.isSingle() || !(item.value.getSingle() instanceof StringExprToken)) {
analyzer.getEnvironment().error(result.toTraceInfo(analyzer.getContext()),
ErrorType.E_ERROR, Messages.ERR_PACKAGE_CONSTANT_MUST_BE_NON_EMPTY_STRING, result.getName().getName()
);
return;
}

String value = ((StringExprToken) item.value.getSingle()).getValue();

if (value.trim().isEmpty()) {
analyzer.getEnvironment().error(result.toTraceInfo(analyzer.getContext()),
ErrorType.E_ERROR, Messages.ERR_PACKAGE_CONSTANT_MUST_BE_NON_EMPTY_STRING, result.getName().getName()
);
return;
}
}
}
}

lastComment = null;

constants.add(one);
Expand Down
Expand Up @@ -10,6 +10,12 @@
import org.develnext.jphp.core.tokenizer.token.expr.value.NameToken;
import org.develnext.jphp.core.tokenizer.token.stmt.*;
import org.develnext.jphp.core.syntax.SyntaxAnalyzer;
import php.runtime.Information;
import php.runtime.common.LangMode;
import php.runtime.common.StringUtils;
import php.runtime.env.Environment;
import php.runtime.env.Package;
import php.runtime.env.PackageManager;

import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -30,6 +36,14 @@ public void parseBody(NamespaceUseStmtToken use, Token current, ListIterator<Tok
boolean first = true;
NamespaceUseStmtToken.UseType useType = prefixUseType;


Environment environment = this.analyzer.getEnvironment();

PackageManager packageManager = null;
if (environment != null) {
packageManager = environment.getPackageManager();
}

do {
Token next = nextToken(iterator);

Expand Down Expand Up @@ -97,7 +111,46 @@ public void parseBody(NamespaceUseStmtToken use, Token current, ListIterator<Tok
}

NamespaceStmtToken namespace = analyzer.getNamespace();
namespace.getUses().add(use);

if (analyzer.getEnvironment() != null && analyzer.getEnvironment().scope.getLangMode() == LangMode.MODERN) {
if (packageManager != null && packageManager.has(use.getName().toName())) {
Package aPackage = packageManager.fetch(use.getName().toName());

for (String cls : aPackage.getClasses()) {
FulledNameToken nameToken = FulledNameToken.valueOf(StringUtils.split(cls, Information.NAMESPACE_SEP_CHAR));

NamespaceUseStmtToken useStmtToken = new NamespaceUseStmtToken(TokenMeta.of(cls, use));
useStmtToken.setName(nameToken);
useStmtToken.setUseType(NamespaceUseStmtToken.UseType.CLASS);

namespace.getUses().add(useStmtToken);
}

for (String s : aPackage.getFunctions()) {
FulledNameToken nameToken = FulledNameToken.valueOf(StringUtils.split(s, Information.NAMESPACE_SEP_CHAR));

NamespaceUseStmtToken useStmtToken = new NamespaceUseStmtToken(TokenMeta.of(s, use));
useStmtToken.setName(nameToken);
useStmtToken.setUseType(NamespaceUseStmtToken.UseType.FUNCTION);

namespace.getUses().add(useStmtToken);
}

for (String s : aPackage.getConstants()) {
FulledNameToken nameToken = FulledNameToken.valueOf(StringUtils.split(s, Information.NAMESPACE_SEP_CHAR));

NamespaceUseStmtToken useStmtToken = new NamespaceUseStmtToken(TokenMeta.of(s, use));
useStmtToken.setName(nameToken);
useStmtToken.setUseType(NamespaceUseStmtToken.UseType.CONSTANT);

namespace.getUses().add(useStmtToken);
}
} else {
namespace.getUses().add(use);
}
} else {
namespace.getUses().add(use);
}

if (token instanceof CommaToken){
use = new NamespaceUseStmtToken(current.getMeta());
Expand Down
Expand Up @@ -16,7 +16,12 @@ public class HttpClientExtension extends Extension {

@Override
public Status getStatus() {
return Status.EXPERIMENTAL;
return Status.STABLE;
}

@Override
public String[] getPackageNames() {
return new String[] { "http", "httpclient" };
}

@Override
Expand Down
Expand Up @@ -10,6 +10,11 @@ public Status getStatus() {
return Status.STABLE;
}

@Override
public String[] getPackageNames() {
return new String[] { "std", "json" };
}

@Override
public void onRegister(CompileScope scope) {
registerClass(scope, JsonSerializable.class);
Expand Down
Expand Up @@ -16,7 +16,12 @@ public class JsoupExtension extends Extension {

@Override
public Status getStatus() {
return Status.BETA;
return Status.STABLE;
}

@Override
public String[] getPackageNames() {
return new String[] { "jsoup" };
}

@Override
Expand Down
Expand Up @@ -14,6 +14,11 @@ public Status getStatus() {
return Status.EXPERIMENTAL;
}

@Override
public String[] getPackageNames() {
return new String[] { "mail" };
}

@Override
public void onRegister(CompileScope scope) {
registerMemoryOperation(InternetAddressMemoryOperation.class);
Expand Down
11 changes: 11 additions & 0 deletions jphp-runtime/src/main/resources/JPHP-INF/sdk/.functions.php
Expand Up @@ -11,4 +11,15 @@
function flow($iterator)
{
return Flow::of($iterator);
}

/**
* @param string $name
* @param array $classes
* @param array $functions
* @param array $constants
* @return bool
*/
function define_package($name, array $classes, array $functions = [], array $constants = [])
{
}
Expand Up @@ -150,6 +150,29 @@ public function findModule($path)
{
}

/**
* @return string[]
*/
public function getPackages()
{
}

/**
* @param string $name
* @return bool
*/
public function hasPackage($name)
{
}

/**
* @param string $name
* @return array like [classes => [], functions => [], constants => []]
*/
public function getPackage($name)
{
}

/**
* Get environment of current execution
* --RU--
Expand Down
Expand Up @@ -36,4 +36,10 @@ public function call(array $variables = null) { }
* @throws
*/
public function dump($target, $saveDebugInfo = true) { }

/**
* @param string $name
* @param array $classes
*/
public static function package($name, array $classes) { }
}
1 change: 1 addition & 0 deletions jphp-runtime/src/php/runtime/common/Messages.java
Expand Up @@ -81,6 +81,7 @@ private Messages(){}
public final static Item ERR_CANNOT_INHERIT_OVERRIDE_CONSTANT = new Item("Cannot inherit previously-inherited or override constant %s from interface %s");

public final static Item ERR_INTERFACE_MAY_NOT_INCLUDE_VARS = new Item("Interfaces may not include member variables");
public final static Item ERR_PACKAGE_CONSTANT_MUST_BE_NON_EMPTY_STRING = new Item("Class constant %s::__PACKAGE__ must be a non-empty string");

public final static Item ERR_CANNOT_USE_SYSTEM_CLASS = new Item("Cannot use system class/interface %s for %s");

Expand Down
51 changes: 49 additions & 2 deletions jphp-runtime/src/php/runtime/env/Environment.java
Expand Up @@ -16,6 +16,7 @@
import php.runtime.ext.java.JavaReflection;
import php.runtime.ext.support.Extension;
import php.runtime.ext.support.compile.CompileConstant;
import php.runtime.ext.support.compile.CompileFunctionSpec;
import php.runtime.invoke.Invoker;
import php.runtime.invoke.ObjectInvokeHelper;
import php.runtime.lang.*;
Expand Down Expand Up @@ -97,6 +98,7 @@ public class Environment {
protected final Map<String, ConstantEntity> constantMap = new LinkedHashMap<String, ConstantEntity>();

protected final ModuleManager moduleManager;
protected final PackageManager packageManager;

protected static final ThreadLocal<Environment> environment = new ThreadLocal<Environment>();

Expand Down Expand Up @@ -178,6 +180,7 @@ public Environment(Environment parent, OutputStream output) {
constantMap.putAll(parent.constantMap);

moduleManager.apply(parent.moduleManager);
packageManager.apply(parent.packageManager);
}

public Environment(CompileScope scope, OutputStream output) {
Expand All @@ -194,6 +197,7 @@ public Environment(CompileScope scope, OutputStream output) {
}

this.moduleManager = new ModuleManager(this);
this.packageManager = new PackageManager();

this.outputBuffers = new Stack<OutputBuffer>();

Expand Down Expand Up @@ -246,9 +250,42 @@ public boolean onFatal(ErrorException error) {
if (invoker != null)
this.defaultAutoLoader = new SplClassLoader(invoker, splAutoloader);

for(Extension e: scope.extensions.values())
for(Extension e: scope.extensions.values()) {
e.onLoad(this);

if (scope.getLangMode() == LangMode.MODERN) {
String[] packageNames = e.getPackageNames();

if (packageNames != null) {

Package aPackage = null;
for (String packageName : packageNames) {
if (aPackage == null) {
aPackage = getPackageManager().fetch(packageName);

for (Class<?> aClass : e.getClasses().values()) {
aPackage.addClass(ReflectionUtils.getClassName(aClass));
}

for (CompileFunctionSpec functionSpec : e.getFunctions().values()) {
aPackage.addFunction(functionSpec.getName());
}

for (CompileConstant constant : e.getConstants().values()) {
aPackage.addConstant(constant.name);
}
} else {
Package aPackage2 = getPackageManager().fetch(packageName);

for (String s : aPackage.getClasses()) aPackage2.addClass(s);
for (String s : aPackage.getFunctions()) aPackage2.addFunction(s);
for (String s : aPackage.getConstants()) aPackage2.addConstant(s);
}
}
}
}
}

environment.set(this);
}

Expand Down Expand Up @@ -400,6 +437,10 @@ public ModuleManager getModuleManager() {
return moduleManager;
}

public PackageManager getPackageManager() {
return packageManager;
}

public CompileScope getScope() {
return scope;
}
Expand Down Expand Up @@ -1134,12 +1175,14 @@ public void registerModule(ModuleEntity module) {

public void registerModule(ModuleEntity module, boolean ignoreErrors) {
for(ClassEntity entity : module.getClasses()) {
if (entity.isStatic()){
if (entity.isStatic()) {
entity.setModule(module);

if (classMap.put(entity.getLowerName(), entity) != null && !ignoreErrors) {
error(entity.getTrace(), Messages.ERR_CANNOT_REDECLARE_CLASS.fetch(entity.getName()));
}

entity.register(this);
}
}

Expand All @@ -1150,6 +1193,8 @@ public void registerModule(ModuleEntity module, boolean ignoreErrors) {
if (functionMap.put(entity.getLowerName(), entity) != null && !ignoreErrors) {
error(entity.getTrace(), Messages.ERR_CANNOT_REDECLARE_FUNCTION.fetch(entity.getName()));
}

entity.register(this);
}
}

Expand All @@ -1159,6 +1204,8 @@ public void registerModule(ModuleEntity module, boolean ignoreErrors) {
if (constantMap.put(entity.getLowerName(), entity) != null && !ignoreErrors) {
error(entity.getTrace(), Messages.ERR_CANNOT_REDECLARE_CONSTANT.fetch(entity.getName()));
}

entity.register(this);
}
}

Expand Down

0 comments on commit 45f6ce8

Please sign in to comment.