Skip to content

Commit

Permalink
Improvements for ImportStatement
Browse files Browse the repository at this point in the history
  • Loading branch information
nilproject committed Mar 3, 2020
1 parent 40770e6 commit 68e7213
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 35 deletions.
2 changes: 1 addition & 1 deletion NiL.JS/Core/JSObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ public sealed override void Assign(JSValue value)
if ((_attributes & JSValueAttributesInternal.ReadOnly) == 0)
{
if (this is GlobalObject)
ExceptionHelper.Throw(new NiL.JS.BaseLibrary.ReferenceError("Invalid left-hand side"));
ExceptionHelper.Throw(new ReferenceError("Invalid left-hand side"));
throw new InvalidOperationException("Try to assign to a non-primitive value");
}
}
Expand Down
10 changes: 5 additions & 5 deletions NiL.JS/Core/VariableDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,20 +121,20 @@ private JSValue deepGet(Context context, bool forWrite, int depth)

internal VariableDescriptor(string name, int definitionScopeLevel)
{
this.isDefined = true;
isDefined = true;
this.definitionScopeLevel = definitionScopeLevel;
this.name = name;
this.references = new List<VariableReference>();
references = new List<VariableReference>();
}

internal VariableDescriptor(VariableReference proto, int definitionDepth)
{
if (proto._descriptor != null)
throw new ArgumentException("proto");

this.definitionScopeLevel = definitionDepth;
this.name = proto.Name;
this.references = new List<VariableReference>() { proto };
definitionScopeLevel = definitionDepth;
name = proto.Name;
references = new List<VariableReference>() { proto };
proto._descriptor = this;
}

