aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/packages
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/packages')
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/Info.java97
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/NativeInfo.java54
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/NativeProvider.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/SkylarkInfo.java105
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/SkylarkProvider.java2
5 files changed, 174 insertions, 91 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Info.java b/src/main/java/com/google/devtools/build/lib/packages/Info.java
index 059c55efb2..6c004e2776 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Info.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Info.java
@@ -15,20 +15,15 @@ package com.google.devtools.build.lib.packages;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Ordering;
-import com.google.common.collect.Sets;
-import com.google.common.collect.Sets.SetView;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.ClassObject;
-import com.google.devtools.build.lib.syntax.Concatable;
import com.google.devtools.build.lib.syntax.EvalException;
-import com.google.devtools.build.lib.syntax.EvalUtils;
import com.google.devtools.build.lib.syntax.Printer;
import com.google.devtools.build.lib.syntax.SkylarkType;
import com.google.devtools.build.lib.util.Preconditions;
@@ -48,24 +43,21 @@ import javax.annotation.Nullable;
+ "See the global <a href=\"globals.html#struct\">struct</a> function "
+ "for more details."
)
-public class Info implements ClassObject, SkylarkValue, Concatable, Serializable {
+public abstract class Info implements ClassObject, SkylarkValue, Serializable {
private final Provider provider;
- private final ImmutableMap<String, Object> values;
private final Location creationLoc;
private final String errorMessage;
/** Creates an empty struct with a given location. */
public Info(Provider provider, Location location) {
this.provider = provider;
- this.values = ImmutableMap.of();
this.creationLoc = location;
this.errorMessage = provider.getErrorMessageFormatForInstances();
}
/** Creates a built-in struct (i.e. without creation loc). */
- public Info(Provider provider, Map<String, Object> values) {
+ public Info(Provider provider) {
this.provider = provider;
- this.values = copyValues(values);
this.creationLoc = null;
this.errorMessage = provider.getErrorMessageFormatForInstances();
}
@@ -80,20 +72,12 @@ public class Info implements ClassObject, SkylarkValue, Concatable, Serializable
*/
Info(Provider provider, Map<String, Object> values, String errorMessage) {
this.provider = provider;
- this.values = copyValues(values);
this.creationLoc = null;
this.errorMessage = Preconditions.checkNotNull(errorMessage);
}
- public Info(Provider provider, Map<String, Object> values, Location creationLoc) {
- this.provider = provider;
- this.values = copyValues(values);
- this.creationLoc = Preconditions.checkNotNull(creationLoc);
- this.errorMessage = provider.getErrorMessageFormatForInstances();
- }
-
// Ensure that values are all acceptable to Skylark before to stuff them in a ClassObject
- private ImmutableMap<String, Object> copyValues(Map<String, Object> values) {
+ protected static ImmutableMap<String, Object> copyValues(Map<String, Object> values) {
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
for (Map.Entry<String, Object> e : values.entrySet()) {
builder.put(
@@ -102,18 +86,11 @@ public class Info implements ClassObject, SkylarkValue, Concatable, Serializable
return builder.build();
}
- @Override
- public Object getValue(String name) {
- return values.get(name);
- }
-
- public boolean hasKey(String name) {
- return values.containsKey(name);
- }
+ public abstract boolean hasKey(String name);
/** Returns a value and try to cast it into specified type */
public <TYPE> TYPE getValue(String key, Class<TYPE> type) throws EvalException {
- Object obj = values.get(key);
+ Object obj = getValue(key);
if (obj == null) {
return null;
}
@@ -121,20 +98,10 @@ public class Info implements ClassObject, SkylarkValue, Concatable, Serializable
return type.cast(obj);
}
- @Override
- public ImmutableCollection<String> getKeys() {
- return values.keySet();
- }
-
public Location getCreationLoc() {
return Preconditions.checkNotNull(creationLoc, "This struct was not created in a Skylark code");
}
- @Override
- public Concatter getConcatter() {
- return StructConcatter.INSTANCE;
- }
-
public Provider getProvider() {
return provider;
}
@@ -144,58 +111,14 @@ public class Info implements ClassObject, SkylarkValue, Concatable, Serializable
return creationLoc;
}
- private static class StructConcatter implements Concatter {
- private static final StructConcatter INSTANCE = new StructConcatter();
-
- private StructConcatter() {}
-
- @Override
- public Info concat(Concatable left, Concatable right, Location loc) throws EvalException {
- Info lval = (Info) left;
- Info rval = (Info) right;
- if (!lval.provider.equals(rval.provider)) {
- throw new EvalException(
- loc,
- String.format(
- "Cannot concat %s with %s",
- lval.provider.getPrintableName(), rval.provider.getPrintableName()));
- }
- SetView<String> commonFields = Sets.intersection(lval.values.keySet(), rval.values.keySet());
- if (!commonFields.isEmpty()) {
- throw new EvalException(
- loc,
- "Cannot concat structs with common field(s): " + Joiner.on(",").join(commonFields));
- }
- return new Info(
- lval.provider,
- ImmutableMap.<String, Object>builder().putAll(lval.values).putAll(rval.values).build(),
- loc);
- }
- }
-
@Override
public String errorMessage(String name) {
String suffix =
- "Available attributes: "
- + Joiner.on(", ").join(Ordering.natural().sortedCopy(values.keySet()));
+ "Available attributes: " + Joiner.on(", ").join(Ordering.natural().sortedCopy(getKeys()));
return String.format(errorMessage, name) + "\n" + suffix;
}
@Override
- public boolean isImmutable() {
- // If the provider is not yet exported the hash code of the object is subject to change
- if (!provider.isExported()) {
- return false;
- }
- for (Object item : values.values()) {
- if (!EvalUtils.isImmutable(item)) {
- return false;
- }
- }
- return true;
- }
-
- @Override
public boolean equals(Object otherObject) {
if (!(otherObject instanceof Info)) {
return false;
@@ -241,14 +164,14 @@ public class Info implements ClassObject, SkylarkValue, Concatable, Serializable
boolean first = true;
printer.append("struct(");
// Sort by key to ensure deterministic output.
- for (String key : Ordering.natural().sortedCopy(values.keySet())) {
+ for (String key : Ordering.natural().sortedCopy(getKeys())) {
if (!first) {
printer.append(", ");
}
first = false;
printer.append(key);
printer.append(" = ");
- printer.repr(values.get(key));
+ printer.repr(getValue(key));
}
printer.append(")");
}
@@ -259,14 +182,14 @@ public class Info implements ClassObject, SkylarkValue, Concatable, Serializable
printer.append(provider.getPrintableName());
printer.append("(");
// Sort by key to ensure deterministic output.
- for (String key : Ordering.natural().sortedCopy(values.keySet())) {
+ for (String key : Ordering.natural().sortedCopy(getKeys())) {
if (!first) {
printer.append(", ");
}
first = false;
printer.append(key);
printer.append(" = ");
- printer.repr(values.get(key));
+ printer.repr(getValue(key));
}
printer.append(")");
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/NativeInfo.java b/src/main/java/com/google/devtools/build/lib/packages/NativeInfo.java
new file mode 100644
index 0000000000..d52fa87a1d
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/packages/NativeInfo.java
@@ -0,0 +1,54 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.packages;
+
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.events.Location;
+import java.util.Map;
+
+/** Base class for native implementations of {@link Info}. */
+// todo(vladmos,dslomov): make abstract once DefaultInfo stops instantiating it.
+public class NativeInfo extends Info {
+ protected final ImmutableMap<String, Object> values;
+
+ @Override
+ public Object getValue(String name) {
+ return values.get(name);
+ }
+
+ @Override
+ public boolean hasKey(String name) {
+ return values.containsKey(name);
+ }
+
+ @Override
+ public ImmutableCollection<String> getKeys() {
+ return values.keySet();
+ }
+
+ public NativeInfo(NativeProvider<?> provider) {
+ super(provider, Location.BUILTIN);
+ this.values = ImmutableMap.of();
+ }
+
+ public NativeInfo(NativeProvider<?> provider, Map<String, Object> values, Location loc) {
+ super(provider, loc);
+ this.values = copyValues(values);
+ }
+
+ public NativeInfo(NativeProvider<?> provider, Map<String, Object> values) {
+ this(provider, values, Location.BUILTIN);
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/NativeProvider.java b/src/main/java/com/google/devtools/build/lib/packages/NativeProvider.java
index f400255400..39b87cc781 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/NativeProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/NativeProvider.java
@@ -13,6 +13,7 @@
// limitations under the License.
package com.google.devtools.build.lib.packages;
+import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.syntax.EvalException;
@@ -78,15 +79,15 @@ public abstract class NativeProvider<VALUE extends Info> extends Provider {
protected Info createInstanceFromSkylark(Object[] args, Location loc) {
@SuppressWarnings("unchecked")
Map<String, Object> kwargs = (Map<String, Object>) args[0];
- return new Info(this, kwargs, loc);
+ return new SkylarkInfo(this, kwargs, loc);
}
public Info create(Map<String, Object> values, String message) {
- return new Info(this, values, message);
+ return new SkylarkInfo(this, values, message);
}
public Info create(Location loc) {
- return new Info(this, loc);
+ return new SkylarkInfo(this, ImmutableMap.of(), loc);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkInfo.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkInfo.java
new file mode 100644
index 0000000000..755a5df5f1
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkInfo.java
@@ -0,0 +1,105 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.packages;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+import com.google.common.collect.Sets.SetView;
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.packages.NativeProvider.StructConstructor;
+import com.google.devtools.build.lib.syntax.Concatable;
+import com.google.devtools.build.lib.syntax.EvalException;
+import com.google.devtools.build.lib.syntax.EvalUtils;
+import java.util.Map;
+
+/** Implementation of {@link Info} created from Skylark. */
+public final class SkylarkInfo extends Info implements Concatable {
+ protected final ImmutableMap<String, Object> values;
+
+ public SkylarkInfo(Provider provider, Map<String, Object> kwargs, Location loc) {
+ super(provider, loc);
+ this.values = copyValues(kwargs);
+ }
+
+ public SkylarkInfo(StructConstructor provider, Map<String, Object> values, String message) {
+ super(provider, values, message);
+ this.values = copyValues(values);
+ }
+
+ @Override
+ public Concatter getConcatter() {
+ return StructConcatter.INSTANCE;
+ }
+
+ @Override
+ public Object getValue(String name) {
+ return values.get(name);
+ }
+
+ @Override
+ public boolean hasKey(String name) {
+ return values.containsKey(name);
+ }
+
+ @Override
+ public ImmutableCollection<String> getKeys() {
+ return values.keySet();
+ }
+
+ @Override
+ public boolean isImmutable() {
+ // If the provider is not yet exported the hash code of the object is subject to change
+ if (!getProvider().isExported()) {
+ return false;
+ }
+ for (Object item : values.values()) {
+ if (!EvalUtils.isImmutable(item)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static class StructConcatter implements Concatter {
+ private static final StructConcatter INSTANCE = new StructConcatter();
+
+ private StructConcatter() {}
+
+ @Override
+ public SkylarkInfo concat(Concatable left, Concatable right, Location loc)
+ throws EvalException {
+ SkylarkInfo lval = (SkylarkInfo) left;
+ SkylarkInfo rval = (SkylarkInfo) right;
+ if (!lval.getProvider().equals(rval.getProvider())) {
+ throw new EvalException(
+ loc,
+ String.format(
+ "Cannot concat %s with %s",
+ lval.getProvider().getPrintableName(), rval.getProvider().getPrintableName()));
+ }
+ SetView<String> commonFields = Sets.intersection(lval.values.keySet(), rval.values.keySet());
+ if (!commonFields.isEmpty()) {
+ throw new EvalException(
+ loc,
+ "Cannot concat structs with common field(s): " + Joiner.on(",").join(commonFields));
+ }
+ return new SkylarkInfo(
+ lval.getProvider(),
+ ImmutableMap.<String, Object>builder().putAll(lval.values).putAll(rval.values).build(),
+ loc);
+ }
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkProvider.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkProvider.java
index 8489d81407..d76c006414 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkProvider.java
@@ -60,7 +60,7 @@ public class SkylarkProvider extends Provider implements SkylarkExportable {
protected Info createInstanceFromSkylark(Object[] args, Location loc) throws EvalException {
@SuppressWarnings("unchecked")
Map<String, Object> kwargs = (Map<String, Object>) args[0];
- return new Info(this, kwargs, loc);
+ return new SkylarkInfo(this, kwargs, loc);
}
@Override