diff --git a/src/Core/Compiler/Generator/ExpressionGenerator.cs b/src/Core/Compiler/Generator/ExpressionGenerator.cs
index 796d4e430..f05d70f36 100644
--- a/src/Core/Compiler/Generator/ExpressionGenerator.cs
+++ b/src/Core/Compiler/Generator/ExpressionGenerator.cs
@@ -43,11 +43,10 @@ private static void GenerateBinaryExpression(ScriptGenerator generator, MemberSy
Debug.Assert(propExpression.Type == ExpressionType.PropertySet);
if (propExpression.ObjectReference is BaseExpression) {
- writer.Write("ss.base(");
- writer.Write(generator.CurrentImplementation.ThisIdentifier);
- writer.Write(", 'set_");
+ writer.Write(((BaseExpression)propExpression.ObjectReference).EvaluatedType.FullGeneratedName);
+ writer.Write(".prototype.set_");
writer.Write(propExpression.Property.GeneratedName);
- writer.Write("').call(");
+ writer.Write(".call(");
writer.Write(generator.CurrentImplementation.ThisIdentifier);
writer.Write(", ");
GenerateExpression(generator, symbol, expression.RightOperand);
@@ -71,11 +70,10 @@ private static void GenerateBinaryExpression(ScriptGenerator generator, MemberSy
Debug.Assert(indexExpression.Type == ExpressionType.Indexer);
if (indexExpression.ObjectReference is BaseExpression) {
- writer.Write("ss.base(");
- writer.Write(generator.CurrentImplementation.ThisIdentifier);
- writer.Write(", 'set_");
+ writer.Write(((BaseExpression)indexExpression.ObjectReference).EvaluatedType.FullGeneratedName);
+ writer.Write(".prototype.set_");
writer.Write(indexExpression.Indexer.GeneratedName);
- writer.Write("').call(");
+ writer.Write(".call(");
writer.Write(generator.CurrentImplementation.ThisIdentifier);
writer.Write(", ");
GenerateExpressionList(generator, symbol, indexExpression.Indices);
@@ -478,11 +476,10 @@ private static void GenerateIndexerExpression(ScriptGenerator generator, MemberS
writer.Write("]");
}
else if (expression.ObjectReference is BaseExpression) {
- writer.Write("ss.base(");
- writer.Write(generator.CurrentImplementation.ThisIdentifier);
- writer.Write(", 'get_");
+ writer.Write(((BaseExpression)expression.ObjectReference).EvaluatedType.FullGeneratedName);
+ writer.Write(".prototype.get_");
writer.Write(expression.Indexer.GeneratedName);
- writer.Write("').call(");
+ writer.Write(".call(");
writer.Write(generator.CurrentImplementation.ThisIdentifier);
writer.Write(", ");
GenerateExpressionList(generator, symbol, expression.Indices);
@@ -707,11 +704,10 @@ private static void GenerateMethodExpression(ScriptGenerator generator, MemberSy
if (expression.ObjectReference is BaseExpression) {
Debug.Assert(expression.Method.IsExtension == false);
- writer.Write("ss.base(");
- writer.Write(generator.CurrentImplementation.ThisIdentifier);
- writer.Write(", '");
+ writer.Write(((BaseExpression)expression.ObjectReference).EvaluatedType.FullGeneratedName);
+ writer.Write(".prototype.");
writer.Write(expression.Method.GeneratedName);
- writer.Write("').call(");
+ writer.Write(".call(");
writer.Write(generator.CurrentImplementation.ThisIdentifier);
if ((expression.Parameters != null) && (expression.Parameters.Count != 0)) {
writer.Write(", ");
@@ -860,13 +856,7 @@ private static void GeneratePropertyExpression(ScriptGenerator generator, Member
Debug.Assert(baseClass != null);
writer.Write(baseClass.FullGeneratedName);
- if (baseClass.IsApplicationType) {
- writer.Write("$.");
- }
- else {
- writer.Write(".prototype.");
- }
- writer.Write("get_");
+ writer.Write(".prototype.get_");
writer.Write(expression.Property.GeneratedName);
writer.Write(".call(");
writer.Write(generator.CurrentImplementation.ThisIdentifier);
diff --git a/src/Core/Scripts/Runtime.js b/src/Core/Scripts/Runtime.js
index 4fa0d4d37..beba55767 100644
--- a/src/Core/Scripts/Runtime.js
+++ b/src/Core/Scripts/Runtime.js
@@ -95,7 +95,6 @@
safeCast: safeCast,
canAssign: canAssign,
instanceOf: instanceOf,
- base: base,
culture: {
neutral: neutralCulture,
diff --git a/src/Core/Scripts/Runtime/Task.js b/src/Core/Scripts/Runtime/Task.js
index 066c34b67..40dd9f3b3 100644
--- a/src/Core/Scripts/Runtime/Task.js
+++ b/src/Core/Scripts/Runtime/Task.js
@@ -90,6 +90,10 @@ function _joinTasks(tasks, any) {
tasks = tasks.slice(1);
count--;
}
+ if (Array.isArray(tasks[0])) {
+ tasks = tasks[0];
+ count = tasks.length;
+ }
var joinTask = new Task();
var seen = 0;
diff --git a/src/Core/Scripts/Runtime/TypeSystem.js b/src/Core/Scripts/Runtime/TypeSystem.js
index c478b92ff..5bf79bcfc 100644
--- a/src/Core/Scripts/Runtime/TypeSystem.js
+++ b/src/Core/Scripts/Runtime/TypeSystem.js
@@ -153,12 +153,6 @@ function safeCast(instance, type) {
return instanceOf(type, instance) ? instance : null;
}
-function base(instanceOrType, method) {
- var baseType = instanceOrType.constructor.$base || instanceOrType.$base;
- var m = baseType.prototype[method];
- return m !== instanceOrType[method] ? m : base(baseType, method);
-}
-
function module(name, implementation, exports) {
var registry = _modules[name] = { $name: name };
diff --git a/src/Libraries/Node/Node.Core/IO/Buffer.cs b/src/Libraries/Node/Node.Core/IO/Buffer.cs
index b2c81f3ae..3b8c1de6a 100644
--- a/src/Libraries/Node/Node.Core/IO/Buffer.cs
+++ b/src/Libraries/Node/Node.Core/IO/Buffer.cs
@@ -24,6 +24,7 @@ public Buffer(string data) {
public Buffer(string data, Encoding encoding) {
}
+ [ScriptField]
public int Length {
get {
return 0;
diff --git a/src/Libraries/Web/Html/Document.cs b/src/Libraries/Web/Html/Document.cs
index b4790206e..957266017 100644
--- a/src/Libraries/Web/Html/Document.cs
+++ b/src/Libraries/Web/Html/Document.cs
@@ -148,18 +148,53 @@ public static void AddEventListener(string eventName, ElementEventListener liste
public static void AttachEvent(string eventName, ElementEventHandler handler) {
}
+ ///
+ /// Creates an Attr of the given name. Note that the Attr instance can then be set on an
+ /// Element using the setAttributeNode method. To create an attribute with a qualified name
+ /// and namespace URI, use the CreateAttributeNS method.
+ ///
+ /// The name of the attribute.
+ /// A new Attr object with the nodeName attribute set to name, and localName, prefix,
+ /// and namespaceURI set to null. The value of the attribute is the empty string.
public static ElementAttribute CreateAttribute(string name) {
return null;
}
+ ///
+ /// Creates an attribute of the given qualified name and namespace URI.
+ ///
+ /// The namespace URI of the attribute to create.
+ /// The qualified name of the attribute to instantiate.
+ /// A new Attr object with the given namespace and qualified name.
+ public static ElementAttribute CreateAttributeNS(string namespaceURI, string qualifiedName) {
+ return null;
+ }
+
public static DocumentFragment CreateDocumentFragment() {
return null;
}
+ ///
+ /// Creates an element of the type specified.
+ /// To create an element with a qualified name and namespace URI, use the CreateElementNS method.
+ ///
+ /// The name of the element type to instantiate.
+ /// A new Element object with the nodeName attribute set to tagName, and localName,
+ /// prefix, and namespaceURI set to null.
public static Element CreateElement(string tagName) {
return null;
}
+ ///
+ /// Creates an element of the given qualified name and namespace URI.
+ ///
+ /// The namespace URI of the element to create.
+ /// The qualified name of the element type to instantiate.
+ /// A new Element object with the given namespace and qualified name.
+ public static Element CreateElementNS(string namespaceURI, string qualifiedName) {
+ return null;
+ }
+
public static MutableEvent CreateEvent(string eventType) {
return null;
}
@@ -168,6 +203,10 @@ public static Element CreateTextNode(string data) {
return null;
}
+ public static Element ImportNode(Element imporedNode, bool deep) {
+ return null;
+ }
+
public static void DetachEvent(string eventName, ElementEventHandler handler) {
}
@@ -206,6 +245,16 @@ public static ElementCollection GetElementsByTagName(string tagName) {
return null;
}
+ ///
+ /// Returns a NodeList of all the Elements with a given local name and namespace URI in the order in which they are encountered in a preorder traversal of the Document tree.
+ ///
+ /// The namespace URI of the elements to match on. The special value "*" matches all namespaces.
+ /// The local name of the elements to match on. The special value "*" matches all local names.
+ /// A new NodeList object containing all the matched Elements.
+ public static ElementCollection GetElementsByTagNameNS(string namespaceURI, string localName) {
+ return null;
+ }
+
public static bool HasFocus() {
return false;
}
diff --git a/src/Libraries/Web/Xml/XmlDocument.cs b/src/Libraries/Web/Xml/XmlDocument.cs
index d196825f3..2629072e9 100644
--- a/src/Libraries/Web/Xml/XmlDocument.cs
+++ b/src/Libraries/Web/Xml/XmlDocument.cs
@@ -59,5 +59,9 @@ public XmlNode CreateProcessingInstruction(string target, string data) {
public XmlText CreateTextNode(string text) {
return null;
}
+
+ public XmlNode ImportNode(XmlNode externalNode, bool deep) {
+ return null;
+ }
}
}
diff --git a/src/ZipX/VSIX/Extension.vsixmanifest b/src/ZipX/VSIX/Extension.vsixmanifest
index d8ed80ae0..459fd8d27 100644
--- a/src/ZipX/VSIX/Extension.vsixmanifest
+++ b/src/ZipX/VSIX/Extension.vsixmanifest
@@ -29,6 +29,13 @@
VCSExpress
VWDExpress
+
+ Ultimate
+ Premium
+ Pro
+ VCSExpress
+ VWDExpress
+
diff --git a/tests/Core/BrowserTest.cs b/tests/Core/BrowserTest.cs
index 5b450750a..2dc75d4ab 100644
--- a/tests/Core/BrowserTest.cs
+++ b/tests/Core/BrowserTest.cs
@@ -22,6 +22,7 @@ public abstract class BrowserTest {
private static readonly string[] _codeFiles = new string[] {
"OOP.cs"
};
+ private static string _compilationFailures;
private const int _port = 3976;
@@ -40,16 +41,24 @@ static BrowserTest() {
File.Copy(Path.Combine(binDirectory, script), Path.Combine(scriptsDirectory, script), overwrite: true);
}
+ List codeFailures = new List();
+
string mscorlibPath = Path.Combine(binDirectory, "mscorlib.dll");
foreach (string codeFile in _codeFiles) {
string script = Path.GetFileNameWithoutExtension(codeFile) + Path.ChangeExtension(".cs", ".js");
SimpleCompilation compilation = new SimpleCompilation(Path.Combine(scriptsDirectory, script));
- compilation.AddReference(mscorlibPath)
- .AddSource(Path.Combine(codeDirectory, codeFile))
- .Execute();
+ bool result = compilation.AddReference(mscorlibPath)
+ .AddSource(Path.Combine(codeDirectory, codeFile))
+ .Execute();
+
+ if (result == false) {
+ codeFailures.Add(codeFile);
+ }
}
+ _compilationFailures = (codeFailures.Count == 0) ? null : String.Join(", ", codeFailures);
+
_webTest = new WebTest();
_webTest.StartWebServer(_port, webRoot);
}
@@ -64,6 +73,11 @@ public TestContext TestContext {
}
protected void RunTest(string url) {
+ if (_compilationFailures != null) {
+ Assert.Fail("Could not run test due to compilation failure of " + _compilationFailures + ".");
+ return;
+ }
+
Uri testUri = _webTest.GetTestUri(url);
WebTestResult result = _webTest.RunTest(testUri, WebBrowser.Chrome);
diff --git a/tests/ScriptTests.cs b/tests/ScriptTests.cs
index e64325083..6ea00bfb1 100644
--- a/tests/ScriptTests.cs
+++ b/tests/ScriptTests.cs
@@ -22,6 +22,11 @@ public void TestTypeSystem() {
RunTest("/TypeSystem.htm");
}
+ [TestMethod]
+ public void TestBases() {
+ RunTest("/Bases.htm");
+ }
+
#region Loader Tests
[TestMethod]
public void TestLoader() {
diff --git a/tests/TestCases/Basic/Minimization/Baseline.txt b/tests/TestCases/Basic/Minimization/Baseline.txt
index cf463a71c..daf9da6f6 100644
--- a/tests/TestCases/Basic/Minimization/Baseline.txt
+++ b/tests/TestCases/Basic/Minimization/Baseline.txt
@@ -173,7 +173,7 @@ define('test', ['ss', 'lib'], function(ss, lib) {
},
$0: function() {
this.$2();
- ss.base(this, '$0').call(this);
+ Bar2.prototype.$0.call(this);
var d = MyData('a', 'b');
d.$0 = d.$1;
},
@@ -273,7 +273,7 @@ define('test', ['ss', 'lib'], function(ss, lib) {
},
dispose: function() {
this.c$0 = 0;
- ss.base(this, 'dispose').call(this);
+ lib.Behavior.prototype.dispose.call(this);
},
c$6: function() {
},
diff --git a/tests/TestCases/Expression/Base/Baseline.txt b/tests/TestCases/Expression/Base/Baseline.txt
index 60080165b..8c8ee0fd1 100644
--- a/tests/TestCases/Expression/Base/Baseline.txt
+++ b/tests/TestCases/Expression/Base/Baseline.txt
@@ -24,10 +24,10 @@ define('test', ['ss'], function(ss) {
}
var Bar$ = {
sum: function() {
- return ss.base(this, 'sum').call(this, 1) + 1;
+ return Foo.prototype.sum.call(this, 1) + 1;
},
toString: function() {
- return ss.base(this, 'toString').call(this) + ' -> Bar';
+ return Foo.prototype.toString.call(this) + ' -> Bar';
}
};
diff --git a/tests/TestCases/Expression/Members/Baseline.txt b/tests/TestCases/Expression/Members/Baseline.txt
index 609890cbb..322c8d28e 100644
--- a/tests/TestCases/Expression/Members/Baseline.txt
+++ b/tests/TestCases/Expression/Members/Baseline.txt
@@ -67,10 +67,10 @@ define('test', ['ss'], function(ss) {
test2: function() {
var n = this.get_XYZ();
n = this.get_XYZ();
- n = App$.get_XYZ.call(this);
+ n = App.prototype.get_XYZ.call(this);
this.set_XYZ(n);
this.set_XYZ(n);
- ss.base(this, 'set_XYZ').call(this, n);
+ App.prototype.set_XYZ.call(this, n);
this._value2 = n;
this._value2 = n;
this._value2 = n;
diff --git a/tests/TestCases/Member/Indexers/Baseline.txt b/tests/TestCases/Member/Indexers/Baseline.txt
index a4db55dd7..3c2065171 100644
--- a/tests/TestCases/Member/Indexers/Baseline.txt
+++ b/tests/TestCases/Member/Indexers/Baseline.txt
@@ -133,15 +133,15 @@ define('test', ['ss'], function(ss) {
VirtualIndexer.call(this);
var i = this.get_item('name');
this.set_item('name', i + 1);
- var j = ss.base(this, 'get_item').call(this, 'name');
- ss.base(this, 'set_item').call(this, 'name', 43);
+ var j = VirtualIndexer.prototype.get_item.call(this, 'name');
+ VirtualIndexer.prototype.set_item.call(this, 'name', 43);
}
var OverriddenIndexer$ = {
get_item: function(name) {
- return ss.base(this, 'get_item').call(this, name) + 1;
+ return VirtualIndexer.prototype.get_item.call(this, name) + 1;
},
set_item: function(name, value) {
- ss.base(this, 'set_item').call(this, name, value - 1);
+ VirtualIndexer.prototype.set_item.call(this, name, value - 1);
return value;
}
};
diff --git a/tests/TestCases/Member/Properties/Baseline.txt b/tests/TestCases/Member/Properties/Baseline.txt
index 9c8678a95..88c797959 100644
--- a/tests/TestCases/Member/Properties/Baseline.txt
+++ b/tests/TestCases/Member/Properties/Baseline.txt
@@ -41,7 +41,7 @@ define('test', ['ss'], function(ss) {
function Test2() {
Test.call(this);
- var n = Test$.get_XYZ.call(this);
+ var n = Test.prototype.get_XYZ.call(this);
if (n === this.get_XYZ()) {
}
if (this.get_XYZ() === n) {
diff --git a/tests/TestCases/Type/Partials/Baseline.txt b/tests/TestCases/Type/Partials/Baseline.txt
index 968a6db33..11d256e6c 100644
--- a/tests/TestCases/Type/Partials/Baseline.txt
+++ b/tests/TestCases/Type/Partials/Baseline.txt
@@ -112,7 +112,7 @@ define('test', ['ss'], function(ss) {
var e1 = document.getElementById(this.bar);
var e2 = document.getElementById(this.name);
var e3 = document.getElementById(this.bar);
- var s = this.testMethod() + ss.base(this, 'testMethod').call(this);
+ var s = this.testMethod() + MergedMembersClass.prototype.testMethod.call(this);
},
get_item: function(s) {
return s;
diff --git a/tests/TestSite/Bases.htm b/tests/TestSite/Bases.htm
new file mode 100644
index 000000000..a90ed09b5
--- /dev/null
+++ b/tests/TestSite/Bases.htm
@@ -0,0 +1,45 @@
+
+
+
+ Bases
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/TestSite/Code/OOP.cs b/tests/TestSite/Code/OOP.cs
index 1b5d7b415..7891e84ef 100644
--- a/tests/TestSite/Code/OOP.cs
+++ b/tests/TestSite/Code/OOP.cs
@@ -121,3 +121,140 @@ public interface IObject {
public class Zoo {
}
}
+
+
+namespace Test.Bases {
+
+ // A series of classes with different combinations of overrides at different
+ // levels in the class hierarchy. Tests issues #379, #384 as applied to properties,
+ // methods, and index operators.
+
+ public class C1 {
+ private string _valueA = "A";
+
+ public virtual string PropertyA {
+ get {
+ return _valueA + "-PC1";
+ }
+ set {
+ _valueA = value + "+PC1";
+ }
+ }
+
+ public virtual string MethodA() {
+ return _valueA + "-MC1";
+ }
+
+ public virtual string this[int key] {
+ get {
+ return _valueA + "-" + key.ToString() + "IC1";
+ }
+ set {
+ _valueA = value + "+" + key.ToString() + "IC1";
+ }
+ }
+ }
+
+ public class C2 : C1 {
+ public override string PropertyA {
+ get {
+ return base.PropertyA + "-PC2";
+ }
+ set {
+ base.PropertyA = value + "+PC2";
+ }
+ }
+
+ public override string MethodA() {
+ return base.MethodA() + "-MC2";
+ }
+
+ public override string this[int key] {
+ get {
+ return base[key] + "-" + key.ToString() + "IC2";
+ }
+ set {
+ base[key] = value + "+" + key.ToString() + "IC2";
+ }
+ }
+ }
+
+ public class C3 : C2 {
+ public override string PropertyA {
+ get {
+ return base.PropertyA + "-PC3";
+ }
+ set {
+ base.PropertyA = value + "+PC3";
+ }
+ }
+
+ public override string MethodA() {
+ return base.MethodA() + "-MC3";
+ }
+
+ public override string this[int key] {
+ get {
+ return base[key] + "-" + key.ToString() + "IC3";
+ }
+ set {
+ base[key] = value + "+" + key.ToString() + "IC3";
+ }
+ }
+ }
+
+ public class C4 : C3 {
+ // intentionally skip this generation of overrides
+ }
+
+ public class C5 : C4 {
+ public override string PropertyA {
+ get {
+ return base.PropertyA + "-PC5";
+ }
+ set {
+ base.PropertyA = value + "+PC5";
+ }
+ }
+
+ public override string MethodA() {
+ return base.MethodA() + "-MC5";
+ }
+
+ public override string this[int key] {
+ get {
+ return base[key] + "-" + key.ToString() + "IC5";
+ }
+ set {
+ base[key] = value + "+" + key.ToString() + "IC5";
+ }
+ }
+ }
+
+ public class TestCase {
+
+ public static string RunTest(C1 x) {
+ string output = "";
+ string delim = ",";
+
+ // Test getter, method, and index (should accumulate outward through bases)
+ output = x.PropertyA
+ + delim + x.MethodA()
+ + delim + x[99];
+
+ // Test property setter (should accumulate inward and outward through bases)
+
+ x.PropertyA = "X";
+ output += delim + x.PropertyA;
+
+ // Test index setter (should accumulate inward and outward through bases)
+
+ x[88] = "Y";
+ output += delim + x[99];
+
+ return output;
+ }
+
+ }
+
+}