Expand Down
2 changes: 1 addition & 1 deletion NiL.JS/Expressions/AssignmentOperatorCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public override bool Build(ref CodeNode _this, int expressionDepth, Dictionary<s

var res = _left.Build(ref _this, expressionDepth, variables, codeContext | CodeContext.InExpression, message, stats, opts);
if (!res && _left is Variable)
(_left as Variable)._ForceThrow = true;
(_left as Variable)._forceThrow = true;
return res;
}
}
Expand Down
2 changes: 1 addition & 1 deletion NiL.JS/Expressions/Delete.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public override bool Build(ref CodeNode _this, int expressionDepth, Dictionary<s
{
if ((codeContext & CodeContext.Strict) != 0)
ExceptionHelper.Throw(new SyntaxError("Can not delete variable in strict mode"));
(_left as Variable)._SuspendThrow = true;
(_left as Variable)._suspendThrow = true;
}
var gme = _left as Property;
if (gme != null)
Expand Down
2 changes: 1 addition & 1 deletion NiL.JS/Expressions/TypeOf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public override bool Build(ref CodeNode _this, int expressionDepth, Dictionary<s
{
base.Build(ref _this, expressionDepth, variables, codeContext, message, stats, opts);
if (_left is Variable)
(_left as Variable)._SuspendThrow = true;
(_left as Variable)._suspendThrow = true;
return false;
}

Expand Down
17 changes: 8 additions & 9 deletions NiL.JS/Expressions/Variable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ public override JSValue Evaluate(Context context)
#endif
public class Variable : VariableReference
{
private string _variableName;
internal bool _SuspendThrow;
internal bool _ForceThrow;
internal string _variableName;
internal bool _suspendThrow;
internal bool _forceThrow;

public override string Name { get { return _variableName; } }

Expand All @@ -62,8 +62,7 @@ protected internal override bool ContextIndependent

internal Variable(string name, int scopeLevel)
{
int fake = 0;
if (!Parser.ValidateName(name, fake, true, true, false))
if (!Parser.ValidateName(name, 0, true, true, false))
throw new ArgumentException("Invalid variable name");

ScopeLevel = scopeLevel;
Expand All @@ -74,9 +73,9 @@ internal protected override JSValue EvaluateForWrite(Context context)
{
var result = _descriptor.Get(context, true, _scopeLevel);

if (context._strict || _ForceThrow)
if (context._strict || _forceThrow)
{
if (result._valueType < JSValueType.Undefined && (!_SuspendThrow || _ForceThrow))
if (result._valueType < JSValueType.Undefined && (!_suspendThrow || _forceThrow))
{
if ((_codeContext & CodeContext.InEval) != 0)
{
Expand Down Expand Up @@ -105,7 +104,7 @@ public override JSValue Evaluate(Context context)
{
case JSValueType.NotExists:
{
if (!_SuspendThrow)
if (!_suspendThrow)
{
if ((_codeContext & CodeContext.InEval) != 0)
{
Expand Down Expand Up @@ -183,7 +182,7 @@ public override bool Build(ref CodeNode _this, int expressionDepth, Dictionary<s
desc.definitionScopeLevel = -Math.Abs(desc.definitionScopeLevel);
}

_ForceThrow |= desc.lexicalScope; // ����� TDZ
_forceThrow |= desc.lexicalScope;

if (expressionDepth >= 0 && expressionDepth < 2 && desc.IsDefined && !desc.lexicalScope && (opts & Options.SuppressUselessExpressionsElimination) == 0)
{
Expand Down
2 changes: 1 addition & 1 deletion NiL.JS/Properties/InternalInfo.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
internal static class InternalInfo
{
internal const string Version = "2.5.1419";
internal const string Version = "2.5.1428";
}
66 changes: 51 additions & 15 deletions NiL.JS/Statements/ImportStatement.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using NiL.JS.Backward;
using NiL.JS.Core;
using NiL.JS.Expressions;
using System;
using System.Collections.Generic;
using System.Text;
Expand All @@ -8,10 +9,10 @@ namespace NiL.JS.Statements
{
public sealed class ImportStatement : CodeNode
{
private readonly List<KeyValuePair<string, string>> _map = new List<KeyValuePair<string, string>>();
private readonly List<KeyValuePair<string, Variable>> _map = new List<KeyValuePair<string, Variable>>();
private string _moduleName;

public IList<KeyValuePair<string, string>> ImportMap => _map.AsReadOnly();
public IList<KeyValuePair<string, Variable>> ImportMap => _map.AsReadOnly();
public string SourceModuleName => _moduleName;

internal static CodeNode Parse(ParseInfo state, ref int index)
Expand All @@ -30,7 +31,13 @@ internal static CodeNode Parse(ParseInfo state, ref int index)
if (Parser.ValidateName(state.Code, ref index))
{
var defaultAlias = state.Code.Substring(start, index - start);
result._map.Add(new KeyValuePair<string, string>("", defaultAlias));
result._map.Add(new KeyValuePair<string, Variable>(
string.Empty,
new Variable(defaultAlias, state.lexicalScopeLevel)
{
Position = start,
Length = defaultAlias.Length
}));

onlyDefault = true;
Tools.SkipSpaces(state.Code, ref index);
Expand All @@ -48,21 +55,39 @@ internal static CodeNode Parse(ParseInfo state, ref int index)
{
index++;
Tools.SkipSpaces(state.Code, ref index);

var alias = parseAlias(state.Code, ref index);
if (alias == null)
ExceptionHelper.ThrowSyntaxError("Expected identifier", state.Code, index);
result._map.Add(new KeyValuePair<string, string>("*", alias));

var aliasVariable = new Variable(alias, state.lexicalScopeLevel)
{
Position = index - alias.Length - 1,
Length = alias.Length
};
result._map.Add(new KeyValuePair<string, Variable>("*", aliasVariable));
}
else if (state.Code[index] == '{')
{
parseImportMap(result, state.Code, ref index);
parseImportMap(result, state.Code, ref index, state);
}
else
{
ExceptionHelper.ThrowSyntaxError(Strings.UnexpectedToken, state.Code, index);
}
}

for (var i = 0; i < result._map.Count; i++)
{
state.Variables.Add(new VariableDescriptor(
result._map[i].Value,
state.lexicalScopeLevel)
{
lexicalScope = true,
isReadOnly = true
});
}

Tools.SkipSpaces(state.Code, ref index);

if (!Parser.Validate(state.Code, "from", ref index))
Expand All @@ -81,7 +106,7 @@ internal static CodeNode Parse(ParseInfo state, ref int index)
return result;
}

private static void parseImportMap(ImportStatement import, string code, ref int index)
private static void parseImportMap(ImportStatement import, string code, ref int index, ParseInfo state)
{
index++;
Tools.SkipSpaces(code, ref index);
Expand All @@ -95,19 +120,21 @@ private static void parseImportMap(ImportStatement import, string code, ref int
if (!Parser.ValidateName(code, ref index))
ExceptionHelper.ThrowSyntaxError("Invalid import name", code, index);
var name = code.Substring(start, index - start);
var alias = name;

Tools.SkipSpaces(code, ref index);

alias = parseAlias(code, ref index) ?? name;
var alias = parseAlias(code, ref index) ?? name;

for (var i = 0; i < import._map.Count; i++)
{
if (import._map[i].Key == name)
ExceptionHelper.ThrowSyntaxError("Duplicate import", code, index);
}

import._map.Add(new KeyValuePair<string, string>(name, alias));
import._map.Add(new KeyValuePair<string, Variable>(name, new Variable(alias, state.lexicalScopeLevel)
{
Position = start,
Length = name.Length
}));

if (Parser.Validate(code, ",", ref index))
Tools.SkipSpaces(code, ref index);
Expand Down Expand Up @@ -175,7 +202,7 @@ public override JSValue Evaluate(Context context)
}
}

context._variables[_map[i].Value] = value;
context._variables[_map[i].Value._variableName] = value;
}
}
else
Expand Down Expand Up @@ -214,13 +241,13 @@ public override string ToString()
{
result.Append("{ ");

for (;;)
for (; ; )
{
var item = _map[i];

result.Append(item.Key);

if (item.Key != item.Value)
if (item.Key != item.Value._variableName)
{
result
.Append(" as ")
Expand All @@ -238,12 +265,21 @@ public override string ToString()
result.Append(" }");
}

result
.Append(" from \"")
result.Append(" from \"")
.Append(_moduleName)
.Append("\"");

return result.ToString();
}

public override bool Build(ref CodeNode _this, int expressionDepth, Dictionary<string, VariableDescriptor> variables, CodeContext codeContext, InternalCompilerMessageCallback message, FunctionInfo stats, Options opts)
{
for (var i = 0; i < _map.Count; i++)
{
var v = _map[i].Value;
Parser.Build(ref v, 1, variables, codeContext, message, stats, opts);
}
return false;
}
}
}
2 changes: 1 addition & 1 deletion NiL.JS/Statements/VariableDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ internal static CodeNode Parse(ParseInfo state, ref int index, bool forForLoop)
{
if (state.Variables[j].name == names[i] && state.Variables[j].definitionScopeLevel >= level)
{
if (state.Variables[j].lexicalScope && mode > VariableKind.FunctionScope)
if (state.Variables[j].lexicalScope)
ExceptionHelper.ThrowSyntaxError(string.Format(Strings.IdentifierAlreadyDeclared, names[i]), state.Code, index);

skip = true;
Expand Down

0 comments on commit 68e7213

Please sign in to comment.