Version 0.2.6.0
svn merge -r 15295:15346 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
and cherry pick 15354 from bleeding edge to trunk.
git-svn-id: http://dart.googlecode.com/svn/trunk@15355 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/compiler/java/com/google/dart/compiler/CommandLineOptions.java b/compiler/java/com/google/dart/compiler/CommandLineOptions.java
index 93220fb..e264801 100644
--- a/compiler/java/com/google/dart/compiler/CommandLineOptions.java
+++ b/compiler/java/com/google/dart/compiler/CommandLineOptions.java
@@ -6,6 +6,7 @@
import com.google.common.collect.Lists;
import com.google.dart.compiler.CompilerConfiguration.ErrorFormat;
+import com.google.dart.compiler.util.apache.StringUtils;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.CmdLineException;
@@ -14,6 +15,7 @@
import java.io.File;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
/**
@@ -269,6 +271,16 @@
*/
public static CmdLineParser parse(String[] args, CompilerOptions parsedOptions)
throws CmdLineException {
+ // convert new "--name=value" into old "--name value" style
+ {
+ List<String> argList = Lists.newArrayList();
+ for (String arg : args) {
+ String[] parts = StringUtils.split(arg, '=');
+ Collections.addAll(argList, parts);
+ }
+ args = argList.toArray(new String[argList.size()]);
+ }
+
boolean ignoreUnrecognized = false;
for (String arg : args) {
if (arg.equals("--ignore-unrecognized-flags")) {
diff --git a/compiler/java/com/google/dart/compiler/ast/DartCommentRefName.java b/compiler/java/com/google/dart/compiler/ast/DartCommentRefName.java
index e39c50a..52c133e 100644
--- a/compiler/java/com/google/dart/compiler/ast/DartCommentRefName.java
+++ b/compiler/java/com/google/dart/compiler/ast/DartCommentRefName.java
@@ -5,14 +5,13 @@
package com.google.dart.compiler.ast;
import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.NodeElement;
/**
- * <code>[new name]</code> in {@link DartComment}.
+ * <code>[name]</code> in {@link DartComment}.
*/
public final class DartCommentRefName extends DartNode {
private final String name;
- private NodeElement element;
+ private Element element;
public DartCommentRefName(String name) {
assert name != null;
@@ -25,13 +24,13 @@
}
@Override
- public NodeElement getElement() {
+ public Element getElement() {
return element;
}
@Override
public void setElement(Element element) {
- this.element = (NodeElement) element;
+ this.element = element;
}
public String getName() {
diff --git a/compiler/java/com/google/dart/compiler/ast/LibraryExport.java b/compiler/java/com/google/dart/compiler/ast/LibraryExport.java
index 81104f5..98c2ffd 100644
--- a/compiler/java/com/google/dart/compiler/ast/LibraryExport.java
+++ b/compiler/java/com/google/dart/compiler/ast/LibraryExport.java
@@ -5,6 +5,7 @@
package com.google.dart.compiler.ast;
import com.google.common.collect.Sets;
+import com.google.dart.compiler.common.SourceInfo;
import java.util.List;
import java.util.Set;
@@ -13,16 +14,23 @@
* Information about export - {@link LibraryUnit} and show/hide names.
*/
public class LibraryExport {
+ private final SourceInfo sourceInfo;
private final LibraryUnit library;
private final Set<String> showNames;
private final Set<String> hideNames;
- public LibraryExport(LibraryUnit library, List<ImportCombinator> combinators) {
+ public LibraryExport(SourceInfo sourceInfo, LibraryUnit library,
+ List<ImportCombinator> combinators) {
+ this.sourceInfo = sourceInfo;
this.library = library;
this.showNames = createCombinatorsSet(combinators, true);
this.hideNames = createCombinatorsSet(combinators, false);
}
+ public SourceInfo getSourceInfo() {
+ return sourceInfo;
+ }
+
public LibraryUnit getLibrary() {
return library;
}
diff --git a/compiler/java/com/google/dart/compiler/ast/LibraryNode.java b/compiler/java/com/google/dart/compiler/ast/LibraryNode.java
index 31407d8..5a98e66 100644
--- a/compiler/java/com/google/dart/compiler/ast/LibraryNode.java
+++ b/compiler/java/com/google/dart/compiler/ast/LibraryNode.java
@@ -33,6 +33,7 @@
}
public LibraryNode(DartImportDirective importDirective) {
+ setSourceInfo(importDirective.getSourceInfo());
this.text = importDirective.getLibraryUri().getValue();
this.prefix = importDirective.getPrefixValue();
this.combinators = importDirective.getCombinators();
@@ -40,12 +41,13 @@
}
public LibraryNode(DartExportDirective exportDirective) {
+ setSourceInfo(exportDirective.getSourceInfo());
this.text = exportDirective.getLibraryUri().getValue();
this.prefix = null;
this.combinators = exportDirective.getCombinators();
this.exported = false;
}
-
+
public String getText() {
return text;
}
diff --git a/compiler/java/com/google/dart/compiler/ast/LibraryUnit.java b/compiler/java/com/google/dart/compiler/ast/LibraryUnit.java
index 2bd491f..d4fa682 100644
--- a/compiler/java/com/google/dart/compiler/ast/LibraryUnit.java
+++ b/compiler/java/com/google/dart/compiler/ast/LibraryUnit.java
@@ -124,7 +124,7 @@
public void addExport(LibraryUnit unit, LibraryNode node) {
if (unit != null) {
if (node != null) {
- exports.add(new LibraryExport(unit, node.getCombinators()));
+ exports.add(new LibraryExport(node.getSourceInfo(), unit, node.getCombinators()));
}
}
}
diff --git a/compiler/java/com/google/dart/compiler/parser/DartParser.java b/compiler/java/com/google/dart/compiler/parser/DartParser.java
index a79148c..1482111 100644
--- a/compiler/java/com/google/dart/compiler/parser/DartParser.java
+++ b/compiler/java/com/google/dart/compiler/parser/DartParser.java
@@ -308,14 +308,14 @@
beginCompilationUnit();
ctx.unitAboutToCompile(dartSource, isDietParse);
DartUnit unit = new DartUnit(dartSource, isDietParse);
+ List<DartAnnotation> metadata = parseMetadata();
// parse any directives at the beginning of the source
- parseDirectives(unit);
+ metadata = parseDirectives(unit, metadata);
while (!EOS()) {
DartNodeWithMetadata node = null;
beginTopLevelElement();
- List<DartAnnotation> metadata = parseMetadata();
isParsingClass = isParsingInterface = false;
// Check for ABSTRACT_KEYWORD.
isTopLevelAbstract = false;
@@ -347,14 +347,15 @@
node = done(parseFunctionTypeAlias());
} else if (looksLikeDirective()) {
reportErrorWithoutAdvancing(ParserErrorCode.DIRECTIVE_OUT_OF_ORDER);
- parseDirectives(unit);
+ metadata = parseDirectives(unit, metadata);
} else {
node = done(parseFieldOrMethod(false));
}
// Parsing was successful, add node.
if (node != null) {
- setMetadata(node, metadata);
unit.getTopLevelNodes().add(node);
+ setMetadata(node, metadata);
+ metadata = parseMetadata();
// Only "class" can be top-level abstract element.
if (isTopLevelAbstract && !isParsingClass) {
int abstractPositionEnd = topLevelAbstractModifierPosition + ABSTRACT_KEYWORD.length();
@@ -530,8 +531,8 @@
return done(libUnit);
}
- private void parseDirectives(DartUnit unit) {
- List<DartAnnotation> metadata = parseMetadata();
+ private List<DartAnnotation> parseDirectives(DartUnit unit, List<DartAnnotation> metadata) {
+ boolean hasLibraryDirective = false;
if (peekPseudoKeyword(0, LIBRARY_KEYWORD)) {
DartLibraryDirective libraryDirective = parseLibraryDirective();
for (DartDirective directive : unit.getDirectives()) {
@@ -540,29 +541,38 @@
break;
}
}
- setMetadata(libraryDirective, metadata);
unit.getDirectives().add(libraryDirective);
+ hasLibraryDirective = true;
+ setMetadata(libraryDirective, metadata);
+ metadata = parseMetadata();
}
while (peekPseudoKeyword(0, IMPORT_KEYWORD) || peekPseudoKeyword(0, EXPORT_KEYWORD)) {
if (peekPseudoKeyword(0, IMPORT_KEYWORD)) {
DartImportDirective importDirective = parseImportDirective();
- setMetadata(importDirective, metadata);
unit.getDirectives().add(importDirective);
+ setMetadata(importDirective, metadata);
+ metadata = parseMetadata();
} else {
DartExportDirective exportDirective = parseExportDirective();
- setMetadata(exportDirective, metadata);
unit.getDirectives().add(exportDirective);
+ if (!hasLibraryDirective) {
+ reportError(exportDirective, ParserErrorCode.EXPORT_WITHOUT_LIBRARY_DIRECTIVE);
+ }
+ setMetadata(exportDirective, metadata);
+ metadata = parseMetadata();
}
}
while (peekPseudoKeyword(0, PART_KEYWORD)) {
if (peekPseudoKeyword(1, OF_KEYWORD)) {
DartPartOfDirective partOfDirective = parsePartOfDirective();
- setMetadata(partOfDirective, metadata);
unit.getDirectives().add(partOfDirective);
+ setMetadata(partOfDirective, metadata);
+ metadata = parseMetadata();
} else {
DartSourceDirective partDirective = parsePartDirective();
- setMetadata(partDirective, metadata);
unit.getDirectives().add(partDirective);
+ setMetadata(partDirective, metadata);
+ metadata = parseMetadata();
}
}
//
@@ -578,21 +588,24 @@
break;
}
}
- setMetadata(libraryDirective, metadata);
unit.getDirectives().add(libraryDirective);
done(libraryDirective);
+ setMetadata(libraryDirective, metadata);
+ metadata = parseMetadata();
}
while (peek(0) == Token.IMPORT) {
beginImportDirective();
DartImportDirective importDirective = parseObsoleteImportDirective();
- setMetadata(importDirective, metadata);
unit.getDirectives().add(done(importDirective));
+ setMetadata(importDirective, metadata);
+ metadata = parseMetadata();
}
while (peek(0) == Token.SOURCE) {
beginSourceDirective();
DartSourceDirective sourceDirective = parseSourceDirective();
- setMetadata(sourceDirective, metadata);
unit.getDirectives().add(done(sourceDirective));
+ setMetadata(sourceDirective, metadata);
+ metadata = parseMetadata();
}
while (peek(0) == Token.RESOURCE) {
parseResourceDirective();
@@ -600,9 +613,11 @@
while (peek(0) == Token.NATIVE) {
beginNativeDirective();
DartNativeDirective nativeDirective = parseNativeDirective();
- setMetadata(nativeDirective, metadata);
unit.getDirectives().add(done(nativeDirective));
+ setMetadata(nativeDirective, metadata);
+ metadata = parseMetadata();
}
+ return metadata;
}
private DartLibraryDirective parseLibraryDirective() {
@@ -3842,6 +3857,21 @@
DartIdentifier error = doneWithoutConsuming(new DartIdentifier(""));
return doneWithoutConsuming(new DartPropertyAccess(receiver, error));
}
+ // receiver.() = missing name
+ if (peek(0) == Token.LPAREN) {
+ reportUnexpectedToken(position(), Token.IDENTIFIER, peek(0));
+ DartIdentifier name;
+ {
+ beginIdentifier();
+ name = done(new DartSyntheticErrorIdentifier());
+ }
+ boolean save = setAllowFunctionExpression(true);
+ DartMethodInvocation expr = doneWithoutConsuming(new DartMethodInvocation(receiver,
+ false, name, parseArguments()));
+ setAllowFunctionExpression(save);
+ return expr;
+ }
+ // expect name
DartIdentifier name = parseIdentifier();
if (peek(0) == Token.LPAREN) {
boolean save = setAllowFunctionExpression(true);
diff --git a/compiler/java/com/google/dart/compiler/parser/ParserErrorCode.java b/compiler/java/com/google/dart/compiler/parser/ParserErrorCode.java
index aa904a6..1e458cb 100644
--- a/compiler/java/com/google/dart/compiler/parser/ParserErrorCode.java
+++ b/compiler/java/com/google/dart/compiler/parser/ParserErrorCode.java
@@ -78,6 +78,7 @@
EXPECTED_TOKEN("Unexpected token '%s' (expected '%s')"),
// TODO(zundel): error message needs JUnit test
EXPECTED_VAR_FINAL_OR_TYPE("Expected 'var', 'final' or type"),
+ EXPORT_WITHOUT_LIBRARY_DIRECTIVE("Only library can use 'export' directive"),
EXTERNAL_ABSTRACT("External methods cannot be abstract"),
EXTERNAL_ONLY_METHOD("Only a top-level function, a method, a getter, a setter or an non-redirecting constructor can be specified as external"),
EXTERNAL_METHOD_BODY("External methods cannot have body"),
diff --git a/compiler/java/com/google/dart/compiler/resolver/Elements.java b/compiler/java/com/google/dart/compiler/resolver/Elements.java
index b95d48c..66aa87c 100644
--- a/compiler/java/com/google/dart/compiler/resolver/Elements.java
+++ b/compiler/java/com/google/dart/compiler/resolver/Elements.java
@@ -91,8 +91,8 @@
((LibraryElementImplementation) element).setMetadata(metadata);
}
- public static void addExportedElement(LibraryElement libraryElement, Element element) {
- ((LibraryElementImplementation) libraryElement).addExportedElements(element);
+ public static Element addExportedElement(LibraryElement libraryElement, Element element) {
+ return ((LibraryElementImplementation) libraryElement).addExportedElements(element);
}
public static LibraryElement getLibraryElement(Element element) {
@@ -766,9 +766,17 @@
|| Elements.isLibrarySource(source, "/core/core.dart");
}
+ public static boolean isCollectionLibrarySource(Source source) {
+ return Elements.isLibrarySource(source, "/collection/collection.dart");
+ }
+
public static boolean isHtmlLibrarySource(Source source) {
return Elements.isLibrarySource(source, "/html/dartium/html_dartium.dart");
}
+
+ public static boolean isSourceName(Source source, String requiredName) {
+ return source.getName().equals(requiredName);
+ }
/**
* @return the {@link LibraryElement} which declares given {@link Element}.
@@ -893,4 +901,34 @@
addAllMembers(visited, allMembers, intf.getElement());
}
}
+
+ public static boolean isAbstractElement(Element element) {
+ if (element == null) {
+ return false;
+ }
+ if (element.getModifiers().isAbstract()) {
+ return true;
+ }
+ if (element.getModifiers().isExternal()) {
+ return false;
+ }
+ if (element.getModifiers().isStatic()) {
+ return false;
+ }
+ if (ElementKind.of(element) == ElementKind.METHOD) {
+ MethodElement method = (MethodElement) element;
+ return !method.hasBody();
+ }
+ if (ElementKind.of(element) == ElementKind.FIELD) {
+ FieldElement field = (FieldElement) element;
+ if (isAbstractElement(field.getGetter())) {
+ return true;
+ }
+ if (isAbstractElement(field.getSetter())) {
+ return true;
+ }
+ return false;
+ }
+ return false;
+ }
}
diff --git a/compiler/java/com/google/dart/compiler/resolver/LibraryElement.java b/compiler/java/com/google/dart/compiler/resolver/LibraryElement.java
index ec1a0d3..529ad64 100644
--- a/compiler/java/com/google/dart/compiler/resolver/LibraryElement.java
+++ b/compiler/java/com/google/dart/compiler/resolver/LibraryElement.java
@@ -6,14 +6,14 @@
import com.google.dart.compiler.ast.LibraryUnit;
-import java.util.List;
+import java.util.Collection;
public interface LibraryElement extends EnclosingElement {
Scope getImportScope();
Scope getScope();
- List<Element> getExportedElements();
+ Collection<Element> getExportedElements();
LibraryUnit getLibraryUnit();
diff --git a/compiler/java/com/google/dart/compiler/resolver/LibraryElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/LibraryElementImplementation.java
index ea4d530..baffee0 100644
--- a/compiler/java/com/google/dart/compiler/resolver/LibraryElementImplementation.java
+++ b/compiler/java/com/google/dart/compiler/resolver/LibraryElementImplementation.java
@@ -4,18 +4,18 @@
package com.google.dart.compiler.resolver;
-import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import com.google.dart.compiler.ast.DartObsoleteMetadata;
import com.google.dart.compiler.ast.LibraryUnit;
import java.util.Collection;
-import java.util.List;
+import java.util.Map;
class LibraryElementImplementation extends AbstractNodeElement implements LibraryElement {
private final Scope importScope = new Scope("import", this);
private final Scope scope = new Scope("library", this, importScope);
- private final List<Element> exportedElements = Lists.newArrayList();
+ private final Map<String, Element> exportedElements = Maps.newHashMap();
private LibraryUnit libraryUnit;
private MethodElement entryPoint;
private DartObsoleteMetadata metadata;
@@ -41,12 +41,13 @@
return scope;
}
- public void addExportedElements(Element element) {
- exportedElements.add(element);
+ public Element addExportedElements(Element element) {
+ String name = element.getName();
+ return exportedElements.put(name, element);
}
- public List<Element> getExportedElements() {
- return exportedElements;
+ public Collection<Element> getExportedElements() {
+ return exportedElements.values();
}
@Override
diff --git a/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java b/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java
index 8b6f83c..ee9743b77 100644
--- a/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java
+++ b/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java
@@ -81,16 +81,6 @@
void declare(Element element, ErrorCode errorCode) {
String name = element.getName();
Element existingLocalElement = scope.findLocalElement(name);
- // Check for duplicate declaration in the enclosing scope.
- if (existingLocalElement == null) {
- Element existingElement = scope.findElement(scope.getLibrary(), name);
- if (existingElement != null) {
- SourceInfo nameSourceInfo = element.getNameLocation();
- if (existingElement.getKind() == ElementKind.LIBRARY_PREFIX) {
- onError(nameSourceInfo, ResolverErrorCode.CANNOT_HIDE_IMPORT_PREFIX, name);
- }
- }
- }
// Check for duplicate declaration in the same scope.
if (existingLocalElement != null && errorCode != null) {
SourceInfo nameSourceInfo = element.getNameLocation();
diff --git a/compiler/java/com/google/dart/compiler/resolver/Resolver.java b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
index 88b06e4..66308b2 100644
--- a/compiler/java/com/google/dart/compiler/resolver/Resolver.java
+++ b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
@@ -5,11 +5,13 @@
package com.google.dart.compiler.resolver;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.dart.compiler.DartCompilationPhase;
import com.google.dart.compiler.DartCompilerContext;
import com.google.dart.compiler.ErrorCode;
+import com.google.dart.compiler.Source;
import com.google.dart.compiler.ast.ASTNodes;
import com.google.dart.compiler.ast.ASTVisitor;
import com.google.dart.compiler.ast.DartArrayLiteral;
@@ -520,7 +522,7 @@
boundNode,
false,
false,
- false,
+ true,
ResolverErrorCode.NO_SUCH_TYPE,
ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
boundNode.setType(bound);
@@ -732,11 +734,12 @@
if (body == null) {
if (member.getModifiers().isStatic() && !member.getModifiers().isExternal()) {
onError(functionNode, ResolverErrorCode.STATIC_METHOD_MUST_HAVE_BODY);
- } else if (!Elements.isNonFactoryConstructor(member) && !member.getModifiers().isAbstract()
- && !member.getModifiers().isExternal() && node.getRedirectedTypeName() == null
- && !(isInterface || isAbstractClass)) {
- onError(functionNode, ResolverErrorCode.METHOD_MUST_HAVE_BODY);
}
+// else if (!Elements.isNonFactoryConstructor(member) && !member.getModifiers().isAbstract()
+// && !member.getModifiers().isExternal() && node.getRedirectedTypeName() == null
+// && !(isInterface || isAbstractClass)) {
+// onError(functionNode, ResolverErrorCode.METHOD_MUST_HAVE_BODY);
+// }
}
resolve(functionNode.getBody());
@@ -877,13 +880,51 @@
}
public VariableElement resolveVariable(DartVariable x, Modifiers modifiers) {
+ final DartIdentifier nameNode = x.getName();
+ final String name = nameNode.getName();
// Visit the initializer first.
- resolve(x.getValue());
- VariableElement element = Elements.variableElement(enclosingElement, x, x.getVariableName(), modifiers);
- getContext().declare(
- recordElement(x, element),
+ DartExpression value = x.getValue();
+ if (value != null) {
+ // It is a compile-time error if e refers to the name v or the name v=.
+ value.accept(new ASTVisitor<Void>() {
+ @Override
+ public Void visitIdentifier(DartIdentifier node) {
+ // ignore cases when name is used with some qualifier
+ if (node.getParent() instanceof DartPropertyAccess) {
+ DartPropertyAccess x = (DartPropertyAccess) node.getParent();
+ if (x.getName() == node) {
+ return null;
+ }
+ }
+ if (node.getParent() instanceof DartMethodInvocation) {
+ DartMethodInvocation x = (DartMethodInvocation) node.getParent();
+ if (x.getFunctionName() == node) {
+ return null;
+ }
+ }
+ // TODO(scheglov) remove this after http://code.google.com/p/dart/issues/detail?id=6869
+ {
+ Source source = node.getSourceInfo().getSource();
+ if (Elements.isSourceName(source, "dart://json/json.dart/json.dart")) {
+ return null;
+ }
+ }
+ if (Objects.equal(node.getName(), name)) {
+ onError(node, ResolverErrorCode.VARIABLE_REFERENCES_SAME_NAME_IN_INITIALIZER, name,
+ name);
+ node.markResolutionAlreadyReportedThatTheMethodCouldNotBeFound();
+ }
+ return null;
+ }
+ });
+ // do resolve
+ resolve(value);
+ }
+ // declare variable
+ VariableElement element = Elements.variableElement(enclosingElement, x, name, modifiers);
+ getContext().declare(recordElement(x, element),
ResolverErrorCode.DUPLICATE_LOCAL_VARIABLE_ERROR);
- recordElement(x.getName(), element);
+ recordElement(nameNode, element);
return element;
}
@@ -1265,8 +1306,10 @@
}
}
if (isStaticOrFactoryContextOrInitializer(x) && !isQualifier) {
- onError(x, ResolverErrorCode.CANNOT_BE_RESOLVED, name);
- x.markResolutionAlreadyReportedThatTheMethodCouldNotBeFound();
+ if (!x.isResolutionAlreadyReportedThatTheMethodCouldNotBeFound()) {
+ onError(x, TypeErrorCode.CANNOT_BE_RESOLVED, name);
+ x.markResolutionAlreadyReportedThatTheMethodCouldNotBeFound();
+ }
}
} else if (x.getParent() instanceof DartComment) {
} else {
diff --git a/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java b/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
index f6d91c6..f40fd84 100644
--- a/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
+++ b/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
@@ -85,6 +85,7 @@
DEPRECATED_MAP_LITERAL_SYNTAX(ErrorSeverity.WARNING,
"Deprecated Map literal syntax. Both String (as key) and value type arguments required."),
DID_YOU_MEAN_NEW("%1$s is a %2$s. Did you mean (new %1$s)?"),
+ DUPLICATE_EXPORTED_NAME("%s already exported from '%s'"),
DUPLICATE_IMPLEMENTS_TYPE("Duplicate type in the implements clause"),
DUPLICATE_IMPORTED_NAME("Element '%s' is introduced by %s imports: %s"),
DUPLICATE_IMPORTED_NAME_TYPE(ErrorSeverity.WARNING, "Element '%s' is introduced by %s imports: %s"),
@@ -213,6 +214,7 @@
"type variables are not allowed in identifier expressions"),
USE_ASSIGNMENT_ON_SETTER("Use assignment to set field '%s'"),
USING_LOCAL_VARIABLE_BEFORE_DECLARATION("Using local variable '%s' before its declaration in lexical scope"),
+ VARIABLE_REFERENCES_SAME_NAME_IN_INITIALIZER("Initializer of variable \"%s\" cannot refer to the name \"%s\""),
WRONG_NUMBER_OF_TYPE_ARGUMENTS("%s: wrong number of type arguments (%d). Expected %d");
private final ErrorSeverity severity;
diff --git a/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java b/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
index 9481433..0aef7bc 100644
--- a/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
+++ b/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
@@ -142,7 +142,7 @@
boundNode,
false,
false,
- false,
+ true,
ResolverErrorCode.NO_SUCH_TYPE,
ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
boundNode.setType(bound);
diff --git a/compiler/java/com/google/dart/compiler/resolver/TopLevelElementBuilder.java b/compiler/java/com/google/dart/compiler/resolver/TopLevelElementBuilder.java
index 3cb47c7..89e204c 100644
--- a/compiler/java/com/google/dart/compiler/resolver/TopLevelElementBuilder.java
+++ b/compiler/java/com/google/dart/compiler/resolver/TopLevelElementBuilder.java
@@ -164,13 +164,25 @@
fillInLibraryScope(lib, listener, processedObjects);
for (Element element : lib.getElement().getExportedElements()) {
String name = element.getName();
- // re-export only in not defined locally
+ // re-export only if not defined locally
if (scope.findLocalElement(name) != null) {
continue;
}
// check if show/hide combinators of "export" are satisfied
- if (export.isVisible(name)) {
- Elements.addExportedElement(library.getElement(), element);
+ if (!export.isVisible(name)) {
+ continue;
+ }
+ // do export
+ Element oldElement = Elements.addExportedElement(library.getElement(), element);
+ if (oldElement != null && oldElement.getEnclosingElement() instanceof LibraryElement) {
+ LibraryElement oldLibrary = (LibraryElement) oldElement.getEnclosingElement();
+ SourceInfo sourceInfo = export.getSourceInfo();
+ if (sourceInfo != null) {
+ String oldLibraryName = oldLibrary.getLibraryUnit().getName();
+ listener.onError(new DartCompilationError(sourceInfo,
+ ResolverErrorCode.DUPLICATE_EXPORTED_NAME, Elements.getUserElementTitle(oldElement),
+ oldLibraryName));
+ }
}
}
}
diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
index e6a6419..ea351ca 100644
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
@@ -3147,7 +3147,7 @@
Set<String> artificialNames = Sets.newHashSet();
for (ClassElement interfaceElement : typesForAbstractMembers) {
for (Element member : interfaceElement.getMembers()) {
- if (interfaceElement == currentClass.getElement() && !member.getModifiers().isAbstract()) {
+ if (interfaceElement == currentClass.getElement() && !Elements.isAbstractElement(member)) {
continue;
}
String name = member.getName();
@@ -3188,7 +3188,7 @@
ClassElement superclass = supertype.getElement();
for (Element member : superclass.getMembers()) {
String name = member.getName();
- if (!member.getModifiers().isAbstract()) {
+ if (!Elements.isAbstractElement(member)) {
superMembers.removeAll(name);
}
if (member instanceof FieldElement) {
@@ -3219,7 +3219,7 @@
// add abstract members of current class
for (Element member : currentClass.getElement().getMembers()) {
- if (member.getModifiers().isAbstract()) {
+ if (Elements.isAbstractElement(member)) {
unimplementedElements.add(member);
}
}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java
index fcd7d63..3b08569 100644
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java
+++ b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java
@@ -727,6 +727,54 @@
compile();
assertErrors(errors);
}
+
+ public void test_importConflict_used_inCommentRef() throws Exception {
+ prepare_importConflictAB();
+ appSource.setContent(
+ APP,
+ makeCode(
+ "// filler filler filler filler filler filler filler filler filler filler filler",
+ "library test.app;",
+ "import 'A.dart';",
+ "import 'B.dart';",
+ "/** [Test] */",
+ "main() {",
+ "}",
+ ""));
+ compile();
+ assertErrors(errors);
+ }
+
+ /**
+ * <p>
+ * http://code.google.com/p/dart/issues/detail?id=6824
+ */
+ public void test_exportConflict() throws Exception {
+ appSource.setContent(
+ "A.dart",
+ makeCode(
+ "// filler filler filler filler filler filler filler filler filler filler filler",
+ "library lib_a;",
+ "class Test {}",
+ ""));
+ appSource.setContent(
+ "B.dart",
+ makeCode(
+ "// filler filler filler filler filler filler filler filler filler filler filler",
+ "library lib_b;",
+ "class Test {}",
+ ""));
+ appSource.setContent(
+ APP,
+ makeCode(
+ "// filler filler filler filler filler filler filler filler filler filler filler",
+ "library test.app;",
+ "export 'A.dart';",
+ "export 'B.dart';",
+ ""));
+ compile();
+ assertErrors(errors, errEx(APP, ResolverErrorCode.DUPLICATE_EXPORTED_NAME, 4, 1, 16));
+ }
private void prepare_importConflictAB() {
appSource.setContent(
@@ -969,7 +1017,7 @@
/**
* <p>
- * http://code.google.com/p/dart/issues/detail?id=3340
+ * http://code.google.com/p/dart/issues/detail?id=6822
*/
public void test_useImportPrefix_asVariableName() throws Exception {
appSource.setContent(
@@ -990,7 +1038,7 @@
""));
// do compile, no errors expected
compile();
- assertErrors(errors, errEx(ResolverErrorCode.CANNOT_HIDE_IMPORT_PREFIX, 5, 7, 3));
+ assertErrors(errors);
}
/**
diff --git a/compiler/javatests/com/google/dart/compiler/parser/SyntaxTest.java b/compiler/javatests/com/google/dart/compiler/parser/SyntaxTest.java
index 5b4ab91..496653f 100644
--- a/compiler/javatests/com/google/dart/compiler/parser/SyntaxTest.java
+++ b/compiler/javatests/com/google/dart/compiler/parser/SyntaxTest.java
@@ -40,6 +40,9 @@
import com.google.dart.compiler.ast.DartVariableStatement;
import com.google.dart.compiler.ast.NodeList;
+import static com.google.dart.compiler.common.ErrorExpectation.assertErrors;
+import static com.google.dart.compiler.common.ErrorExpectation.errEx;
+
import java.util.List;
public class SyntaxTest extends AbstractParserTest {
@@ -83,6 +86,43 @@
""),
ParserErrorCode.EXPECTED_TOKEN, 3, 12);
}
+
+ /**
+ * <p>
+ * http://code.google.com/p/dart/issues/detail?id=6825
+ */
+ public void test_annotation_forExport() {
+ parseUnit(
+ "test.dart",
+ Joiner.on("\n").join(
+ "// filler filler filler filler filler filler filler filler filler filler",
+ "library Test;",
+ "",
+ "@meta @meta2 export 'Lib.dart';",
+ ""));
+ }
+
+ /**
+ * There was bug that handling missing identifier (method name) after "cursor." in switch caused
+ * infinite parsing loop.
+ * <p>
+ * http://code.google.com/p/dart/issues/detail?id=6908
+ */
+ public void test_switch_noMethodName_inCase() {
+ DartParserRunner runner = parseSource(Joiner.on("\n").join(
+ "// filler filler filler filler filler filler filler filler filler filler",
+ "void main() {",
+ " print((e) {",
+ " switch (e) {",
+ " case 'Up': cursor.();",
+ " case 'Down':",
+ " }",
+ " }); ",
+ "}",
+ ""));
+ assertErrors(runner.getErrors(),
+ errEx(ParserErrorCode.INVALID_IDENTIFIER, 5, 24, 1));
+ }
public void test_getter() {
parseUnit("getter.dart", Joiner.on("\n").join(
@@ -1522,4 +1562,12 @@
"typedef func(final arg());",
ParserErrorCode.FUNCTION_TYPED_PARAMETER_IS_FINAL, 1, 20);
}
+
+ public void test_export_withoutLibraryDirective() {
+ parseUnit("test.dart", Joiner.on("\n").join(
+ "// filler filler filler filler filler filler filler filler filler filler",
+ "export 'Lib.dart';",
+ ""),
+ ParserErrorCode.EXPORT_WITHOUT_LIBRARY_DIRECTIVE, 2, 1);
+ }
}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/NegativeResolverTest.java b/compiler/javatests/com/google/dart/compiler/resolver/NegativeResolverTest.java
index 9eeab09..9333042 100644
--- a/compiler/javatests/com/google/dart/compiler/resolver/NegativeResolverTest.java
+++ b/compiler/javatests/com/google/dart/compiler/resolver/NegativeResolverTest.java
@@ -1081,7 +1081,7 @@
" for (var y in foo(y)) {",
" }",
"}"),
- errEx(ResolverErrorCode.CANNOT_BE_RESOLVED, 4, 21, 1));
+ errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 4, 21, 1));
}
/**
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java b/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java
index 90d8486..e27f146 100644
--- a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java
+++ b/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java
@@ -1303,7 +1303,7 @@
"method() {",
" A.noField = 1;",
"}"),
- errEx(ResolverErrorCode.CANNOT_BE_RESOLVED, 3, 22, 1),
+ errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 3, 22, 1),
errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 6, 5, 7));
}
@@ -1380,15 +1380,6 @@
errEx(ResolverErrorCode.IS_AN_INSTANCE_METHOD, 6, 13, 6));
}
- public void test_methodMustHaveBody() {
- resolveAndTest(Joiner.on("\n").join(
- "class Object {}",
- "class C {",
- " method();",
- "}"),
- errEx(ResolverErrorCode.METHOD_MUST_HAVE_BODY, 3, 3, 9));
- }
-
public void test_staticAccess() throws Exception {
resolveAndTest(Joiner.on("\n").join(
"class Object {}",
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
index 5f72504..dd81e86 100644
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
+++ b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
@@ -539,11 +539,11 @@
throws Exception {
AnalyzeLibraryResult libraryResult =
analyzeLibrary(
- "interface Foo {",
+ "abstract class Foo {",
" int fooA;",
" void fooB();",
"}",
- "interface Bar {",
+ "abstract class Bar {",
" void barA();",
"}",
"class A implements Foo, Bar {",
@@ -552,10 +552,10 @@
" new A();",
"}");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.CONTRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 8, 7, 1));
{
- DartCompilationError typeError = libraryResult.getTypeErrors().get(0);
+ DartCompilationError typeError = libraryResult.getErrors().get(0);
String message = typeError.getMessage();
assertTrue(message.contains("# From Foo:"));
assertTrue(message.contains("int fooA"));
@@ -574,7 +574,7 @@
AnalyzeLibraryResult libraryResult =
analyzeLibrary(
"abstract class A {",
- " abstract void foo();",
+ " void foo();",
"}",
"class B extends A {",
"}",
@@ -582,10 +582,10 @@
" new B();",
"}");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.CONTRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 4, 7, 1));
{
- DartCompilationError typeError = libraryResult.getTypeErrors().get(0);
+ DartCompilationError typeError = libraryResult.getErrors().get(0);
String message = typeError.getMessage();
assertTrue(message.contains("# From A:"));
assertTrue(message.contains("void foo()"));
@@ -601,16 +601,16 @@
AnalyzeLibraryResult libraryResult =
analyzeLibrary(
"class A {",
- " abstract void foo();",
+ " void foo();",
"}",
"main() {",
" new A();",
"}");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.CONTRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 1, 7, 1));
{
- DartCompilationError typeError = libraryResult.getTypeErrors().get(0);
+ DartCompilationError typeError = libraryResult.getErrors().get(0);
String message = typeError.getMessage();
assertTrue(message.contains("# From A:"));
assertTrue(message.contains("void foo()"));
@@ -622,13 +622,13 @@
AnalyzeLibraryResult libraryResult =
analyzeLibrary(
"class A {",
- " abstract get x;",
+ " get x;",
"}",
"main() {",
" new A();",
"}");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.CONTRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 1, 7, 1));
}
@@ -639,7 +639,7 @@
*/
public void test_warnAbstract_whenInstantiate_implementSetter() throws Exception {
AnalyzeLibraryResult libraryResult = analyzeLibrary(
- "interface I {",
+ "abstract class I {",
" set foo(x);",
"}",
"class A implements I {",
@@ -648,7 +648,7 @@
"main() {",
" new A();",
"}");
- assertErrors(libraryResult.getTypeErrors());
+ assertErrors(libraryResult.getErrors());
}
/**
@@ -658,7 +658,7 @@
*/
public void test_warnAbstract_whenInstantiate_implementsOnlyGetter() throws Exception {
AnalyzeLibraryResult libraryResult = analyzeLibrary(
- "interface I {",
+ "abstract class I {",
" get foo;",
" set foo(x);",
"}",
@@ -669,7 +669,7 @@
" new A();",
"}");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.CONTRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 5, 7, 1));
}
@@ -679,12 +679,12 @@
*/
public void test_warnAbstract_whenInstantiate_implementsSetter_inSuperClass() throws Exception {
AnalyzeLibraryResult libraryResult = analyzeLibrary(
- "interface I {",
+ "abstract class I {",
" get foo;",
" set foo(x);",
"}",
"abstract class A implements I {",
- " abstract get foo;",
+ " get foo;",
" set foo(x) {}",
"}",
"class B extends A {",
@@ -693,7 +693,7 @@
"main() {",
" new B();",
"}");
- assertErrors(libraryResult.getTypeErrors());
+ assertErrors(libraryResult.getErrors());
}
public void test_warnAbstract_onAbstractClass_whenInstantiate_normalConstructor()
@@ -701,13 +701,13 @@
AnalyzeLibraryResult libraryResult =
analyzeLibrary(
"abstract class A {",
- " abstract void bar();",
+ " void bar();",
"}",
"main() {",
" new A();",
"}");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.INSTANTIATION_OF_ABSTRACT_CLASS, 5, 7, 1));
}
@@ -729,7 +729,7 @@
" return new A();", // no error - factory constructor
" }",
"}");
- assertErrors(libraryResult.getTypeErrors());
+ assertErrors(libraryResult.getErrors());
}
/**
@@ -745,14 +745,14 @@
" factory A() {",
" return null;",
" }",
- " abstract method();",
+ " method();",
"}",
"class C {",
" foo() {",
" return new A();", // no error, factory constructor
" }",
"}");
- assertErrors(libraryResult.getTypeErrors());
+ assertErrors(libraryResult.getErrors());
}
/**
@@ -768,7 +768,7 @@
" bool set bob(bool a) {}",
"}");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.SETTER_RETURN_TYPE, 4, 3, 7),
errEx(TypeErrorCode.SETTER_RETURN_TYPE, 5, 3, 4));
}
@@ -797,7 +797,7 @@
"foo(WorkElement e) {",
" e.run();",
"}");
- assertErrors(libraryResult.getTypeErrors());
+ assertErrors(libraryResult.getErrors());
}
/**
@@ -832,7 +832,7 @@
" for (var v in test.iter) {}",
"}",
"");
- assertErrors(libraryResult.getTypeErrors());
+ assertErrors(libraryResult.getErrors());
}
/**
@@ -867,7 +867,7 @@
"f_0_2({n1, n2}) {}",
"");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.EXTRA_ARGUMENT, 3, 18, 2),
errEx(TypeErrorCode.MISSING_ARGUMENT, 5, 12, 5),
errEx(TypeErrorCode.EXTRA_ARGUMENT, 7, 22, 2),
@@ -876,9 +876,7 @@
errEx(TypeErrorCode.EXTRA_ARGUMENT, 12, 18, 1),
errEx(TypeErrorCode.EXTRA_ARGUMENT, 13, 18, 1),
errEx(TypeErrorCode.EXTRA_ARGUMENT, 13, 21, 1),
- errEx(TypeErrorCode.NO_SUCH_NAMED_PARAMETER, 15, 18, 4));
- assertErrors(
- libraryResult.getCompilationErrors(),
+ errEx(TypeErrorCode.NO_SUCH_NAMED_PARAMETER, 15, 18, 4),
errEx(ResolverErrorCode.DUPLICATE_NAMED_ARGUMENT, 16, 25, 5));
}
@@ -894,7 +892,7 @@
"}",
"");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.NO_SUCH_NAMED_PARAMETER, 4, 8, 6),
errEx(TypeErrorCode.NO_SUCH_NAMED_PARAMETER, 4, 16, 6),
errEx(TypeErrorCode.NO_SUCH_NAMED_PARAMETER, 4, 24, 6));
@@ -966,7 +964,7 @@
" new SetOnlyWrapper().setOnly.foo = 3;", // 16: OK
"}");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.FIELD_HAS_NO_GETTER, 11, 11, 3),
errEx(TypeErrorCode.FIELD_HAS_NO_GETTER, 12, 17, 3),
errEx(TypeErrorCode.FIELD_HAS_NO_GETTER, 14, 17, 3),
@@ -986,7 +984,7 @@
" a.foo += 2;",
" print(a.foo);",
"}");
- assertErrors(libraryResult.getTypeErrors());
+ assertErrors(libraryResult.getErrors());
}
public void test_setterOnlyProperty_getterInSuper() throws Exception {
@@ -1005,13 +1003,13 @@
" b.foo += 2;",
" print(b.foo);",
"}");
- assertErrors(libraryResult.getTypeErrors());
+ assertErrors(libraryResult.getErrors());
}
public void test_setterOnlyProperty_getterInInterface() throws Exception {
AnalyzeLibraryResult libraryResult =
analyzeLibrary(
- "interface A {",
+ "abstract class A {",
" get foo {}",
"}",
"abstract class B implements A {",
@@ -1025,7 +1023,7 @@
" print(b.foo);",
"}");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.INSTANTIATION_OF_ABSTRACT_CLASS, 9, 13, 1));
}
@@ -1050,7 +1048,7 @@
" bar = new GetOnlyWrapper().getOnly.foo;", // 16: OK, use getter
"}");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.FIELD_HAS_NO_SETTER, 11, 11, 3),
errEx(TypeErrorCode.FIELD_HAS_NO_SETTER, 12, 11, 3),
errEx(TypeErrorCode.FIELD_HAS_NO_SETTER, 15, 32, 3));
@@ -1072,13 +1070,13 @@
" b.foo += 2;",
" print(b.foo);",
"}");
- assertErrors(libraryResult.getTypeErrors());
+ assertErrors(libraryResult.getErrors());
}
public void test_getterOnlyProperty_setterInInterface() throws Exception {
AnalyzeLibraryResult libraryResult =
analyzeLibrary(
- "interface A {",
+ "abstract class A {",
" set foo(arg) {}",
"}",
"abstract class B implements A {",
@@ -1092,7 +1090,7 @@
" print(b.foo);",
"}");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.INSTANTIATION_OF_ABSTRACT_CLASS, 9, 13, 1));
}
@@ -1147,7 +1145,7 @@
"}",
"");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 12, 9, 3),
errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 13, 9, 3));
}
@@ -1168,7 +1166,7 @@
"}",
"");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 6, 15, 13));
}
@@ -1176,7 +1174,7 @@
AnalyzeLibraryResult libraryResult = analyzeLibrary(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
- " final f;",
+ " final f = 0;",
"}",
"main() {",
" A a = new A();",
@@ -1185,48 +1183,24 @@
" print(a.f);", // 8: OK, can read
"}");
assertErrors(
- libraryResult.getTypeErrors(),
+ libraryResult.getErrors(),
errEx(TypeErrorCode.FIELD_IS_FINAL, 7, 5, 1),
errEx(TypeErrorCode.FIELD_IS_FINAL, 8, 5, 1));
}
- public void test_finalField_inInterface() throws Exception {
- AnalyzeLibraryResult libraryResult = analyzeLibrary(
- "// filler filler filler filler filler filler filler filler filler filler",
- "interface I default A {",
- " final f;",
- "}",
- "class A implements I {",
- " var f;",
- "}",
- "main() {",
- " I a = new I();",
- " a.f = 0;", // 6: ERR, is final
- " a.f += 1;", // 7: ERR, is final
- " print(a.f);", // 8: OK, can read
- "}");
- assertErrors(
- libraryResult.getTypeErrors(),
- errEx(TypeErrorCode.FIELD_IS_FINAL, 10, 5, 1),
- errEx(TypeErrorCode.FIELD_IS_FINAL, 11, 5, 1));
- }
-
public void test_notFinalField() throws Exception {
AnalyzeLibraryResult libraryResult = analyzeLibrary(
"// filler filler filler filler filler filler filler filler filler filler",
- "interface I default A {",
- " var f;",
- "}",
- "class A implements I {",
+ "class A {",
" var f;",
"}",
"main() {",
- " I a = new I();",
+ " A a = new A();",
" a.f = 0;", // 6: OK, field "f" is not final
" a.f += 1;", // 7: OK, field "f" is not final
" print(a.f);", // 8: OK, can read
"}");
- assertErrors(libraryResult.getTypeErrors());
+ assertErrors(libraryResult.getErrors());
}
public void test_constField() throws Exception {
@@ -1356,7 +1330,7 @@
"void fC() {}",
"fD() {}",
"");
- assertErrors(libraryResult.getTypeErrors());
+ assertErrors(libraryResult.getErrors());
{
DartMethodDefinition fA = (DartMethodDefinition) testUnit.getTopLevelNodes().get(0);
assertEquals("int", fA.getElement().getReturnType().getElement().getName());
@@ -3379,15 +3353,15 @@
AnalyzeLibraryResult libraryResult = analyzeLibrary(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {}",
- "interface I {",
+ "abstract class I {",
" foo();",
" bar();",
"}",
- "interface J extends I {",
+ "abstract class J implements I {",
" get foo;",
- " set bar();",
+ " set bar(x);",
"}");
- assertErrors(libraryResult.getTypeErrors(),
+ assertErrors(libraryResult.getErrors(),
errEx(TypeErrorCode.SUPERTYPE_HAS_METHOD, 8, 7, 3));
}
@@ -3455,18 +3429,17 @@
public void test_supertypeHasField() throws Exception {
AnalyzeLibraryResult libraryResult = analyzeLibrary(
"// filler filler filler filler filler filler filler filler filler filler",
- "class A {}",
- "interface I {",
+ "class A {",
" var foo;",
" var bar;",
"}",
- "interface J extends I {",
- " foo();",
- " bar();",
+ "class B extends A {",
+ " foo() {}",
+ " bar() {}",
"}");
- assertErrors(libraryResult.getTypeErrors(),
- errEx(TypeErrorCode.SUPERTYPE_HAS_FIELD, 8, 3, 3),
- errEx(TypeErrorCode.SUPERTYPE_HAS_FIELD, 9, 3, 3));
+ assertErrors(libraryResult.getErrors(),
+ errEx(TypeErrorCode.SUPERTYPE_HAS_FIELD, 7, 3, 3),
+ errEx(TypeErrorCode.SUPERTYPE_HAS_FIELD, 8, 3, 3));
}
/**
@@ -3475,17 +3448,16 @@
public void test_supertypeHasGetterSetter() throws Exception {
AnalyzeLibraryResult libraryResult = analyzeLibrary(
"// filler filler filler filler filler filler filler filler filler filler",
- "class A {}",
- "interface I {",
- " get foo;",
- " set bar();",
+ "class A {",
+ " get foo => 0;",
+ " set bar(x) {}",
"}",
- "interface J extends I {",
- " foo();",
- " bar();",
+ "class B extends A {",
+ " foo() {}",
+ " bar() {}",
"}");
- assertErrors(libraryResult.getTypeErrors(),
- errEx(TypeErrorCode.SUPERTYPE_HAS_FIELD, 8, 3, 3));
+ assertErrors(libraryResult.getErrors(),
+ errEx(TypeErrorCode.SUPERTYPE_HAS_FIELD, 7, 3, 3));
}
/**
@@ -4534,23 +4506,29 @@
}
/**
- * If "unknown" is separate identifier, it is handled as "this.unknown", but "this" is not
- * accessible in static context.
* <p>
- * http://code.google.com/p/dart/issues/detail?id=3084
+ * http://code.google.com/p/dart/issues/detail?id=6836
*/
public void test_unresolvedIdentifier_inStatic_notPropertyAccess() throws Exception {
AnalyzeLibraryResult libraryResult = analyzeLibrary(
"// filler filler filler filler filler filler filler filler filler filler",
"process(x) {}",
+ "",
+ "class A {",
+ " static foo() {",
+ " unknown = 0;",
+ " }",
+ "}",
+ "",
"main() {",
" unknown = 0;",
" process(unknown);",
"}");
assertErrors(
libraryResult.getErrors(),
- errEx(ResolverErrorCode.CANNOT_BE_RESOLVED, 4, 3, 7),
- errEx(ResolverErrorCode.CANNOT_BE_RESOLVED, 5, 11, 7));
+ errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 6, 5, 7),
+ errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 11, 3, 7),
+ errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 12, 11, 7));
}
/**
@@ -5690,7 +5668,7 @@
assertErrors(result.getErrors(),
errEx(ResolverErrorCode.NOT_GENERATIVE_SUPER_CONSTRUCTOR, 8, 9, 13));
}
-
+
/**
* <p>
* http://code.google.com/p/dart/issues/detail?id=6718
@@ -5706,4 +5684,15 @@
assertErrors(result.getErrors(),
errEx(ResolverErrorCode.INITIALIZER_ONLY_IN_GENERATIVE_CONSTRUCTOR, 4, 9, 15));
}
+
+ public void test_variableReferencesItselfInInitializer() throws Exception {
+ AnalyzeLibraryResult result = analyzeLibrary(
+ "// filler filler filler filler filler filler filler filler filler filler",
+ "main() {",
+ " var x = x;",
+ "}",
+ "");
+ assertErrors(result.getErrors(),
+ errEx(ResolverErrorCode.VARIABLE_REFERENCES_SAME_NAME_IN_INITIALIZER, 3, 11, 1));
+ }
}
diff --git a/pkg/intl/lib/src/http_request_data_reader.dart b/pkg/intl/lib/src/http_request_data_reader.dart
index b6d2e35..61c59d6 100644
--- a/pkg/intl/lib/src/http_request_data_reader.dart
+++ b/pkg/intl/lib/src/http_request_data_reader.dart
@@ -23,7 +23,7 @@
var source = '$url$locale.json';
var request = new HttpRequest.get(
source,
- (request) => completer.complete(request.responseText));
+ (req) => completer.complete(req.responseText));
return completer.future;
}
}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 32d4068..e8688de 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -48,7 +48,6 @@
[ $compiler == dartc ]
unittest/test/mock_regexp_negative_test: Fail
unittest/test/mock_stepwise_negative_test: Fail
-args/test/args_test: Fail # http://dartbug.com/6790
[ $compiler == dart2js || $compiler == dartc ]
unittest/test/instance_test: Skip
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index 9c379ca..f81e078 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -45,9 +45,9 @@
OS::Print("Integer_bitAndFromInteger %s & %s\n",
right.ToCString(), left.ToCString());
}
- Integer& result =
+ const Integer& result =
Integer::Handle(left.BitOp(Token::kBIT_AND, right));
- return result.AsInteger();
+ return result.AsValidInteger();
}
@@ -60,9 +60,9 @@
OS::Print("Integer_bitOrFromInteger %s | %s\n",
left.ToCString(), right.ToCString());
}
- Integer& result =
+ const Integer& result =
Integer::Handle(left.BitOp(Token::kBIT_OR, right));
- return result.AsInteger();
+ return result.AsValidInteger();
}
@@ -75,9 +75,9 @@
OS::Print("Integer_bitXorFromInteger %s ^ %s\n",
left.ToCString(), right.ToCString());
}
- Integer& result =
+ const Integer& result =
Integer::Handle(left.BitOp(Token::kBIT_XOR, right));
- return result.AsInteger();
+ return result.AsValidInteger();
}
@@ -90,7 +90,9 @@
OS::Print("Integer_addFromInteger %s + %s\n",
left_int.ToCString(), right_int.ToCString());
}
- return left_int.ArithmeticOp(Token::kADD, right_int);
+ const Integer& result =
+ Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int));
+ return result.AsValidInteger();
}
@@ -103,7 +105,9 @@
OS::Print("Integer_subFromInteger %s - %s\n",
left_int.ToCString(), right_int.ToCString());
}
- return left_int.ArithmeticOp(Token::kSUB, right_int);
+ const Integer& result =
+ Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int));
+ return result.AsValidInteger();
}
@@ -116,7 +120,9 @@
OS::Print("Integer_mulFromInteger %s * %s\n",
left_int.ToCString(), right_int.ToCString());
}
- return left_int.ArithmeticOp(Token::kMUL, right_int);
+ const Integer& result =
+ Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int));
+ return result.AsValidInteger();
}
@@ -126,7 +132,9 @@
ASSERT(CheckInteger(right_int));
ASSERT(CheckInteger(left_int));
ASSERT(!right_int.IsZero());
- return left_int.ArithmeticOp(Token::kTRUNCDIV, right_int);
+ const Integer& result =
+ Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int));
+ return result.AsValidInteger();
}
@@ -143,7 +151,9 @@
// Should have been caught before calling into runtime.
UNIMPLEMENTED();
}
- return left_int.ArithmeticOp(Token::kMOD, right_int);
+ const Integer& result =
+ Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int));
+ return result.AsValidInteger();
}
@@ -250,9 +260,9 @@
GET_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1));
ASSERT(CheckInteger(amount));
ASSERT(CheckInteger(value));
- Integer& result = Integer::Handle(
+ const Integer& result = Integer::Handle(
ShiftOperationHelper(Token::kSHR, value, amount));
- return result.AsInteger();
+ return result.AsValidInteger();
}
@@ -266,9 +276,9 @@
OS::Print("Smi_shlFromInt: %s << %s\n",
value.ToCString(), amount.ToCString());
}
- Integer& result = Integer::Handle(
+ const Integer& result = Integer::Handle(
ShiftOperationHelper(Token::kSHL, value, amount));
- return result.AsInteger();
+ return result.AsValidInteger();
}
@@ -301,7 +311,7 @@
const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value));
ASSERT(CheckInteger(value));
ASSERT(CheckInteger(result));
- return result.AsInteger();
+ return result.AsValidInteger();
}
} // namespace dart
diff --git a/runtime/vm/bigint_operations.cc b/runtime/vm/bigint_operations.cc
index 5690d7b..4adec18 100644
--- a/runtime/vm/bigint_operations.cc
+++ b/runtime/vm/bigint_operations.cc
@@ -731,7 +731,13 @@
const DoubleChunk left_over_carry = kDoubleChunkMaxValue >> kDigitBitSize;
const intptr_t kMaxDigits = (kDoubleChunkMaxValue - left_over_carry) / square;
if (Utils::Minimum(a_length, b_length) > kMaxDigits) {
- UNIMPLEMENTED();
+ // Use the preallocated out of memory exception to avoid calling
+ // into dart code or allocating any code.
+ Isolate* isolate = Isolate::Current();
+ const Instance& exception =
+ Instance::Handle(isolate->object_store()->out_of_memory());
+ Exceptions::Throw(exception);
+ UNREACHABLE();
}
DoubleChunk accumulator = 0; // Accumulates the result of one column.
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index f24bd03..abf1cdd 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -6,6 +6,7 @@
#include "vm/assembler_macros.h"
#include "vm/ast.h"
+#include "vm/bigint_operations.h"
#include "vm/code_patcher.h"
#include "vm/compiler.h"
#include "vm/dart_api_impl.h"
@@ -1908,4 +1909,17 @@
}
+DEFINE_LEAF_RUNTIME_ENTRY(intptr_t,
+ BigintCompare,
+ RawBigint* left,
+ RawBigint* right) {
+ Isolate* isolate = Isolate::Current();
+ StackZone zone(isolate);
+ HANDLESCOPE(isolate);
+ const Bigint& big_left = Bigint::Handle(left);
+ const Bigint& big_right = Bigint::Handle(right);
+ return BigintOperations::Compare(big_left, big_right);
+}
+END_LEAF_RUNTIME_ENTRY
+
} // namespace dart
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index c9d67eb..37be5e7 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -1599,7 +1599,8 @@
// arguments: <ArgumentList> }
void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
if (node->function().name() == Symbols::Identical()) {
- // Attempt to replace identical with strcit equal early on.
+ // Attempt to replace top level defined 'identical' from the core
+ // library with strict equal early on.
// TODO(hausner): Evaluate if this can happen at AST building time.
const Class& cls = Class::Handle(node->function().Owner());
if (cls.IsTopLevel()) {
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 02d94fc..7b8b194 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -954,7 +954,6 @@
intptr_t offset) {
switch (cid) {
case kArrayCid:
- case kGrowableObjectArrayCid:
case kImmutableArrayCid: {
const intptr_t disp = offset * kWordSize + sizeof(RawArray);
ASSERT(Utils::IsInt(31, disp));
@@ -972,6 +971,33 @@
ASSERT(Utils::IsInt(31, disp));
return FieldAddress(array, disp);
}
+ case kUint8ArrayCid: {
+ const intptr_t disp = offset + Uint8Array::data_offset();
+ ASSERT(Utils::IsInt(31, disp));
+ return FieldAddress(array, disp);
+ }
+ default:
+ UNIMPLEMENTED();
+ return FieldAddress(SPREG, 0);
+ }
+}
+
+
+FieldAddress FlowGraphCompiler::ElementAddressForRegIndex(intptr_t cid,
+ Register array,
+ Register index) {
+ // Note that index is Smi, i.e, times 2.
+ ASSERT(kSmiTagShift == 1);
+ switch (cid) {
+ case kArrayCid:
+ case kImmutableArrayCid:
+ return FieldAddress(array, index, TIMES_HALF_WORD_SIZE, sizeof(RawArray));
+ case kFloat32ArrayCid:
+ return FieldAddress(array, index, TIMES_2, Float32Array::data_offset());
+ case kFloat64ArrayCid:
+ return FieldAddress(array, index, TIMES_4, Float64Array::data_offset());
+ case kUint8ArrayCid:
+ return FieldAddress(array, index, TIMES_1, Uint8Array::data_offset());
default:
UNIMPLEMENTED();
return FieldAddress(SPREG, 0);
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index f0236df..5efe27e 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -24,26 +24,6 @@
DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
-FieldAddress FlowGraphCompiler::ElementAddressForRegIndex(intptr_t cid,
- Register array,
- Register index) {
- // Note that index is Smi, i.e, times 2.
- ASSERT(kSmiTagShift == 1);
- switch (cid) {
- case kArrayCid:
- case kImmutableArrayCid:
- return FieldAddress(array, index, TIMES_2, sizeof(RawArray));
- case kFloat32ArrayCid:
- return FieldAddress(array, index, TIMES_2, Float32Array::data_offset());
- case kFloat64ArrayCid:
- return FieldAddress(array, index, TIMES_4, Float64Array::data_offset());
- default:
- UNIMPLEMENTED();
- return FieldAddress(SPREG, 0);
- }
-}
-
-
bool FlowGraphCompiler::SupportsUnboxedMints() {
// Support unboxed mints when SSE 4.1 is available.
return FLAG_unbox_mints && CPUFeatures::sse4_1_supported();
@@ -1106,11 +1086,45 @@
void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
- const Object& obj) {
+ const Object& obj,
+ bool needs_number_check) {
+ if (needs_number_check) {
+ if (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()) {
+ needs_number_check = false;
+ }
+ }
+
if (obj.IsSmi() && (Smi::Cast(obj).Value() == 0)) {
+ ASSERT(!needs_number_check);
__ testl(reg, reg);
+ return;
+ }
+
+ if (needs_number_check) {
+ __ pushl(reg);
+ __ PushObject(obj);
+ __ call(&StubCode::IdenticalWithNumberCheckLabel());
+ __ popl(reg); // Discard constant.
+ __ popl(reg); // Restore 'reg'.
+ return;
+ }
+
+ __ CompareObject(reg, obj);
+}
+
+
+void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
+ Register right,
+ bool needs_number_check) {
+ if (needs_number_check) {
+ __ pushl(left);
+ __ pushl(right);
+ __ call(&StubCode::IdenticalWithNumberCheckLabel());
+ // Stub returns result in flags (result of a cmpl, we need ZF computed).
+ __ popl(right);
+ __ popl(left);
} else {
- __ CompareObject(reg, obj);
+ __ cmpl(left, right);
}
}
diff --git a/runtime/vm/flow_graph_compiler_ia32.h b/runtime/vm/flow_graph_compiler_ia32.h
index 201b964..5576041 100644
--- a/runtime/vm/flow_graph_compiler_ia32.h
+++ b/runtime/vm/flow_graph_compiler_ia32.h
@@ -159,7 +159,12 @@
XmmRegister right,
Register result);
- void EmitEqualityRegConstCompare(Register reg, const Object& obj);
+ void EmitEqualityRegConstCompare(Register reg,
+ const Object& obj,
+ bool needs_number_check);
+ void EmitEqualityRegRegCompare(Register left,
+ Register right,
+ bool needs_number_check);
// Implement equality: if any of the arguments is null do identity check.
// Fallthrough calls super equality.
void EmitSuperEqualityCallPrologue(Register result, Label* skip_call);
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index a407051..f5c7e2b 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -24,26 +24,6 @@
DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
-FieldAddress FlowGraphCompiler::ElementAddressForRegIndex(intptr_t cid,
- Register array,
- Register index) {
- // Note that index is Smi, i.e, times 2.
- ASSERT(kSmiTagShift == 1);
- switch (cid) {
- case kArrayCid:
- case kImmutableArrayCid:
- return FieldAddress(array, index, TIMES_4, sizeof(RawArray));
- case kFloat32ArrayCid:
- return FieldAddress(array, index, TIMES_2, Float32Array::data_offset());
- case kFloat64ArrayCid:
- return FieldAddress(array, index, TIMES_4, Float64Array::data_offset());
- default:
- UNIMPLEMENTED();
- return FieldAddress(SPREG, 0);
- }
-}
-
-
bool FlowGraphCompiler::SupportsUnboxedMints() {
return false;
}
@@ -1110,11 +1090,45 @@
void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
- const Object& obj) {
+ const Object& obj,
+ bool needs_number_check) {
+ if (needs_number_check) {
+ if (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()) {
+ needs_number_check = false;
+ }
+ }
+
if (obj.IsSmi() && (Smi::Cast(obj).Value() == 0)) {
+ ASSERT(!needs_number_check);
__ testq(reg, reg);
+ return;
+ }
+
+ if (needs_number_check) {
+ __ pushq(reg);
+ __ PushObject(obj);
+ __ call(&StubCode::IdenticalWithNumberCheckLabel());
+ __ popq(reg); // Discard constant.
+ __ popq(reg); // Restore 'reg'.
+ return;
+ }
+
+ __ CompareObject(reg, obj);
+}
+
+
+void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
+ Register right,
+ bool needs_number_check) {
+ if (needs_number_check) {
+ __ pushq(left);
+ __ pushq(right);
+ __ call(&StubCode::IdenticalWithNumberCheckLabel());
+ // Stub returns result in flags (result of a cmpl, we need ZF computed).
+ __ popq(right);
+ __ popq(left);
} else {
- __ CompareObject(reg, obj);
+ __ cmpl(left, right);
}
}
diff --git a/runtime/vm/flow_graph_compiler_x64.h b/runtime/vm/flow_graph_compiler_x64.h
index 3f74bc8..8d61eda 100644
--- a/runtime/vm/flow_graph_compiler_x64.h
+++ b/runtime/vm/flow_graph_compiler_x64.h
@@ -159,6 +159,12 @@
XmmRegister right,
Register result);
+ void EmitEqualityRegConstCompare(Register reg,
+ const Object& obj,
+ bool needs_number_check);
+ void EmitEqualityRegRegCompare(Register left,
+ Register right,
+ bool needs_number_check);
void EmitEqualityRegConstCompare(Register reg, const Object& obj);
// Implement equality: if any of the arguments is null do identity check.
// Fallthrough calls super equality.
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 2321f54..2e5d624 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -56,6 +56,13 @@
VisitInstanceCall(call);
}
}
+ } else if (it.Current()->IsStrictCompare()) {
+ VisitStrictCompare(it.Current()->AsStrictCompare());
+ } else if (it.Current()->IsBranch()) {
+ ComparisonInstr* compare = it.Current()->AsBranch()->comparison();
+ if (compare->IsStrictCompare()) {
+ VisitStrictCompare(compare->AsStrictCompare());
+ }
}
}
current_iterator_ = NULL;
@@ -628,6 +635,8 @@
case kGrowableObjectArrayCid:
case kFloat32ArrayCid:
case kFloat64ArrayCid:
+ case kUint8ArrayCid:
+ case kExternalUint8ArrayCid:
// Acceptable load index classes.
break;
default:
@@ -1512,6 +1521,27 @@
}
+static bool MayBeBoxableNumber(intptr_t cid) {
+ return (cid == kDynamicCid) ||
+ (cid == kMintCid) ||
+ (cid == kBigintCid) ||
+ (cid == kDoubleCid);
+}
+
+
+// Check if number check is not needed.
+void FlowGraphOptimizer::VisitStrictCompare(StrictCompareInstr* instr) {
+ if (!instr->needs_number_check()) return;
+
+ // If one of the input is not a boxable number (Mint, Double, Bigint), no
+ // need for number checks.
+ if (!MayBeBoxableNumber(instr->left()->ResultCid()) ||
+ !MayBeBoxableNumber(instr->right()->ResultCid())) {
+ instr->set_needs_number_check(false);
+ }
+}
+
+
// SminessPropagator ensures that CheckSmis are eliminated across phis.
class SminessPropagator : public ValueObject {
public:
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index 3c81b4a..e2c9cd1 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -42,6 +42,7 @@
virtual void VisitRelationalOp(RelationalOpInstr* instr);
virtual void VisitEqualityCompare(EqualityCompareInstr* instr);
virtual void VisitBranch(BranchInstr* instr);
+ virtual void VisitStrictCompare(StrictCompareInstr* instr);
void InsertBefore(Instruction* next,
Instruction* instr,
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 70a1ee8..5fec3ad 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -20,6 +20,8 @@
namespace dart {
+DEFINE_FLAG(bool, new_identity_spec, true,
+ "Use new identity check rules for numbers.");
DEFINE_FLAG(bool, propagate_ic_data, true,
"Propagate IC data from unoptimized to optimized IC calls.");
DECLARE_FLAG(bool, enable_type_checks);
@@ -1142,12 +1144,14 @@
RawAbstractType* LoadIndexedInstr::CompileType() const {
switch (class_id_) {
case kArrayCid:
- case kGrowableObjectArrayCid:
case kImmutableArrayCid:
return Type::DynamicType();
case kFloat32ArrayCid :
case kFloat64ArrayCid :
return Type::Double();
+ case kUint8ArrayCid:
+ case kExternalUint8ArrayCid:
+ return Type::IntType();
default:
UNIMPLEMENTED();
return Type::IntType();
@@ -1158,12 +1162,14 @@
intptr_t LoadIndexedInstr::ResultCid() const {
switch (class_id_) {
case kArrayCid:
- case kGrowableObjectArrayCid:
case kImmutableArrayCid:
return kDynamicCid;
case kFloat32ArrayCid :
case kFloat64ArrayCid :
return kDoubleCid;
+ case kUint8ArrayCid:
+ case kExternalUint8ArrayCid:
+ return kSmiCid;
default:
UNIMPLEMENTED();
return kSmiCid;
@@ -1174,8 +1180,9 @@
Representation LoadIndexedInstr::representation() const {
switch (class_id_) {
case kArrayCid:
- case kGrowableObjectArrayCid:
case kImmutableArrayCid:
+ case kUint8ArrayCid:
+ case kExternalUint8ArrayCid:
return kTagged;
case kFloat32ArrayCid :
case kFloat64ArrayCid :
@@ -1198,8 +1205,6 @@
ASSERT(idx == 2);
switch (class_id_) {
case kArrayCid:
- case kGrowableObjectArrayCid:
- case kImmutableArrayCid:
return kTagged;
case kFloat32ArrayCid :
case kFloat64ArrayCid :
@@ -1784,6 +1789,15 @@
}
+StrictCompareInstr::StrictCompareInstr(Token::Kind kind,
+ Value* left,
+ Value* right)
+ : ComparisonInstr(kind, left, right),
+ needs_number_check_(FLAG_new_identity_spec) {
+ ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT));
+}
+
+
LocationSummary* StrictCompareInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 2;
const intptr_t kNumTemps = 0;
@@ -1796,6 +1810,7 @@
}
+// Special code for numbers (compare values instead of references.)
void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
Location left = locs()->in(0);
@@ -1810,11 +1825,17 @@
return;
}
if (left.IsConstant()) {
- compiler->EmitEqualityRegConstCompare(right.reg(), left.constant());
+ compiler->EmitEqualityRegConstCompare(right.reg(),
+ left.constant(),
+ needs_number_check());
} else if (right.IsConstant()) {
- compiler->EmitEqualityRegConstCompare(left.reg(), right.constant());
+ compiler->EmitEqualityRegConstCompare(left.reg(),
+ right.constant(),
+ needs_number_check());
} else {
- __ CompareRegisters(left.reg(), right.reg());
+ compiler->EmitEqualityRegRegCompare(left.reg(),
+ right.reg(),
+ needs_number_check());
}
Register result = locs()->out().reg();
@@ -1843,11 +1864,17 @@
return;
}
if (left.IsConstant()) {
- compiler->EmitEqualityRegConstCompare(right.reg(), left.constant());
+ compiler->EmitEqualityRegConstCompare(right.reg(),
+ left.constant(),
+ needs_number_check());
} else if (right.IsConstant()) {
- compiler->EmitEqualityRegConstCompare(left.reg(), right.constant());
+ compiler->EmitEqualityRegConstCompare(left.reg(),
+ right.constant(),
+ needs_number_check());
} else {
- __ CompareRegisters(left.reg(), right.reg());
+ compiler->EmitEqualityRegRegCompare(left.reg(),
+ right.reg(),
+ needs_number_check());
}
Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
@@ -2437,6 +2464,20 @@
}
+void LoadIndexedInstr::InferRange() {
+ switch (class_id()) {
+ case kExternalUint8ArrayCid:
+ case kUint8ArrayCid:
+ range_ = new Range(RangeBoundary::FromConstant(0),
+ RangeBoundary::FromConstant(255));
+ break;
+ default:
+ Definition::InferRange();
+ break;
+ }
+}
+
+
void PhiInstr::InferRange() {
RangeBoundary new_min;
RangeBoundary new_max;
@@ -2662,6 +2703,10 @@
case kArrayCid:
case kImmutableArrayCid:
return Array::length_offset();
+ case kUint8ArrayCid:
+ return Uint8Array::length_offset();
+ case kExternalUint8ArrayCid:
+ return ByteArray::length_offset();
default:
UNREACHABLE();
return -1;
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 59ba34e..a6e3452 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -2234,10 +2234,7 @@
class StrictCompareInstr : public ComparisonInstr {
public:
- StrictCompareInstr(Token::Kind kind, Value* left, Value* right)
- : ComparisonInstr(kind, left, right) {
- ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT));
- }
+ StrictCompareInstr(Token::Kind kind, Value* left, Value* right);
DECLARE_INSTRUCTION(StrictCompare)
virtual RawAbstractType* CompileType() const;
@@ -2258,7 +2255,14 @@
virtual void EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch);
+ bool needs_number_check() const { return needs_number_check_; }
+ void set_needs_number_check(bool value) { needs_number_check_ = value; }
+
private:
+ // True if the comparison must check for double, Mint or Bigint and
+ // use value comparison instead.
+ bool needs_number_check_;
+
DISALLOW_COPY_AND_ASSIGN(StrictCompareInstr);
};
@@ -2756,6 +2760,8 @@
virtual bool AffectedBySideEffect() const { return true; }
+ virtual void InferRange();
+
private:
const intptr_t class_id_;
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index fd2c971..8a1e32f 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -1169,6 +1169,27 @@
void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Register array = locs()->in(0).reg();
Location index = locs()->in(1);
+
+ if (class_id() == kExternalUint8ArrayCid) {
+ Register result = locs()->out().reg();
+ Address element_address = index.IsRegister()
+ ? Address(result, index.reg(), TIMES_1, 0)
+ : Address(result, Smi::Cast(index.constant()).Value());
+ if (index.IsRegister()) {
+ __ SmiUntag(index.reg());
+ }
+ __ movl(result,
+ FieldAddress(array, ExternalUint8Array::external_data_offset()));
+ __ movl(result,
+ Address(result, ExternalByteArrayData<uint8_t>::data_offset()));
+ __ movzxb(result, element_address);
+ __ SmiTag(result);
+ if (index.IsRegister()) {
+ __ SmiTag(index.reg()); // Re-tag.
+ }
+ return;
+ }
+
FieldAddress element_address = index.IsRegister() ?
FlowGraphCompiler::ElementAddressForRegIndex(
class_id(), array, index.reg()) :
@@ -1176,18 +1197,34 @@
class_id(), array, Smi::Cast(index.constant()).Value());
if (representation() == kUnboxedDouble) {
+ XmmRegister result = locs()->out().xmm_reg();
if (class_id() == kFloat32ArrayCid) {
// Load single precision float.
- __ movss(locs()->out().xmm_reg(), element_address);
+ __ movss(result, element_address);
// Promote to double.
- __ cvtss2sd(locs()->out().xmm_reg(), locs()->out().xmm_reg());
+ __ cvtss2sd(result, locs()->out().xmm_reg());
} else {
ASSERT(class_id() == kFloat64ArrayCid);
- __ movsd(locs()->out().xmm_reg(), element_address);
+ __ movsd(result, element_address);
}
- } else {
- __ movl(locs()->out().reg(), element_address);
+ return;
}
+
+ Register result = locs()->out().reg();
+ if (class_id() == kUint8ArrayCid) {
+ if (index.IsRegister()) {
+ __ SmiUntag(index.reg());
+ }
+ __ movzxb(result, element_address);
+ __ SmiTag(result);
+ if (index.IsRegister()) {
+ __ SmiTag(index.reg()); // Re-tag.
+ }
+ return;
+ }
+
+ ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
+ __ movl(result, element_address);
}
@@ -1238,6 +1275,7 @@
return;
}
+ ASSERT(class_id() == kArrayCid);
if (ShouldEmitStoreBarrier()) {
Register value = locs()->in(2).reg();
__ StoreIntoObject(array, element_address, value);
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 6933867..51bcc51 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -1038,6 +1038,26 @@
Register array = locs()->in(0).reg();
Location index = locs()->in(1);
+ if (class_id() == kExternalUint8ArrayCid) {
+ Register result = locs()->out().reg();
+ Address element_address = index.IsRegister()
+ ? Address(result, index.reg(), TIMES_1, 0)
+ : Address(result, Smi::Cast(index.constant()).Value());
+ if (index.IsRegister()) {
+ __ SmiUntag(index.reg());
+ }
+ __ movq(result,
+ FieldAddress(array, ExternalUint8Array::external_data_offset()));
+ __ movq(result,
+ Address(result, ExternalByteArrayData<uint8_t>::data_offset()));
+ __ movzxb(result, element_address);
+ __ SmiTag(result);
+ if (index.IsRegister()) {
+ __ SmiTag(index.reg()); // Re-tag.
+ }
+ return;
+ }
+
FieldAddress element_address = index.IsRegister() ?
FlowGraphCompiler::ElementAddressForRegIndex(
class_id(), array, index.reg()) :
@@ -1045,18 +1065,34 @@
class_id(), array, Smi::Cast(index.constant()).Value());
if (representation() == kUnboxedDouble) {
+ XmmRegister result = locs()->out().xmm_reg();
if (class_id() == kFloat32ArrayCid) {
// Load single precision float.
- __ movss(locs()->out().xmm_reg(), element_address);
+ __ movss(result, element_address);
// Promote to double.
- __ cvtss2sd(locs()->out().xmm_reg(), locs()->out().xmm_reg());
+ __ cvtss2sd(result, locs()->out().xmm_reg());
} else {
ASSERT(class_id() == kFloat64ArrayCid);
- __ movsd(locs()->out().xmm_reg(), element_address);
+ __ movsd(result, element_address);
}
- } else {
- __ movq(locs()->out().reg(), element_address);
+ return;
}
+
+ Register result = locs()->out().reg();
+ if (class_id() == kUint8ArrayCid) {
+ if (index.IsRegister()) {
+ __ SmiUntag(index.reg());
+ }
+ __ movzxb(result, element_address);
+ __ SmiTag(result);
+ if (index.IsRegister()) {
+ __ SmiTag(index.reg()); // Re-tag.
+ }
+ return;
+ }
+
+ ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
+ __ movq(result, element_address);
}
@@ -1106,6 +1142,7 @@
return;
}
+ ASSERT(class_id() == kArrayCid);
if (ShouldEmitStoreBarrier()) {
Register value = locs()->in(2).reg();
__ StoreIntoObject(array, element_address, value);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 6867359..b8088ff 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -9283,7 +9283,7 @@
}
-RawInteger* Integer::AsInteger() const {
+RawInteger* Integer::AsValidInteger() const {
if (IsSmi()) return raw();
if (IsMint()) {
Mint& mint = Mint::Handle();
@@ -9402,7 +9402,7 @@
const Bigint& right_big = Bigint::Handle(other.AsBigint());
const Bigint& result =
Bigint::Handle(left_big.ArithmeticOp(operation, right_big));
- return Integer::Handle(result.AsInteger()).raw();
+ return Integer::Handle(result.AsValidInteger()).raw();
}
@@ -9873,12 +9873,10 @@
RawBigint* Bigint::New(const String& str, Heap::Space space) {
- return BigintOperations::NewFromCString(str.ToCString(), space);
-}
-
-
-RawBigint* Bigint::New(int64_t value, Heap::Space space) {
- return BigintOperations::NewFromInt64(value, space);
+ const Bigint& result = Bigint::Handle(
+ BigintOperations::NewFromCString(str.ToCString(), space));
+ ASSERT(!BigintOperations::FitsIntoMint(result));
+ return result.raw();
}
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index e40d545..a6734ad 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -3474,7 +3474,7 @@
virtual int CompareWith(const Integer& other) const;
// Return the most compact presentation of an integer.
- RawInteger* AsInteger() const;
+ RawInteger* AsValidInteger() const;
// Return an integer in the form of a RawBigint.
RawBigint* AsBigint() const;
@@ -3622,7 +3622,6 @@
}
static RawBigint* New(const String& str, Heap::Space space = Heap::kNew);
- static RawBigint* New(int64_t value, Heap::Space space = Heap::kNew);
RawBigint* ArithmeticOp(Token::Kind operation, const Bigint& other) const;
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index f91f5d6..11b7f77 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -454,10 +454,11 @@
TEST_CASE(Bigint) {
Bigint& b = Bigint::Handle();
EXPECT(b.IsNull());
- const String& test = String::Handle(String::New("1234"));
+ const char* cstr = "18446744073709551615000";
+ const String& test = String::Handle(String::New(cstr));
b = Bigint::New(test);
const char* str = b.ToCString();
- EXPECT_STREQ("1234", str);
+ EXPECT_STREQ(cstr, str);
int64_t t64 = DART_2PART_UINT64_C(1, 0);
Bigint& big = Bigint::Handle();
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index d95b996..7e37ea4 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -671,16 +671,18 @@
intptr_t RawOneByteString::VisitOneByteStringPointers(
RawOneByteString* raw_obj, ObjectPointerVisitor* visitor) {
+ ASSERT(!raw_obj->ptr()->length_->IsHeapObject());
+ ASSERT(!raw_obj->ptr()->hash_->IsHeapObject());
intptr_t length = Smi::Value(raw_obj->ptr()->length_);
- visitor->VisitPointers(raw_obj->from(), raw_obj->to());
return OneByteString::InstanceSize(length);
}
intptr_t RawTwoByteString::VisitTwoByteStringPointers(
RawTwoByteString* raw_obj, ObjectPointerVisitor* visitor) {
+ ASSERT(!raw_obj->ptr()->length_->IsHeapObject());
+ ASSERT(!raw_obj->ptr()->hash_->IsHeapObject());
intptr_t length = Smi::Value(raw_obj->ptr()->length_);
- visitor->VisitPointers(raw_obj->from(), raw_obj->to());
return TwoByteString::InstanceSize(length);
}
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 07326ae..beaca40 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -373,7 +373,9 @@
// Write snapshot with object content.
uint8_t* buffer;
MessageWriter writer(&buffer, &zone_allocator);
- const Bigint& bigint = Bigint::Handle(Bigint::New(DART_INT64_C(0xfffffffff)));
+ const char* cstr = "0x270FFFFFFFFFFFFFD8F0";
+ const String& str = String::Handle(String::New(cstr));
+ const Bigint& bigint = Bigint::Handle(Bigint::New(str));
writer.WriteMessage(bigint);
intptr_t buffer_len = writer.BytesWritten();
@@ -383,7 +385,8 @@
Bigint& obj = Bigint::Handle();
obj ^= reader.ReadObject();
- EXPECT_EQ(BigintOperations::ToMint(bigint), BigintOperations::ToMint(obj));
+ EXPECT_STREQ(BigintOperations::ToHexCString(bigint, &allocator),
+ BigintOperations::ToHexCString(obj, &allocator));
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
@@ -392,7 +395,7 @@
// Bigint not supported.
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject::kBigint, root->type);
- EXPECT_STREQ("FFFFFFFFF", root->value.as_bigint);
+ EXPECT_STREQ("270FFFFFFFFFFFFFD8F0", root->value.as_bigint);
CheckEncodeDecodeMessage(root);
}
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index ac02e84..48ed808 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -39,6 +39,7 @@
V(GetStackPointer) \
V(JumpToExceptionHandler) \
V(JumpToErrorHandler) \
+ V(IdenticalWithNumberCheck) \
// Is it permitted for the stubs above to refer to Object::null(), which is
// allocated in the VM isolate and shared across all isolates.
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index f354cab..637d1e3 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -2130,6 +2130,92 @@
__ ret();
}
+
+DECLARE_LEAF_RUNTIME_ENTRY(intptr_t,
+ BigintCompare,
+ RawBigint* left,
+ RawBigint* right);
+
+
+// Does identical check (object references are equal or not equal) with special
+// checks for boxed numbers.
+// Left and right are pushed on stack.
+// Return ZF set.
+// Note: A Mint cannot contain a value that would fit in Smi, a Bigint
+// cannot contain a value that fits in Mint or Smi.
+void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) {
+ const Register left = EAX;
+ const Register right = EDX;
+ const Register temp = ECX;
+ // Preserve left, right and temp.
+ __ pushl(left);
+ __ pushl(right);
+ __ pushl(temp);
+ // TOS + 0: saved temp
+ // TOS + 1: saved right
+ // TOS + 2: saved left
+ // TOS + 3: return address
+ // TOS + 4: right argument.
+ // TOS + 5: left argument.
+ __ movl(left, Address(ESP, 5 * kWordSize));
+ __ movl(right, Address(ESP, 4 * kWordSize));
+ Label reference_compare, done, check_mint, check_bigint;
+ // If any of the arguments is Smi do reference compare.
+ __ testl(left, Immediate(kSmiTagMask));
+ __ j(ZERO, &reference_compare, Assembler::kNearJump);
+ __ testl(right, Immediate(kSmiTagMask));
+ __ j(ZERO, &reference_compare, Assembler::kNearJump);
+
+ // Value compare for two doubles.
+ __ CompareClassId(left, kDoubleCid, temp);
+ __ j(NOT_EQUAL, &check_mint, Assembler::kNearJump);
+ __ CompareClassId(right, kDoubleCid, temp);
+ __ j(NOT_EQUAL, &done, Assembler::kNearJump);
+
+ // Double values bitwise compare.
+ __ movl(temp, FieldAddress(left, Double::value_offset() + 0 * kWordSize));
+ __ cmpl(temp, FieldAddress(right, Double::value_offset() + 0 * kWordSize));
+ __ j(NOT_EQUAL, &done, Assembler::kNearJump);
+ __ movl(temp, FieldAddress(left, Double::value_offset() + 1 * kWordSize));
+ __ cmpl(temp, FieldAddress(right, Double::value_offset() + 1 * kWordSize));
+ __ jmp(&done, Assembler::kNearJump);
+
+ __ Bind(&check_mint);
+ __ CompareClassId(left, kMintCid, temp);
+ __ j(NOT_EQUAL, &check_bigint, Assembler::kNearJump);
+ __ CompareClassId(right, kMintCid, temp);
+ __ j(NOT_EQUAL, &done, Assembler::kNearJump);
+ __ movl(temp, FieldAddress(left, Mint::value_offset() + 0 * kWordSize));
+ __ cmpl(temp, FieldAddress(right, Mint::value_offset() + 0 * kWordSize));
+ __ j(NOT_EQUAL, &done, Assembler::kNearJump);
+ __ movl(temp, FieldAddress(left, Mint::value_offset() + 1 * kWordSize));
+ __ cmpl(temp, FieldAddress(right, Mint::value_offset() + 1 * kWordSize));
+ __ jmp(&done, Assembler::kNearJump);
+
+ __ Bind(&check_bigint);
+ __ CompareClassId(left, kBigintCid, temp);
+ __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump);
+ __ CompareClassId(right, kBigintCid, temp);
+ __ j(NOT_EQUAL, &done, Assembler::kNearJump);
+ __ EnterFrame(0);
+ __ ReserveAlignedFrameSpace(2 * kWordSize);
+ __ movl(Address(ESP, 1 * kWordSize), left);
+ __ movl(Address(ESP, 0 * kWordSize), right);
+ __ CallRuntime(kBigintCompareRuntimeEntry);
+ // Result in EAX, 0 means equal.
+ __ LeaveFrame();
+ __ cmpl(EAX, Immediate(0));
+ __ jmp(&done);
+
+ __ Bind(&reference_compare);
+ __ cmpl(left, right);
+ __ Bind(&done);
+ __ popl(temp);
+ __ popl(right);
+ __ popl(left);
+ __ ret();
+}
+
} // namespace dart
#endif // defined TARGET_ARCH_IA32
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 65ea307..d7efa3a 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -2091,6 +2091,82 @@
__ ret();
}
+
+DECLARE_LEAF_RUNTIME_ENTRY(intptr_t,
+ BigintCompare,
+ RawBigint* left,
+ RawBigint* right);
+
+
+// Does identical check (object references are equal or not equal) with special
+// checks for boxed numbers.
+// Left and right are pushed on stack.
+// Return ZF set.
+// Note: A Mint cannot contain a value that would fit in Smi, a Bigint
+// cannot contain a value that fits in Mint or Smi.
+void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) {
+ const Register left = RAX;
+ const Register right = RDX;
+ // Preserve left, right and temp.
+ __ pushq(left);
+ __ pushq(right);
+ // TOS + 0: saved right
+ // TOS + 1: saved left
+ // TOS + 2: return address
+ // TOS + 3: right argument.
+ // TOS + 4: left argument.
+ __ movq(left, Address(RSP, 4 * kWordSize));
+ __ movq(right, Address(RSP, 3 * kWordSize));
+ Label reference_compare, done, check_mint, check_bigint;
+ // If any of the arguments is Smi do reference compare.
+ __ testq(left, Immediate(kSmiTagMask));
+ __ j(ZERO, &reference_compare);
+ __ testq(right, Immediate(kSmiTagMask));
+ __ j(ZERO, &reference_compare);
+
+ // Value compare for two doubles.
+ __ CompareClassId(left, kDoubleCid);
+ __ j(NOT_EQUAL, &check_mint, Assembler::kNearJump);
+ __ CompareClassId(right, kDoubleCid);
+ __ j(NOT_EQUAL, &done, Assembler::kNearJump);
+
+ // Double values bitwise compare.
+ __ movq(left, FieldAddress(left, Double::value_offset()));
+ __ cmpq(left, FieldAddress(right, Double::value_offset()));
+ __ jmp(&done, Assembler::kNearJump);
+
+ __ Bind(&check_mint);
+ __ CompareClassId(left, kMintCid);
+ __ j(NOT_EQUAL, &check_bigint, Assembler::kNearJump);
+ __ CompareClassId(right, kMintCid);
+ __ j(NOT_EQUAL, &done, Assembler::kNearJump);
+ __ movq(left, FieldAddress(left, Mint::value_offset()));
+ __ cmpq(left, FieldAddress(right, Mint::value_offset()));
+ __ jmp(&done, Assembler::kNearJump);
+
+ __ Bind(&check_bigint);
+ __ CompareClassId(left, kBigintCid);
+ __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump);
+ __ CompareClassId(right, kBigintCid);
+ __ j(NOT_EQUAL, &done, Assembler::kNearJump);
+ __ EnterFrame(0);
+ __ ReserveAlignedFrameSpace(0);
+ __ movq(RDI, left);
+ __ movq(RSI, right);
+ __ CallRuntime(kBigintCompareRuntimeEntry);
+ // Result in RAX, 0 means equal.
+ __ LeaveFrame();
+ __ cmpq(RAX, Immediate(0));
+ __ jmp(&done);
+
+ __ Bind(&reference_compare);
+ __ cmpq(left, right);
+ __ Bind(&done);
+ __ popq(right);
+ __ popq(left);
+ __ ret();
+}
+
} // namespace dart
#endif // defined TARGET_ARCH_X64
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
index 6e87ec4..c2542ef 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
@@ -285,16 +285,12 @@
void visit(ClassElement cls) {
if (seen.contains(cls)) return;
seen.add(cls);
- for (final ClassElement subclass in getDirectSubclasses(cls)) {
- visit(subclass);
- }
+ getDirectSubclasses(cls).forEach(visit);
classes.add(cls);
}
- for (final ClassElement classElement in classesWithDynamicDispatch) {
- visit(classElement);
- }
+ classesWithDynamicDispatch.forEach(visit);
- Collection<ClassElement> dispatchClasses = classes.filter(
+ Collection<ClassElement> preorderDispatchClasses = classes.filter(
(cls) => !getDirectSubclasses(cls).isEmpty &&
classesWithDynamicDispatch.contains(cls));
@@ -318,9 +314,12 @@
// Temporary variables for common substrings.
List<String> varNames = <String>[];
- // var -> expression
- Map<dynamic, js.Expression> varDefns = new Map<dynamic, js.Expression>();
- // tag -> expression (a string or a variable)
+ // Values of temporary variables.
+ Map<String, js.Expression> varDefns = new Map<String, js.Expression>();
+
+ // Expression to compute tags string for a class. The expression will
+ // initially be a string or expression building a string, but may be
+ // replaced with a variable reference to the common substring.
Map<ClassElement, js.Expression> tagDefns =
new Map<ClassElement, js.Expression>();
@@ -332,13 +331,21 @@
void walk(ClassElement cls) {
for (final ClassElement subclass in getDirectSubclasses(cls)) {
ClassElement tag = subclass;
- var existing = tagDefns[tag];
+ js.Expression existing = tagDefns[tag];
if (existing == null) {
+ // [subclass] is still within the subtree between dispatch classes.
subtags.add(toNativeName(tag));
walk(subclass);
} else {
- if (varDefns.containsKey(existing)) {
- expressions.add(existing);
+ // [subclass] is one of the preorderDispatchClasses, so CSE this
+ // reference with the previous reference.
+ if (existing is js.VariableUse &&
+ varDefns.containsKey(existing.name)) {
+ // We end up here if the subclasses have a DAG structure. We
+ // don't have DAGs yet, but if the dispatch is used for mixins
+ // that will be a possibility.
+ // Re-use the previously created temporary variable.
+ expressions.add(new js.VariableUse(existing.name));
} else {
String varName = 'v${varNames.length}_${tag.name.slowToString()}';
varNames.add(varName);
@@ -350,6 +357,7 @@
}
}
walk(classElement);
+
if (!subtags.isEmpty) {
expressions.add(
new js.LiteralString("'${Strings.join(subtags, '|')}'"));
@@ -366,7 +374,7 @@
return expression;
}
- for (final ClassElement classElement in dispatchClasses) {
+ for (final ClassElement classElement in preorderDispatchClasses) {
tagDefns[classElement] = makeExpression(classElement);
}
@@ -394,7 +402,7 @@
// [['Node', 'Text|HTMLElement|HTMLDivElement|...'], ...]
js.Expression table =
new js.ArrayInitializer.from(
- dispatchClasses.map((cls) =>
+ preorderDispatchClasses.map((cls) =>
new js.ArrayInitializer.from([
new js.LiteralString("'${toNativeName(cls)}'"),
tagDefns[cls]])));
diff --git a/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
index 21cf6e1..38b90d1 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
@@ -148,8 +148,8 @@
// Patch for Stopwatch implementation.
patch class _StopwatchImpl {
- patch static int _frequency() => 1000;
- patch static int _now() => Primitives.dateNow();
+ patch static int _frequency() => 1000000;
+ patch static int _now() => Primitives.numMicroseconds();
}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
index ea31fe2..ad8d98c 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
@@ -535,7 +535,38 @@
static num dateNow() => JS('num', r'Date.now()');
- static stringFromCodePoints(codePoints) {
+ static num numMicroseconds() {
+ if (JS('bool', 'typeof window != "undefined" && window !== null')) {
+ var performance = JS('var', 'window.performance');
+ if (performance != null &&
+ JS('bool', 'typeof #.webkitNow == "function"', performance)) {
+ return JS('num', '#.webkitNow()', performance);
+ }
+ }
+ return 1000 * dateNow();
+ }
+
+ // This is to avoid stack overflows due to very large argument arrays in
+ // apply(). It fixes http://dartbug.com/6919
+ static String _fromCharCodeApply(List<int> array) {
+ String result = "";
+ const kMaxApply = 500;
+ int end = array.length;
+ for (var i = 0; i < end; i += kMaxApply) {
+ var subarray;
+ if (end <= kMaxApply) {
+ subarray = array;
+ } else {
+ subarray = JS('List<int>', r'array.slice(#, #)',
+ i, i + kMaxApply < end ? i + kMaxApply : end);
+ }
+ result = JS('String', '# + String.fromCharCode.apply(#, #)',
+ result, null, subarray);
+ }
+ return result;
+ }
+
+ static String stringFromCodePoints(codePoints) {
List<int> a = <int>[];
for (var i in codePoints) {
if (i is !int) throw new ArgumentError(i);
@@ -548,7 +579,7 @@
throw new ArgumentError(i);
}
}
- return JS('String', r'String.fromCharCode.apply(#, #)', null, a);
+ return _fromCharCodeApply(a);
}
static String stringFromCharCodes(charCodes) {
@@ -557,7 +588,7 @@
if (i < 0) throw new ArgumentError(i);
if (i > 0xffff) return stringFromCodePoints(charCodes);
}
- return JS('String', r'String.fromCharCode.apply(#, #)', null, charCodes);
+ return _fromCharCodeApply(charCodes);
}
static String getTimeZoneName(receiver) {
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index 0c1579b..8de208f 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -296,6 +296,8 @@
final CodeEmitterTask emitter;
+ final Set<ClassElement> doneAddSubtypes = new Set<ClassElement>();
+
NativeCodegenEnqueuer(Enqueuer world, Compiler compiler, this.emitter)
: super(world, compiler, compiler.enableNativeLiveTypeAnalysis);
@@ -320,6 +322,14 @@
}
void addSubtypes(ClassElement cls, NativeEmitter emitter) {
+ if (!cls.isNative()) return;
+ if (doneAddSubtypes.contains(cls)) return;
+ doneAddSubtypes.add(cls);
+
+ // Walk the superclass chain since classes on the superclass chain might not
+ // be instantiated (abstract or simply unused).
+ addSubtypes(cls.superclass, emitter);
+
for (DartType type in cls.allSupertypes) {
List<Element> subtypes = emitter.subtypes.putIfAbsent(
type.element,
diff --git a/tests/co19/co19-compiler.status b/tests/co19/co19-compiler.status
index ea0e63a..b076d5c 100644
--- a/tests/co19/co19-compiler.status
+++ b/tests/co19/co19-compiler.status
@@ -5,7 +5,6 @@
[ $compiler == dartc ]
Language/03_Overview/1_Scoping_A02_t05: Fail # TODO(analyzer-team): Please triage this failure.
Language/03_Overview/1_Scoping_A02_t06: Fail # TODO(analyzer-team): Please triage this failure.
-Language/03_Overview/2_Privacy_A01_t04: Fail # TODO(analyzer-team): Please triage this failure.
Language/03_Overview/2_Privacy_A01_t05: Fail # TODO(analyzer-team): Please triage this failure.
Language/03_Overview/2_Privacy_A01_t09: Fail # TODO(analyzer-team): Please triage this failure.
Language/03_Overview/2_Privacy_A01_t10: Fail # TODO(analyzer-team): Please triage this failure.
@@ -22,7 +21,6 @@
Language/06_Functions/1_Function_Declaration_A02_t03: Fail # TODO(analyzer-team): Please triage this failure.
Language/06_Functions/1_Function_Declaration_A03_t03: Fail # TODO(analyzer-team): Please triage this failure.
Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t10: Fail # TODO(analyzer-team): Please triage this failure.
-Language/06_Functions/2_Formal_Parameters_A02_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/07_Classes/6_Constructors/2_Factories_A02_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/07_Classes/6_Constructors/2_Factories_A02_t02: Fail # TODO(analyzer-team): Please triage this failure.
Language/07_Classes/6_Constructors/2_Factories_A05_t02: Fail # TODO(analyzer-team): Please triage this failure.
@@ -34,76 +32,45 @@
Language/11_Expressions/01_Constants_A05_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/01_Constants_A14_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/01_Constants_A20_t03: Fail # TODO(analyzer-team): Please triage this failure.
-Language/11_Expressions/05_Strings/1_String_Interpolation_A01_t07: Fail # TODO(analyzer-team): Please triage this failure.
-Language/11_Expressions/05_Strings/1_String_Interpolation_A01_t13: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/08_Throw_A05_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/11_Instance_Creation/1_New_A02_t07: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/11_Instance_Creation/1_New_A06_t06: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/11_Instance_Creation/2_Const_A10_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/18_Assignment_A05_t05: Fail # TODO(analyzer-team): Please triage this failure.
-Language/11_Expressions/30_Identifier_Reference_A13_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/31_Type_Test_A01_t02: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/31_Type_Test_A01_t04: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/32_Type_Cast_A01_t04: Fail # TODO(analyzer-team): Please triage this failure.
Language/12_Statements/02_Expression_Statements_A01_t12: Fail # TODO(analyzer-team): Please triage this failure.
-Language/12_Statements/03_Variable_Declaration_A01_t05: Fail # TODO(analyzer-team): Please triage this failure.
-Language/12_Statements/03_Variable_Declaration_A01_t06: Fail # TODO(analyzer-team): Please triage this failure.
Language/12_Statements/03_Variable_Declaration_A01_t09: Fail # TODO(analyzer-team): Please triage this failure.
-Language/12_Statements/03_Variable_Declaration_A01_t10: Fail # TODO(analyzer-team): Please triage this failure.
Language/12_Statements/03_Variable_Declaration_A01_t16: Fail # TODO(analyzer-team): Please triage this failure.
-Language/12_Statements/03_Variable_Declaration_A01_t17: Fail # TODO(analyzer-team): Please triage this failure.
-Language/12_Statements/03_Variable_Declaration_A01_t18: Fail # TODO(analyzer-team): Please triage this failure.
-Language/12_Statements/03_Variable_Declaration_A01_t19: Fail # TODO(analyzer-team): Please triage this failure.
-Language/12_Statements/06_For_A01_t07: Fail # TODO(analyzer-team): Please triage this failure.
Language/12_Statements/06_For_A01_t11: Fail # TODO(analyzer-team): Please triage this failure.
Language/12_Statements/09_Switch_A02_t03: Fail # TODO(analyzer-team): Please triage this failure.
-Language/12_Statements/09_Switch_A06_t02: Fail # TODO(analyzer-team): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A02_t29: Fail # TODO(analyzer-team): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A05_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/13_Libraries_and_Scripts/2_Exports_A05_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/13_Libraries_and_Scripts/4_Scripts_A01_t21: Fail # TODO(analyzer-team): Please triage this failure.
-Language/13_Libraries_and_Scripts/4_Scripts_A01_t22: Fail # TODO(analyzer-team): Please triage this failure.
Language/13_Libraries_and_Scripts/4_Scripts_A01_t23: Fail # TODO(analyzer-team): Please triage this failure.
Language/13_Libraries_and_Scripts/5_URIs_A01_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/13_Libraries_and_Scripts/5_URIs_A01_t21: Fail # TODO(analyzer-team): Please triage this failure.
-# co19 issue 319
-Language/13_Libraries_and_Scripts/1_Imports_A01_t51: Fail, OK
-Language/13_Libraries_and_Scripts/1_Imports_A01_t52: Fail, OK
-Language/13_Libraries_and_Scripts/2_Exports_A01_t02: Fail, OK
-Language/13_Libraries_and_Scripts/2_Exports_A01_t03: Fail, OK
-
# co19 issue 320
-Language/13_Libraries_and_Scripts/1_Imports_A02_t03: Fail, OK
-Language/13_Libraries_and_Scripts/1_Imports_A02_t05: Fail, OK
Language/13_Libraries_and_Scripts/1_Imports_A02_t12: Fail, OK
-Language/13_Libraries_and_Scripts/1_Imports_A02_t13: Fail, OK
Language/13_Libraries_and_Scripts/1_Imports_A02_t15: Fail, OK
Language/13_Libraries_and_Scripts/1_Imports_A02_t18: Fail, OK
Language/13_Libraries_and_Scripts/1_Imports_A02_t19: Fail, OK
-# issue 6822
-Language/13_Libraries_and_Scripts/1_Imports_A02_t24: Fail
-# issue 6823
-Language/13_Libraries_and_Scripts/1_Imports_A03_t06: Fail
-Language/13_Libraries_and_Scripts/1_Imports_A03_t26: Fail
-Language/13_Libraries_and_Scripts/1_Imports_A03_t46: Fail
-Language/13_Libraries_and_Scripts/1_Imports_A03_t66: Fail
-
-# co19 issue 324
-Language/13_Libraries_and_Scripts/2_Exports_A03_t01: Fail, OK
-Language/13_Libraries_and_Scripts/2_Exports_A03_t02: Fail, OK
-
-# issue 6824
-Language/13_Libraries_and_Scripts/2_Exports_A04_t02: Fail
+# co19 issue 330
+# was issue 6824
Language/13_Libraries_and_Scripts/2_Exports_A04_t05: Fail
+Language/13_Libraries_and_Scripts/2_Exports_A04_t06: Fail
-# issue 6825
-Language/13_Libraries_and_Scripts/2_Exports_A01_t17: Fail
-# wait for answer from Gilad
-Language/13_Libraries_and_Scripts/2_Exports_A04_t06: Fail # TODO(analyzer-team): Please triage this failure.
+# co19 issue 327
+Language/03_Overview/1_Scoping_A02_t17: Fail, OK
+Language/03_Overview/1_Scoping_A02_t32: Fail, OK
+Language/12_Statements/03_Variable_Declaration_A01_t10: Fail, OK
+Language/12_Statements/03_Variable_Declaration_A01_t17: Fail, OK
Language/03_Overview/2_Privacy_A01_t08: pass # http://dartbug.com/5179
Language/03_Overview/2_Privacy_A01_t11: pass # http://dartbug.com/5179
@@ -149,6 +116,9 @@
Language/07_Classes/6_Constructors/2_Factories_A03_t01: Fail, OK # co19 issue 307
+# co19 issue 329
+Language/13_Libraries_and_Scripts/4_Scripts_A01_t20: Fail
+
Language/13_Libraries_and_Scripts/13_Libraries_and_Scripts_A05_t03: Fail, OK # contains syntax error
Language/13_Libraries_and_Scripts/13_Libraries_and_Scripts_A05_t04: Fail, OK # contains syntax error
Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t02: Fail, OK # deprecated parameter syntax
diff --git a/tests/corelib/map_from_test.dart b/tests/corelib/map_from_test.dart
index 00d1a60..8c8a5bc 100644
--- a/tests/corelib/map_from_test.dart
+++ b/tests/corelib/map_from_test.dart
@@ -20,9 +20,9 @@
Expect.equals(2, otherMap.values.length);
var count = (map) {
- int count = 0;
- map.forEach((a, b) { count += b; });
- return count;
+ int cnt = 0;
+ map.forEach((a, b) { cnt += b; });
+ return cnt;
};
Expect.equals(42 + 43, count(map));
diff --git a/tests/corelib/string_from_list_test.dart b/tests/corelib/string_from_list_test.dart
index ec43592..23c90f2 100644
--- a/tests/corelib/string_from_list_test.dart
+++ b/tests/corelib/string_from_list_test.dart
@@ -19,6 +19,26 @@
a.add(66);
Expect.equals("AB", new String.fromCharCodes(a));
}
+
+ // Long list (bug 6919).
+ for (int len in [499, 500, 501, 999, 100000]) {
+ List<int> list = new List(len);
+ for (int i = 0; i < len; i++) {
+ list[i] = 65 + (i % 26);
+ }
+ for (int i = len - 9; i < len; i++) {
+ list[i] = 48 + (len - i);
+ }
+ // We should not throw a stack overflow here.
+ String long = new String.fromCharCodes(list);
+ // Minimal sanity checking on the string.
+ Expect.isTrue(long.startsWith('ABCDE'));
+ Expect.isTrue(long.endsWith('987654321'));
+ int middle = len ~/ 2;
+ middle -= middle % 26;
+ Expect.equals('XYZABC', long.substring(middle - 3, middle + 3));
+ Expect.equals(len, long.length);
+ }
}
}
diff --git a/tests/language/language.status b/tests/language/language.status
index 5c4c267..1cf55b7 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -97,8 +97,6 @@
call_nonexistent_static_test/03: Fail # Unresolved static calls are no longer errors.
call_nonexistent_static_test/04: Fail # Unresolved static calls are no longer errors.
call_nonexistent_static_test/05: Fail # Unresolved static calls are no longer errors.
-call_nonexistent_static_test/06: Fail # Unresolved static calls are no longer errors.
-call_nonexistent_static_test/07: Fail # Unresolved static calls are no longer errors.
call_nonexistent_static_test/08: Fail # Unresolved static calls are no longer errors.
call_nonexistent_static_test/09: Fail # Unresolved static calls are no longer errors.
call_nonexistent_static_test/10: Fail # Unresolved static calls are no longer errors.
@@ -142,7 +140,6 @@
getter_no_setter_test/01: Fail # Fails to detect compile-time error.
getter_no_setter2_test/01: Fail # Fails to detect compile-time error.
instance_call_wrong_argument_count_negative_test: Fail # Runtime only test, rewrite as multitest
-duplicate_export_negative_test: Fail # Duplicate export not reported.
# Test expects signature of noSuchMethod to be correct according
# to specification. Should start working when the library signature
# changes.
@@ -338,7 +335,16 @@
type_variable_identifier_expression_negative_test: Fail, OK
# test issue 6866
-abstract_factory_constructor_test/00: Fail, OK
+abstract_factory_constructor_test/none: Fail
+abstract_syntax_test/none: Fail
+get_set_syntax_test/none: Fail
+
+# test issue 6838
+import_combinators_negative_test: Fail, OK
+unresolved_top_level_var_negative_test: Fail, OK
+
+# test issue 6871
+block_scope_test: Fail, OK
#
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index ceece29..572215f 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -82,6 +82,7 @@
compile_time_constant_checked3_test/06: Fail, OK
[ $compiler == dart2js ]
+number_identity2_test: Fail # identity of NaN
factory_redirection2_test/01: Fail # http://dartbug.com/6791
new_expression_type_args_test/00: Fail # Wrongly reports compile-time error.
new_expression_type_args_test/01: Fail # Wrongly reports compile-time error.
diff --git a/tests/language/number_identity2_test.dart b/tests/language/number_identity2_test.dart
new file mode 100644
index 0000000..883049b
--- /dev/null
+++ b/tests/language/number_identity2_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing params.
+//
+// Contains test that is failing on dart2js. Merge this test with
+// 'number_identity_test.dart' once fixed.
+
+main() {
+ for (int i = 0; i < 1000; i++) testNumberIdentity();
+}
+
+
+testNumberIdentity () {
+ var a = double.NAN;
+ var b = a + 0.0;
+ Expect.isTrue(identical(a, b));
+}
diff --git a/tests/language/number_identity_test.dart b/tests/language/number_identity_test.dart
new file mode 100644
index 0000000..9f475e7
--- /dev/null
+++ b/tests/language/number_identity_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing params.
+
+main() {
+ for (int i = 0; i < 1000; i++) testNumberIdentity();
+}
+
+
+testNumberIdentity () {
+ const int smi = 8;
+ const int mint = 9223372036854775806;
+ const int bigint = 22107138293752210713829375;
+ const double dbl = 8.0;
+
+ var a = smi;
+ var b = a + 0;
+ Expect.isTrue(identical(a, b));
+ Expect.isFalse(identical(b, mint));
+ Expect.isFalse(identical(b, bigint));
+
+ a = mint;
+ b = a + 0;
+ Expect.isTrue(identical(a, b));
+ Expect.isFalse(identical(b, smi));
+ Expect.isFalse(identical(b, bigint));
+ Expect.isFalse(identical(b, dbl));
+
+ a = bigint;
+ b = a + 0;
+ Expect.isTrue(identical(a, b));
+ Expect.isFalse(identical(b, smi));
+ Expect.isFalse(identical(b, mint));
+ Expect.isFalse(identical(b, dbl));
+
+ a = dbl;
+ b = a + 0.0;
+ Expect.isTrue(identical(a, b));
+ Expect.isFalse(identical(b, mint));
+ Expect.isFalse(identical(b, bigint));
+}
diff --git a/tests/standalone/io/test_extension_test.dart b/tests/standalone/io/test_extension_test.dart
index 3f074f9..276cbc9 100644
--- a/tests/standalone/io/test_extension_test.dart
+++ b/tests/standalone/io/test_extension_test.dart
@@ -4,75 +4,60 @@
//
// Dart test program for testing native extensions.
-#import("dart:io");
-#import("dart:isolate");
+#import('dart:io');
-// The following source statements, hidden in a string, fool the test script
-// tools/testing/dart/multitest.dart
-// into copying the files into the generated_tests directory.
-// TODO(3919): Rewrite this test, not as a multitest, to copy them manually.
-const dummyString = '''
-#source('test_extension_tester.dart');
-#source('test_extension.dart');
-''';
+Future copyFileToDirectory(Path file, Path directory) {
+ String src = file.toNativePath();
+ String dst = directory.toNativePath();
+ switch (Platform.operatingSystem) {
+ case 'linux':
+ case 'macos':
+ return Process.run('cp', [src, dst]);
+ case 'windows':
+ return Process.run('cmd.exe', ['/C', 'copy $src $dst']);
+ default:
+ Expect.fail('Unknown operating system ${Platform.operatingSystem}');
+ }
+}
+
+Path getExtensionPath(Path buildDirectory) {
+ switch (Platform.operatingSystem) {
+ case 'linux':
+ return buildDirectory.append('lib.target/libtest_extension.so');
+ case 'macos':
+ return buildDirectory.append('libtest_extension.dylib');
+ case 'windows':
+ return buildDirectory.append('test_extension.dll');
+ default:
+ Expect.fail('Unknown operating system ${Platform.operatingSystem}');
+ }
+}
void main() {
Options options = new Options();
- // Make this a multitest so that the test scripts run a copy of it in
- // [build directory]/generated_tests. This way, we can copy the shared
- // library for test_extension.dart to the test directory.
- // The "none" case of the multitest, without the following
- // line, is the one that runs the test of the extension.
- foo foo foo foo foo; /// 01: compile-time error
-
- Path testDirectory = new Path.fromNative(options.script).directoryPath;
+ Path scriptDirectory = new Path.fromNative(options.script).directoryPath;
Path buildDirectory = new Path.fromNative(options.executable).directoryPath;
+ Directory tempDirectory = new Directory('').createTempSync();
+ Path testDirectory = new Path.fromNative(tempDirectory.path);
- // Copy test_extension shared library from the build directory to the
- // test directory.
- Future sharedLibraryCopied;
- // Use the platforms' copy file commands, to preserve executable privilege.
- switch (Platform.operatingSystem) {
- case 'linux':
- var source = buildDirectory.append('lib.target/libtest_extension.so');
- sharedLibraryCopied = Process.run('cp',
- [source.toNativePath(),
- testDirectory.toNativePath()]);
- break;
- case 'macos':
- var source = buildDirectory.append('libtest_extension.dylib');
- sharedLibraryCopied = Process.run('cp',
- [source.toNativePath(),
- testDirectory.toNativePath()]);
- break;
- case 'windows':
- var source = buildDirectory.append('test_extension.dll');
- sharedLibraryCopied = Process.run('cmd.exe',
- ['/C',
- 'copy ${source.toNativePath()} ${testDirectory.toNativePath()}']);
- break;
- default:
- Expect.fail("Unknown operating system ${Platform.operatingSystem}");
- }
-
- sharedLibraryCopied.handleException((e) {
- print('Copying of shared library test_extension failed.');
- throw e;
- });
- sharedLibraryCopied.then((ignore) {
- print('Shared library copied to test directory.');
- Path copiedTest = testDirectory.append("test_extension_tester.dart");
- var result = Process.run(options.executable,
- [copiedTest.toNativePath()]);
- result.then((processResult) {
- print('Output of test_extension_tester.dart:');
- print(' stdout:');
- print(processResult.stdout);
- print(' stderr:');
- print(processResult.stderr);
- stdout.flush();
- exit(processResult.exitCode);
- });
+ // Copy test_extension shared library, test_extension.dart and
+ // test_extension_tester.dart to the temporary test directory.
+ copyFileToDirectory(getExtensionPath(buildDirectory),
+ testDirectory).chain((_) {
+ Path extensionDartFile = scriptDirectory.append('test_extension.dart');
+ return copyFileToDirectory(extensionDartFile, testDirectory);
+ }).chain((_) {
+ Path testExtensionTesterFile =
+ scriptDirectory.append('test_extension_tester.dart');
+ return copyFileToDirectory(testExtensionTesterFile, testDirectory);
+ }).chain((_) {
+ Path script = testDirectory.append('test_extension_tester.dart');
+ return Process.run(options.executable, [script.toNativePath()]);
+ })..then((ProcessResult result) {
+ Expect.equals(0, result.exitCode);
+ tempDirectory.deleteSync(recursive: true);
+ })..handleException((_) {
+ tempDirectory.deleteSync(recursive: true);
});
}
diff --git a/tests/standalone/number_identity_test.dart b/tests/standalone/number_identity_test.dart
new file mode 100644
index 0000000..4336e81
--- /dev/null
+++ b/tests/standalone/number_identity_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing params.
+//
+// Tests 'identical' for cases that not supported in dart2js (bigint,
+// disambiguation int/double).
+
+main() {
+ for (int i = 0; i < 1000; i++) testNumberIdentity();
+}
+
+
+testNumberIdentity () {
+ const int smi = 8;
+ const int bigint = 22107138293752210713829375;
+ const double dbl = 8.0;
+ // No int/double differences in dart2js.
+ var a = smi + 0;
+ Expect.isFalse(identical(a, dbl));
+ a = dbl + 0.0;
+ Expect.isFalse(identical(a, smi));
+
+ a = bigint;
+ var b = a + 0;
+ Expect.isTrue(identical(a, b));
+ b = a + 1;
+ Expect.isFalse(identical(a, b)); // Fails with dart2js.
+}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index d888b07..d64d1e6 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -63,6 +63,7 @@
*: Skip
[ $compiler == dart2js ]
+number_identity_test: Skip # Bigints and int/double diff. not supported.
typed_array_test: Skip # This is a VM test
float_array_test: Skip # This is a VM test
int_array_test: Skip # This is a VM test
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index 2ce46b6..d8b095d 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -25,3 +25,8 @@
[ $compiler == dart2dart ]
# Skip until we stabilize language tests.
*: Skip
+
+[ $compiler == dartc ]
+# dart2js issue 6870
+dummy_compiler_test: Fail, OK
+recursive_import_test: Fail, OK
diff --git a/tools/VERSION b/tools/VERSION
index 9937b3b..9b6bee7 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
MAJOR 0
MINOR 2
-BUILD 5
+BUILD 6
PATCH 0